欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#實現(xiàn)23種常見的設(shè)計模式的示例詳解

 更新時間:2023年06月05日 15:54:40   作者:tokengo  
設(shè)計模式通常分為三個主要類別:創(chuàng)建型模式、結(jié)構(gòu)型模式和行為型模式,這些模式是用于解決常見的對象導(dǎo)向設(shè)計問題的最佳實踐,本文為大家整理了23種常見的設(shè)計模式的實現(xiàn)代碼,需要的可以參考一下

設(shè)計模式通常分為三個主要類別:

  • 創(chuàng)建型模式
  • 結(jié)構(gòu)型模式
  • 行為型模式。

這些模式是用于解決常見的對象導(dǎo)向設(shè)計問題的最佳實踐。

以下是23種常見的設(shè)計模式并且提供c#代碼案例:

創(chuàng)建型模式

1. 單例模式(Singleton)

public sealed class Singleton
{
    //創(chuàng)建一個只讀的靜態(tài)Singleton實例
    private static readonly Singleton instance = new Singleton();
    // 記錄Singleton的創(chuàng)建次數(shù)
    private static int instanceCounter = 0;
    // 單例實例的公共訪問點
    public static Singleton Instance
    {
        get
        {
            return instance;
        }
    }
    // 私有構(gòu)造函數(shù)
    private Singleton()
    {
        instanceCounter++;
        Console.WriteLine("Instances Created " + instanceCounter);
    }
    // 在此處添加其他的Singleton類方法
    public void LogMessage(string message)
    {
        Console.WriteLine("Message: " + message);
    }
}

在這個例子中,我們有一個名為Singleton的類,它有一個私有的構(gòu)造函數(shù)和一個靜態(tài)的只讀屬性Instance,用于訪問Singleton類的唯一實例。我們還有一個LogMessage方法,用于模擬Singleton類的某個行為。

以下是一個使用這個Singleton類的控制臺應(yīng)用程序:

class Program
{
    static void Main(string[] args)
    {
        Singleton fromEmployee = Singleton.Instance;
        fromEmployee.LogMessage("Message from Employee");
        Singleton fromBoss = Singleton.Instance;
        fromBoss.LogMessage("Message from Boss");
        Console.ReadLine();
    }
}

2. 工廠方法模式(Factory Method)

工廠方法模式是一種創(chuàng)建型設(shè)計模式,它提供了一種創(chuàng)建對象的接口,但允許子類決定實例化哪個類。工廠方法讓類的實例化推遲到子類中進行。

下面是一個使用C#實現(xiàn)的工廠方法模式的簡單示例:

// 抽象產(chǎn)品
public interface IProduct
{
    string Operation();
}
// 具體產(chǎn)品A
public class ProductA : IProduct
{
    public string Operation()
    {
        return "{Result of ProductA}";
    }
}
// 具體產(chǎn)品B
public class ProductB : IProduct
{
    public string Operation()
    {
        return "{Result of ProductB}";
    }
}
// 抽象創(chuàng)建者
public abstract class Creator
{
    public abstract IProduct FactoryMethod();
}
// 具體創(chuàng)建者A
public class CreatorA : Creator
{
    public override IProduct FactoryMethod()
    {
        return new ProductA();
    }
}
// 具體創(chuàng)建者B
public class CreatorB : Creator
{
    public override IProduct FactoryMethod()
    {
        return new ProductB();
    }
}

以上代碼中定義了兩個產(chǎn)品ProductAProductB,這兩個產(chǎn)品都實現(xiàn)了IProduct接口。接著我們有兩個Creator類,CreatorACreatorB,它們都繼承自抽象基類Creator。CreatorA工廠創(chuàng)建ProductA,CreatorB工廠創(chuàng)建ProductB。

以下是一個使用這些工廠和產(chǎn)品的示例:

class Program
{
    static void Main(string[] args)
    {
        // 創(chuàng)建工廠對象
        Creator creatorA = new CreatorA();
        Creator creatorB = new CreatorB();
        // 通過工廠方法創(chuàng)建產(chǎn)品對象
        IProduct productA = creatorA.FactoryMethod();
        IProduct productB = creatorB.FactoryMethod();
        // 打印結(jié)果
        Console.WriteLine("ProductA says: " + productA.Operation());
        Console.WriteLine("ProductB says: " + productB.Operation());
        Console.ReadLine();
    }
}

當(dāng)你運行這個程序時,它會顯示出ProductAProductBOperation方法返回的結(jié)果。這說明我們已經(jīng)成功地使用工廠方法模式創(chuàng)建了產(chǎn)品實例。每個工廠類決定了它創(chuàng)建哪個產(chǎn)品的實例。這種方式使得客戶端代碼不需要直接實例化產(chǎn)品類,而只需要依賴工廠接口,增加了程序的靈活性。

3. 抽象工廠模式(Abstract Factory)

抽象工廠模式是一種創(chuàng)建型設(shè)計模式,它提供了一種接口,用于創(chuàng)建相關(guān)或依賴對象的系列,而不指定這些對象的具體類。在這個模式中,客戶端通過他們的抽象接口使用類,允許該模式在不影響客戶端的情況下替換實現(xiàn)類。

以下是一個簡單的抽象工廠模式的C#實現(xiàn):

// 抽象產(chǎn)品:動物
public interface IAnimal
{
    string Speak();
}
// 具體產(chǎn)品:狗
public class Dog : IAnimal
{
    public string Speak()
    {
        return "Bark Bark";
    }
}
// 具體產(chǎn)品:貓
public class Cat : IAnimal
{
    public string Speak()
    {
        return "Meow Meow";
    }
}
// 抽象工廠
public abstract class IAnimalFactory
{
    public abstract IAnimal CreateAnimal();
}
// 具體工廠:狗工廠
public class DogFactory : IAnimalFactory
{
    public override IAnimal CreateAnimal()
    {
        return new Dog();
    }
}
// 具體工廠:貓工廠
public class CatFactory : IAnimalFactory
{
    public override IAnimal CreateAnimal()
    {
        return new Cat();
    }
}

以上代碼定義了兩種動物DogCat,它們都實現(xiàn)了IAnimal接口。然后我們有兩個工廠類,DogFactoryCatFactory,它們都繼承自IAnimalFactory。DogFactory生產(chǎn)Dog,而CatFactory生產(chǎn)Cat。

以下是一個使用這些工廠和產(chǎn)品的示例:

class Program
{
    static void Main(string[] args)
    {
        // 創(chuàng)建工廠
        IAnimalFactory dogFactory = new DogFactory();
        IAnimalFactory catFactory = new CatFactory();
        // 使用工廠創(chuàng)建產(chǎn)品
        IAnimal dog = dogFactory.CreateAnimal();
        IAnimal cat = catFactory.CreateAnimal();
        // 打印結(jié)果
        Console.WriteLine("Dog says: " + dog.Speak());
        Console.WriteLine("Cat says: " + cat.Speak());
        Console.ReadLine();
    }
}

當(dāng)你運行這個程序時,會打印出Dog和Cat的Speak方法的結(jié)果,這顯示了我們已經(jīng)成功地使用了抽象工廠模式創(chuàng)建了產(chǎn)品實例。這種方式使得客戶端代碼不需要直接實例化產(chǎn)品類,而只需要依賴工廠接口,增加了程序的靈活性和擴展性。

4. 建造者模式(Builder)

建造者模式是一種創(chuàng)建型設(shè)計模式,它提供了一種創(chuàng)建對象的接口,但是允許使用相同的構(gòu)建過程來創(chuàng)建不同的產(chǎn)品。

以下是在C#中實現(xiàn)建造者模式的一個簡單示例:

// 產(chǎn)品
public class Car
{
    public string Engine { get; set; }
    public string Wheels { get; set; }
    public string Doors { get; set; }
}
// 建造者抽象類
public abstract class CarBuilder
{
    protected Car car;
    public void CreateNewCar()
    {
        car = new Car();
    }
    public Car GetCar()
    {
        return car;
    }
    public abstract void SetEngine();
    public abstract void SetWheels();
    public abstract void SetDoors();
}
// 具體建造者
public class FerrariBuilder : CarBuilder
{
    public override void SetEngine()
    {
        car.Engine = "V8";
    }
    public override void SetWheels()
    {
        car.Wheels = "18 inch";
    }
    public override void SetDoors()
    {
        car.Doors = "2";
    }
}
// 指揮者
public class Director
{
    public Car Construct(CarBuilder carBuilder)
    {
        carBuilder.CreateNewCar();
        carBuilder.SetEngine();
        carBuilder.SetWheels();
        carBuilder.SetDoors();
        return carBuilder.GetCar();
    }
}

以上代碼中,Car是我們要創(chuàng)建的產(chǎn)品,CarBuilder是抽象的建造者,定義了制造一個產(chǎn)品所需要的各個步驟,FerrariBuilder是具體的建造者,實現(xiàn)了CarBuilder定義的所有步驟,Director是指揮者,它告訴建造者應(yīng)該按照什么順序去執(zhí)行哪些步驟。

以下是一個使用這個建造者模式的示例:

class Program
{
    static void Main(string[] args)
    {
        Director director = new Director();
        CarBuilder builder = new FerrariBuilder();
        Car ferrari = director.Construct(builder);
        Console.WriteLine($"Engine: {ferrari.Engine}, Wheels: {ferrari.Wheels}, Doors: {ferrari.Doors}");
        Console.ReadLine();
    }
}

當(dāng)你運行這個程序時,會看到我們已經(jīng)成功地創(chuàng)建了一個Car實例,它的各個部分是按照FerrariBuilder所定義的方式創(chuàng)建的。這說明我們使用建造者模式成功地將一個復(fù)雜對象的構(gòu)造過程解耦,使得同樣的構(gòu)造過程可以創(chuàng)建不同的表示。

5. 原型模式(Prototype)

原型模式是一種創(chuàng)建型設(shè)計模式,它實現(xiàn)了一個原型接口,該接口用于創(chuàng)建當(dāng)前對象的克隆。當(dāng)直接創(chuàng)建對象的代價比較大時,則采用這種模式。例如,一個對象需要在一個高代價的數(shù)據(jù)庫操作后被創(chuàng)建。

以下是在C#中實現(xiàn)原型模式的一個簡單示例:

// 抽象原型
public interface IPrototype
{
    IPrototype Clone();
}
// 具體原型
public class ConcretePrototype : IPrototype
{
    public string Name { get; set; }
    public int Value { get; set; }
    public IPrototype Clone()
    {
        // 實現(xiàn)深拷貝
        return (ConcretePrototype)this.MemberwiseClone(); // Clones the concrete object.
    }
}

以上代碼定義了一個ConcretePrototype類,它實現(xiàn)了IPrototype接口。接口定義了一個Clone方法,用于復(fù)制對象。在ConcretePrototype類中,我們使用了MemberwiseClone方法來創(chuàng)建一個新的克隆對象。

以下是一個使用原型模式的示例:

class Program
{
    static void Main(string[] args)
    {
        ConcretePrototype prototype = new ConcretePrototype();
        prototype.Name = "Original";
        prototype.Value = 10;
        Console.WriteLine("Original instance: " + prototype.Name + ", " + prototype.Value);
        ConcretePrototype clone = (ConcretePrototype)prototype.Clone();
        Console.WriteLine("Cloned instance: " + clone.Name + ", " + clone.Value);
        Console.ReadLine();
    }
}

在這個例子中,我們創(chuàng)建了一個ConcretePrototype對象,并為其屬性賦值,然后我們調(diào)用Clone方法創(chuàng)建了一個新的ConcretePrototype對象。當(dāng)我們運行這個程序時,會看到原始對象和克隆對象的屬性是相同的,這表明我們已經(jīng)成功地克隆了一個對象。

執(zhí)行流程如下:

  • 創(chuàng)建一個具體的原型對象,為其屬性賦值。
  • 調(diào)用原型對象的Clone方法,創(chuàng)建一個新的對象,該對象的屬性與原型對象的屬性相同。
  • 打印原型對象和克隆對象的屬性,驗證它們是否相同。

結(jié)構(gòu)型模式

1. 橋接模式(Bridge)

橋接模式是一種結(jié)構(gòu)型設(shè)計模式,用于將抽象部分與其實現(xiàn)部分分離,使它們都可以獨立地變化。

以下是在C#中實現(xiàn)橋接模式的一個簡單示例:

// 實現(xiàn)類接口
public interface IImplementor
{
    void OperationImp();
}
// 具體實現(xiàn)類A
public class ConcreteImplementorA : IImplementor
{
    public void OperationImp()
    {
        Console.WriteLine("Concrete Implementor A");
    }
}
// 具體實現(xiàn)類B
public class ConcreteImplementorB : IImplementor
{
    public void OperationImp()
    {
        Console.WriteLine("Concrete Implementor B");
    }
}
// 抽象類
public abstract class Abstraction
{
    protected IImplementor implementor;
    public Abstraction(IImplementor implementor)
    {
        this.implementor = implementor;
    }
    public virtual void Operation()
    {
        implementor.OperationImp();
    }
}
// 擴充的抽象類
public class RefinedAbstraction : Abstraction
{
    public RefinedAbstraction(IImplementor implementor) : base(implementor) { }
    public override void Operation()
    {
        Console.WriteLine("Refined Abstraction is calling implementor's method:");
        base.Operation();
    }
}

在這個代碼中,Abstraction是抽象類,它有一個IImplementor接口的實例,通過這個實例調(diào)用實現(xiàn)類的方法。RefinedAbstraction是擴充的抽象類,它繼承自Abstraction。ConcreteImplementorAConcreteImplementorB是實現(xiàn)類,它們實現(xiàn)了IImplementor接口。

以下是一個使用這個模式的示例:

class Program
{
    static void Main(string[] args)
    {
        IImplementor implementorA = new ConcreteImplementorA();
        Abstraction abstractionA = new RefinedAbstraction(implementorA);
        abstractionA.Operation();
        IImplementor implementorB = new ConcreteImplementorB();
        Abstraction abstractionB = new RefinedAbstraction(implementorB);
        abstractionB.Operation();
        Console.ReadLine();
    }
}

在這個例子中,我們創(chuàng)建了兩個實現(xiàn)類的實例,然后創(chuàng)建了兩個抽象類的實例,每個抽象類的實例都有一個實現(xiàn)類的實例。當(dāng)我們調(diào)用抽象類的Operation方法時,它會調(diào)用實現(xiàn)類的OperationImp方法。

執(zhí)行流程如下:

  • 創(chuàng)建實現(xiàn)類的實例。
  • 創(chuàng)建抽象類的實例,抽象類的實例有一個實現(xiàn)類的實例。
  • 調(diào)用抽象類的Operation方法,該方法會調(diào)用實現(xiàn)類的OperationImp方法。

2. 組合模式(Composite)

組合模式(Composite pattern)是一種結(jié)構(gòu)型設(shè)計模式,它可以使你將對象組合成樹形結(jié)構(gòu),并且能像使用獨立對象一樣使用它們。這種模式的主要目的是使單個對象和組合對象具有一致性。

以下是在C#中實現(xiàn)組合模式的一個簡單示例:

// 抽象組件類
public abstract class Component
{
    protected string name;
    public Component(string name)
    {
        this.name = name;
    }
    public abstract void Add(Component c);
    public abstract void Remove(Component c);
    public abstract void Display(int depth);
}
// 葉節(jié)點類
public class Leaf : Component
{
    public Leaf(string name) : base(name) { }
    public override void Add(Component c)
    {
        Console.WriteLine("Cannot add to a leaf");
    }
    public override void Remove(Component c)
    {
        Console.WriteLine("Cannot remove from a leaf");
    }
    public override void Display(int depth)
    {
        Console.WriteLine(new String('-', depth) + name);
    }
}
// 構(gòu)件容器類
public class Composite : Component
{
    private List<Component> _children = new List<Component>();
    public Composite(string name) : base(name) { }
    public override void Add(Component component)
    {
        _children.Add(component);
    }
    public override void Remove(Component component)
    {
        _children.Remove(component);
    }
    public override void Display(int depth)
    {
        Console.WriteLine(new String('-', depth) + name);
        // 顯示每個節(jié)點的子節(jié)點
        foreach (Component component in _children)
        {
            component.Display(depth + 2);
        }
    }
}

在這個代碼中,Component是組件抽象類,它有一個名字,并定義了添加、刪除和顯示操作。Leaf是葉子節(jié)點,它實現(xiàn)了Component的操作。Composite是組件容器,它可以添加、刪除和顯示其子節(jié)點。

以下是一個使用這個模式的示例:

class Program
{
    static void Main(string[] args)
    {
        Composite root = new Composite("root");
        root.Add(new Leaf("Leaf A"));
        root.Add(new Leaf("Leaf B"));
        Composite comp = new Composite("Composite X");
        comp.Add(new Leaf("Leaf XA"));
        comp.Add(new Leaf("Leaf XB"));
        root.Add(comp);
        Composite comp2 = new Composite("Composite XY");
        comp2.Add(new Leaf("Leaf XYA"));
        comp2.Add(new Leaf("Leaf XYB"));
        comp.Add(comp2);
        root.Add(new Leaf("Leaf C"));
        // 在組合中添加和刪除
        Leaf leaf = new Leaf("Leaf D");
        root.Add(leaf);
        root.Remove(leaf);
        // 顯示樹形結(jié)構(gòu)
        root.Display(1);
        Console.ReadLine();
    }
}

在這個例子中,我們創(chuàng)建了一個根節(jié)點,并在其中添加了兩個葉子節(jié)點。然后我們創(chuàng)建了一個復(fù)合節(jié)點,并在其中添加了兩個葉子節(jié)點,然后我們把復(fù)合節(jié)點添加到根節(jié)點中。我們還在復(fù)合節(jié)點中添加了另一個復(fù)合節(jié)點。最后,我們又在根節(jié)點中添加和刪除了一個葉子節(jié)點,然后顯示了樹的結(jié)構(gòu)。

執(zhí)行流程如下:

  • 創(chuàng)建組合和葉子對象。
  • 通過調(diào)用組合對象的Add方法將葉子對象和其他組合對象添加到組合對象中。
  • 通過調(diào)用組合對象的Remove方法將葉子對象從組合對象中移除。
  • 調(diào)用組合對象的Display方法顯示組合對象的結(jié)構(gòu)。

3. 裝飾模式(Decorator)

裝飾模式是一種結(jié)構(gòu)型設(shè)計模式,它允許在運行時動態(tài)地將功能添加到對象中,這種模式提供了比繼承更有彈性的解決方案。

以下是在C#中實現(xiàn)裝飾模式的一個簡單示例:

// 抽象組件
public abstract class Component
{
    public abstract string Operation();
}
// 具體組件
public class ConcreteComponent : Component
{
    public override string Operation()
    {
        return "ConcreteComponent";
    }
}
// 抽象裝飾器
public abstract class Decorator : Component
{
    protected Component component;
    public Decorator(Component component)
    {
        this.component = component;
    }
    public override string Operation()
    {
        if (component != null)
        {
            return component.Operation();
        }
        else
        {
            return string.Empty;
        }
    }
}
// 具體裝飾器A
public class ConcreteDecoratorA : Decorator
{
    public ConcreteDecoratorA(Component comp) : base(comp) { }
    public override string Operation()
    {
        return $"ConcreteDecoratorA({base.Operation()})";
    }
}
// 具體裝飾器B
public class ConcreteDecoratorB : Decorator
{
    public ConcreteDecoratorB(Component comp) : base(comp) { }
    public override string Operation()
    {
        return $"ConcreteDecoratorB({base.Operation()})";
    }
}

在這個代碼中,Component是一個抽象組件,它定義了一個Operation方法。ConcreteComponent是具體組件,它實現(xiàn)了ComponentOperation方法。Decorator是一個抽象裝飾器,它包含一個Component對象,并重寫了Operation方法。ConcreteDecoratorAConcreteDecoratorB是具體的裝飾器,它們繼承了Decorator并重寫了Operation方法,以添加新的功能。

以下是一個使用這個模式的示例:

class Program
{
    static void Main(string[] args)
    {
        // 基本組件
        Component component = new ConcreteComponent();
        Console.WriteLine("Basic Component: " + component.Operation());
        // 裝飾后的組件
        Component decoratorA = new ConcreteDecoratorA(component);
        Console.WriteLine("A Decorated: " + decoratorA.Operation());
        Component decoratorB = new ConcreteDecoratorB(decoratorA);
        Console.WriteLine("B Decorated: " + decoratorB.Operation());
        Console.ReadLine();
    }
}

在這個例子中,我們首先創(chuàng)建了一個ConcreteComponent對象,并調(diào)用它的Operation方法。然后我們創(chuàng)建了一個ConcreteDecoratorA對象,它裝飾了ConcreteComponent,并調(diào)用它的Operation方法。最后,我們創(chuàng)建了一個ConcreteDecoratorB對象,它裝飾了ConcreteDecoratorA,并調(diào)用它的Operation方法。這樣,我們就可以在運行時動態(tài)地添加功能。

執(zhí)行流程如下:

  • 創(chuàng)建一個具體組件對象并調(diào)用其操作。
  • 創(chuàng)建一個裝飾器對象,該對象裝飾了具體組件,并調(diào)用其操作。在操作中,裝飾器首先調(diào)用具體組件的操作,然后執(zhí)行額外的操作。
  • 創(chuàng)建另一個裝飾器對象,裝飾前一個裝飾器,并調(diào)用其操作。在操作中,這個裝飾器首先調(diào)用前一個裝飾器的操作,然后執(zhí)行額外的操作。

4. 外觀模式(Facade)

外觀模式是一種結(jié)構(gòu)型設(shè)計模式,提供了一個統(tǒng)一的接口,用來訪問子系統(tǒng)中的一群接口。外觀模式定義了一個高層接口,讓子系統(tǒng)更容易使用。

以下是在C#中實現(xiàn)外觀模式的一個簡單示例:

// 子系統(tǒng)A
public class SubSystemA
{
    public string OperationA()
    {
        return "SubSystemA, OperationA\n";
    }
}
// 子系統(tǒng)B
public class SubSystemB
{
    public string OperationB()
    {
        return "SubSystemB, OperationB\n";
    }
}
// 子系統(tǒng)C
public class SubSystemC
{
    public string OperationC()
    {
        return "SubSystemC, OperationC\n";
    }
}
// 外觀類
public class Facade
{
    private SubSystemA a = new SubSystemA();
    private SubSystemB b = new SubSystemB();
    private SubSystemC c = new SubSystemC();
    public string OperationWrapper()
    {
        string result = "Facade initializes subsystems:\n";
        result += a.OperationA();
        result += b.OperationB();
        result += c.OperationC();
        return result;
    }
}

在這個代碼中,SubSystemASubSystemBSubSystemC都是子系統(tǒng),每個子系統(tǒng)都有一個操作。Facade是一個外觀類,它封裝了對子系統(tǒng)的操作,提供了一個統(tǒng)一的接口。

以下是一個使用這個模式的示例:

class Program
{
    static void Main(string[] args)
    {
        Facade facade = new Facade();
        Console.WriteLine(facade.OperationWrapper());
        Console.ReadLine();
    }
}

在這個例子中,我們創(chuàng)建了一個Facade對象,并調(diào)用了它的OperationWrapper方法。這個方法封裝了對子系統(tǒng)的操作,使得客戶端可以不直接操作子系統(tǒng),而是通過外觀類操作子系統(tǒng)。

執(zhí)行流程如下:

  • 創(chuàng)建一個外觀對象。
  • 通過調(diào)用外觀對象的方法,間接地操作子系統(tǒng)。
  • 子系統(tǒng)的操作被封裝在外觀對象的方法中,客戶端不需要直接操作子系統(tǒng)。

5. 享元模式(Flyweight)

享元模式(Flyweight Pattern)是一種結(jié)構(gòu)型設(shè)計模式,該模式主要用于減少創(chuàng)建對象的數(shù)量,以減少內(nèi)存占用和提高性能。這種類型的設(shè)計模式屬于結(jié)構(gòu)型模式,它提供了一種減少對象數(shù)量從而改善應(yīng)用所需的對象結(jié)構(gòu)的方式。

以下是在C#中實現(xiàn)享元模式的一個簡單示例:

// 享元類
public class Flyweight
{
    private string intrinsicState;
    // 構(gòu)造函數(shù)
    public Flyweight(string intrinsicState)
    {
        this.intrinsicState = intrinsicState;
    }
    // 業(yè)務(wù)方法
    public void Operation(string extrinsicState)
    {
        Console.WriteLine($"Intrinsic State = {intrinsicState}, Extrinsic State = {extrinsicState}");
    }
}
// 享元工廠類
public class FlyweightFactory
{
    private Dictionary<string, Flyweight> flyweights = new Dictionary<string, Flyweight>();
    public Flyweight GetFlyweight(string key)
    {
        if (!flyweights.ContainsKey(key))
        {
            flyweights[key] = new Flyweight(key);
        }
        return flyweights[key];
    }
    public int GetFlyweightCount()
    {
        return flyweights.Count;
    }
}

在這個代碼中,Flyweight是享元類,它有一個內(nèi)在狀態(tài)intrinsicState,這個狀態(tài)是不變的。FlyweightFactory是享元工廠類,它維護了一個享元對象的集合。

以下是一個使用這個模式的示例:

class Program
{
    static void Main(string[] args)
    {
        FlyweightFactory factory = new FlyweightFactory();
        Flyweight flyweightA = factory.GetFlyweight("A");
        flyweightA.Operation("A operation");
        Flyweight flyweightB = factory.GetFlyweight("B");
        flyweightB.Operation("B operation");
        Flyweight flyweightC = factory.GetFlyweight("A");
        flyweightC.Operation("C operation");
        Console.WriteLine($"Total Flyweights: {factory.GetFlyweightCount()}");
        Console.ReadLine();
    }
}

在這個例子中,我們創(chuàng)建了一個FlyweightFactory對象,并通過它創(chuàng)建了兩個享元對象。注意,當(dāng)我們試圖創(chuàng)建第三個享元對象時,工廠實際上返回了第一個享元對象的引用,因為這兩個對象的內(nèi)在狀態(tài)是相同的。

執(zhí)行流程如下:

  • 創(chuàng)建一個享元工廠對象。
  • 通過享元工廠獲取享元對象。如果對象已經(jīng)存在,則返回現(xiàn)有對象;否則,創(chuàng)建新對象。
  • 執(zhí)行享元對象的操作。
  • 顯示當(dāng)前享元對象的數(shù)量。

6. 代理模式(Proxy)

代理模式是一種結(jié)構(gòu)型設(shè)計模式,它提供了一個對象代替另一個對象來控制對它的訪問。代理對象可以在客戶端和目標(biāo)對象之間起到中介的作用,并添加其他的功能。

以下是在C#中實現(xiàn)代理模式的一個簡單示例:

// 抽象主題接口
public interface ISubject
{
    void Request();
}
// 真實主題
public class RealSubject : ISubject
{
    public void Request()
    {
        Console.WriteLine("RealSubject: Handling Request.");
    }
}
// 代理
public class Proxy : ISubject
{
    private RealSubject _realSubject;
    public Proxy(RealSubject realSubject)
    {
        this._realSubject = realSubject;
    }
    public void Request()
    {
        if (this.CheckAccess())
        {
            this._realSubject.Request();
            this.LogAccess();
        }
    }
    public bool CheckAccess()
    {
        // 檢查是否有權(quán)限訪問
        Console.WriteLine("Proxy: Checking access prior to firing a real request.");
        return true;
    }
    public void LogAccess()
    {
        // 記錄請求
        Console.WriteLine("Proxy: Logging the time of request.");
    }
}

在這個代碼中,ISubject是一個接口,定義了Request方法。RealSubject是實現(xiàn)了ISubject接口的類,Proxy是代理類,它也實現(xiàn)了ISubject接口,并持有一個RealSubject對象的引用。

以下是一個使用這個模式的示例:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Client: Executing the client code with a real subject:");
        RealSubject realSubject = new RealSubject();
        realSubject.Request();
        Console.WriteLine();
        Console.WriteLine("Client: Executing the same client code with a proxy:");
        Proxy proxy = new Proxy(realSubject);
        proxy.Request();
        Console.ReadLine();
    }
}

在這個例子中,我們首先直接調(diào)用了RealSubjectRequest方法,然后我們通過代理調(diào)用了相同的方法。注意,在通過代理調(diào)用Request方法時,代理還執(zhí)行了其他的操作,如檢查訪問權(quán)限和記錄日志。

執(zhí)行流程如下:

  • 創(chuàng)建一個真實主題對象,并直接調(diào)用其Request方法。
  • 創(chuàng)建一個代理對象,代理對象包含一個真實主題的引用。
  • 通過代理對象調(diào)用Request方法。在這個方法中,代理首先檢查訪問權(quán)限,然后調(diào)用真實主題的Request方法,最后記錄日志。

行為型模式

1. 命令模式(Command)

命令模式(Command Pattern)是一種數(shù)據(jù)驅(qū)動的設(shè)計模式,它屬于行為型模式。在命令模式中,請求在對象中封裝成為一個操作或行為,這些請求被送到調(diào)用對象,調(diào)用對象尋找可以處理該命令的合適的對象,并把命令直接送達到對應(yīng)的對象,該對象會執(zhí)行這些命令。

以下是在C#中實現(xiàn)命令模式的一個簡單示例:

// 命令接口
public interface ICommand
{
    void Execute();
}
// 具體命令類
public class ConcreteCommand : ICommand
{
    private Receiver receiver;
    public ConcreteCommand(Receiver receiver)
    {
        this.receiver = receiver;
    }
    public void Execute()
    {
        receiver.Action();
    }
}
// 接收者類
public class Receiver
{
    public void Action()
    {
        Console.WriteLine("Receiver performs an action");
    }
}
// 調(diào)用者或發(fā)送者類
public class Invoker
{
    private ICommand command;
    public void SetCommand(ICommand command)
    {
        this.command = command;
    }
    public void ExecuteCommand()
    {
        command.Execute();
    }
}

在這個代碼中,ICommand是命令接口,定義了Execute方法。ConcreteCommand是具體的命令類,它實現(xiàn)了ICommand接口,并持有一個Receiver對象的引用。Invoker是調(diào)用者或發(fā)送者類,它持有一個ICommand對象的引用,并可以通過SetCommand方法設(shè)置命令,通過ExecuteCommand方法執(zhí)行命令。

以下是一個使用這個模式的示例:

class Program
{
    static void Main(string[] args)
    {
        Receiver receiver = new Receiver();
        ICommand command = new ConcreteCommand(receiver);
        Invoker invoker = new Invoker();
        invoker.SetCommand(command);
        invoker.ExecuteCommand();
        Console.ReadLine();
    }
}

在這個例子中,我們創(chuàng)建了一個Receiver對象、一個ConcreteCommand對象和一個Invoker對象。然后我們通過InvokerSetCommand方法設(shè)置了命令,并通過ExecuteCommand方法執(zhí)行了命令。

執(zhí)行流程如下:

  • 創(chuàng)建一個接收者對象。
  • 創(chuàng)建一個具體命令對象,并將接收者對象傳遞給它。
  • 創(chuàng)建一個調(diào)用者或發(fā)送者對象。
  • 通過調(diào)用者對象的SetCommand方法設(shè)置命令。
  • 通過調(diào)用者對象的ExecuteCommand方法執(zhí)行命令。

2. 解釋器模式(Interpreter)

解釋器模式(Interpreter Pattern)是一種行為型設(shè)計模式,用于解決一些固定語法格式的需求。它定義了如何在語言中表示和解析語法。

以下是在C#中實現(xiàn)解釋器模式的一個簡單示例:

// 抽象表達式
public interface IExpression
{
    bool Interpret(string context);
}
// 終結(jié)符表達式
public class TerminalExpression : IExpression
{
    private string data;
    public TerminalExpression(string data)
    {
        this.data = data;
    }
    public bool Interpret(string context)
    {
        if (context.Contains(data))
        {
            return true;
        }
        return false;
    }
}
// 非終結(jié)符表達式
public class OrExpression : IExpression
{
    private IExpression expr1 = null;
    private IExpression expr2 = null;
    public OrExpression(IExpression expr1, IExpression expr2)
    {
        this.expr1 = expr1;
        this.expr2 = expr2;
    }
    public bool Interpret(string context)
    {
        return expr1.Interpret(context) || expr2.Interpret(context);
    }
}

在這個代碼中,IExpression是抽象表達式,定義了Interpret方法。TerminalExpression是終結(jié)符表達式,它實現(xiàn)了IExpression接口。OrExpression是非終結(jié)符表達式,它也實現(xiàn)了IExpression接口。

以下是一個使用這個模式的示例:

class Program
{
    static void Main(string[] args)
    {
        IExpression isMale = GetMaleExpression();
        IExpression isMarriedWoman = GetMarriedWomanExpression();
        Console.WriteLine($"John is male? {isMale.Interpret("John")}");
        Console.WriteLine($"Julie is a married women? {isMarriedWoman.Interpret("Married Julie")}");
        Console.ReadLine();
    }
    // 規(guī)則:Robert 和 John 是男性
    public static IExpression GetMaleExpression()
    {
        IExpression robert = new TerminalExpression("Robert");
        IExpression john = new TerminalExpression("John");
        return new OrExpression(robert, john);
    }
    // 規(guī)則:Julie 是一個已婚的女性
    public static IExpression GetMarriedWomanExpression()
    {
        IExpression julie = new TerminalExpression("Julie");
        IExpression married = new TerminalExpression("Married");
        return new OrExpression(julie, married);
    }
}

在這個例子中,我們定義了兩個規(guī)則,"Robert和John是男性"和"Julie是一個已婚的女性"。我們?nèi)缓髣?chuàng)建了兩個表達式對象,分別表示這兩個規(guī)則,并使用這兩個對象來解析輸入。

執(zhí)行流程如下:

  • 創(chuàng)建終結(jié)符表達式對象和非終結(jié)符表達式對象,用于表示規(guī)則。
  • 調(diào)用表達式對象的Interpret方法,解析輸入的字符串。
  • 輸出解析結(jié)果。

3. 迭代器模式(Iterator)

迭代器模式(Iterator Pattern)是一種行為型設(shè)計模式,它提供了一種方法來訪問一個對象的元素,而不需要暴露該對象的內(nèi)部表示。以下是在C#中實現(xiàn)迭代器模式的一個簡單示例:

// 抽象聚合類
public interface IAggregate
{
    IIterator CreateIterator();
    void Add(string item);
    int Count { get; }
    string this[int index] { get; set; }
}
// 具體聚合類
public class ConcreteAggregate : IAggregate
{
    private List<string> items = new List<string>();
    public IIterator CreateIterator()
    {
        return new ConcreteIterator(this);
    }
    public int Count
    {
        get { return items.Count; }
    }
    public string this[int index]
    {
        get { return items[index]; }
        set { items.Insert(index, value); }
    }
    public void Add(string item)
    {
        items.Add(item);
    }
}
// 抽象迭代器
public interface IIterator
{
    string First();
    string Next();
    bool IsDone { get; }
    string CurrentItem { get; }
}
// 具體迭代器
public class ConcreteIterator : IIterator
{
    private ConcreteAggregate aggregate;
    private int current = 0;
    public ConcreteIterator(ConcreteAggregate aggregate)
    {
        this.aggregate = aggregate;
    }
    public string First()
    {
        return aggregate[0];
    }
    public string Next()
    {
        string ret = null;
        if (current < aggregate.Count - 1)
        {
            ret = aggregate[++current];
        }
        return ret;
    }
    public string CurrentItem
    {
        get { return aggregate[current]; }
    }
    public bool IsDone
    {
        get { return current >= aggregate.Count; }
    }
}

在這個代碼中,IAggregate是抽象聚合類,定義了CreateIterator等方法,ConcreteAggregate是具體聚合類,實現(xiàn)了IAggregate接口。IIterator是抽象迭代器,定義了First、Next等方法,ConcreteIterator是具體迭代器,實現(xiàn)了IIterator接口。

以下是一個使用這個模式的示例:

class Program
{
    static void Main(string[] args)
    {
        IAggregate aggregate = new ConcreteAggregate();
        aggregate.Add("Item A");
        aggregate.Add("Item B");
        aggregate.Add("Item C");
        aggregate.Add("Item D");
        IIterator iterator = aggregate.CreateIterator();
        Console.WriteLine("Iterating over collection:");
        string item = iterator.First();
        while (item != null)
        {
            Console.WriteLine(item);
            item = iterator.Next();
        }
        Console.ReadLine();
    }
}

在這個例子中,我們創(chuàng)建了一個ConcreteAggregate對象,并添加了幾個元素。然后我們通過CreateIterator方法創(chuàng)建了一個迭代器,并使用這個迭代器遍歷了集合中的所有元素。

執(zhí)行流程如下:

  • 創(chuàng)建一個聚合對象,并添加一些元素。
  • 通過聚合對象的CreateIterator方法創(chuàng)建一個迭代器。
  • 通過迭代器的First方法獲取第一個元素,然后通過Next方法獲取后續(xù)的元素,直到獲取不到元素為止。

4. 中介者模式(Mediator)

中介者模式是一種行為設(shè)計模式,它讓你能減少一組對象之間復(fù)雜的通信。它提供了一個中介者對象,此對象負責(zé)在組中的對象之間進行通信,而不是這些對象直接進行通信。

首先,讓我們定義一個中介者接口和一個具體的中介者:

// Mediator 接口聲明了與組件交互的方法。
public interface IMediator
{
    void Notify(object sender, string ev);
}
// 具體 Mediators 實現(xiàn)協(xié)作行為,它負責(zé)協(xié)調(diào)多個組件。
public class ConcreteMediator : IMediator
{
    private Component1 _component1;
    private Component2 _component2;
    public ConcreteMediator(Component1 component1, Component2 component2)
    {
        _component1 = component1;
        _component1.SetMediator(this);
        _component2 = component2;
        _component2.SetMediator(this);
    }
    public void Notify(object sender, string ev)
    {
        if (ev == "A")
        {
            Console.WriteLine("Mediator reacts on A and triggers following operations:");
            this._component2.DoC();
        }
        if (ev == "D")
        {
            Console.WriteLine("Mediator reacts on D and triggers following operations:");
            this._component1.DoB();
            this._component2.DoC();
        }
    }
}

接著,我們定義一個基礎(chǔ)組件類和兩個具體組件:

public abstract class BaseComponent
{
    protected IMediator _mediator;
    public BaseComponent(IMediator mediator = null)
    {
        _mediator = mediator;
    }
    public void SetMediator(IMediator mediator)
    {
        this._mediator = mediator;
    }
}
// 具體 Components 實現(xiàn)各種功能。它們不依賴于其他組件。
// 它們也不依賴于任何具體 Mediator 類。
public class Component1 : BaseComponent
{
    public void DoA()
    {
        Console.WriteLine("Component 1 does A.");
        this._mediator.Notify(this, "A");
    }
    public void DoB()
    {
        Console.WriteLine("Component 1 does B.");
        this._mediator.Notify(this, "B");
    }
}
public class Component2 : BaseComponent
{
    public void DoC()
    {
        Console.WriteLine("Component 2 does C.");
        this._mediator.Notify(this, "C");
    }
    public void DoD()
    {
        Console.WriteLine("Component 2 does D.");
        this._mediator.Notify(this, "D");
    }
}

最后,我們來創(chuàng)建一個客戶端代碼:

class Program
{
    static void Main(string[] args)
    {
        // The client code.
        Component1 component1 = new Component1();
        Component2 component2 = new Component2();
        new ConcreteMediator(component1, component2);
        Console.WriteLine("Client triggers operation A.");
        component1.DoA();
        Console.WriteLine();
        Console.WriteLine("Client triggers operation D.");
        component2.DoD();
    }
}

這個示例中的各個組件通過中介者來進行通信,而不是直接通信,這樣就可以減少組件之間的依賴性,使得它們可以更容易地被獨立修改。當(dāng)一個組件發(fā)生某個事件(例如"Component 1 does A")時,它會通過中介者來通知其他組件,這樣其他組件就可以根據(jù)這個事件來做出響應(yīng)(例如"Component 2 does C")。

5. 備忘錄模式(Memento)

備忘錄模式是一種行為設(shè)計模式,它能保存對象的狀態(tài),以便在后面可以恢復(fù)它。在大多數(shù)情況下,這種模式可以讓你在不破壞對象封裝的前提下,保存和恢復(fù)對象的歷史狀態(tài)。

以下是一個簡單的備忘錄模式的實現(xiàn),其中有三個主要的類:Originator(保存了一個重要的狀態(tài),這個狀態(tài)可能會隨著時間改變),Memento(保存了Originator的一個快照,這個快照包含了Originator的狀態(tài)),以及Caretaker(負責(zé)保存Memento)。

// Originator 類可以生成一個備忘錄,并且可以通過備忘錄恢復(fù)其狀態(tài)。
public class Originator
{
    private string _state;
    public Originator(string state)
    {
        this._state = state;
        Console.WriteLine($"Originator: My initial state is: {_state}");
    }
    public void DoSomething()
    {
        Console.WriteLine("Originator: I'm doing something important.");
        _state = GenerateRandomString(30);
        Console.WriteLine($"Originator: and my state has changed to: {_state}");
    }
    private string GenerateRandomString(int length = 10)
    {
        string allowedSymbols = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        string result = string.Empty;
        while (length > 0)
        {
            result += allowedSymbols[new Random().Next(0, allowedSymbols.Length)];
            length--;
        }
        return result;
    }
    public IMemento Save()
    {
        return new ConcreteMemento(_state);
    }
    public void Restore(IMemento memento)
    {
        _state = memento.GetState();
        Console.WriteLine($"Originator: My state has changed to: {_state}");
    }
}
// 備忘錄接口提供了獲取備忘錄和原發(fā)器狀態(tài)的方法。但在該接口中并未聲明所有的方法,一些方法只在原發(fā)器中聲明。
public interface IMemento
{
    string GetName();
    string GetState();
    DateTime GetDate();
}
// Concrete Memento 存儲原發(fā)器狀態(tài),并通過原發(fā)器實現(xiàn)備份。備忘錄是不可變的,因此,沒有 set 方法。
public class ConcreteMemento : IMemento
{
    private string _state;
    private DateTime _date;
    public ConcreteMemento(string state)
    {
        _state = state;
        _date = DateTime.Now;
    }
    public string GetState()
    {
        return _state;
    }
    public string GetName()
    {
        return $"{_date} / ({_state.Substring(0, 9)})...";
    }
    public DateTime GetDate()
    {
        return _date;
    }
}
// Caretaker 不依賴于具體備忘錄類。結(jié)果,它不會有任何訪問原發(fā)器狀態(tài)的權(quán)利,它只能獲取備忘錄的元數(shù)據(jù)。
public class Caretaker
{
    private List<IMemento> _mementos = new List<IMemento>();
    private Originator _originator = null;
    public Caretaker(Originator originator)
    {
        this._originator = originator;
    }
    public void Backup()
    {
        Console.WriteLine("\nCaretaker: Saving Originator's state...");
        _mementos.Add(_originator.Save());
    }
    public void Undo()
    {
        if (_mementos.Count == 0)
        {
            return;
        }
        var memento = _mementos.Last();
        _mementos.Remove(memento);
        Console.WriteLine("Caretaker: Restoring state to: " + memento.GetName());
        try
        {
            _originator.Restore(memento);
        }
        catch (Exception)
        {
            Undo();
        }
    }
    public void ShowHistory()
    {
        Console.WriteLine("Caretaker: Here's the list of mementos:");
        foreach (var memento in _mementos)
        {
            Console.WriteLine(memento.GetName());
        }
    }
}
// 客戶端代碼
class Program
{
    static void Main(string[] args)
    {
        Originator originator = new Originator("Super-duper-super-puper-super.");
        Caretaker caretaker = new Caretaker(originator);
        caretaker.Backup();
        originator.DoSomething();
        caretaker.Backup();
        originator.DoSomething();
        caretaker.Backup();
        originator.DoSomething();
        Console.WriteLine();
        caretaker.ShowHistory();
        Console.WriteLine("\nClient: Now, let's rollback!\n");
        caretaker.Undo();
        Console.WriteLine("\nClient: Once more!\n");
        caretaker.Undo();
    }
}

以上的代碼中,Originator 持有一些重要的狀態(tài),并且提供了方法去保存它的狀態(tài)到一個備忘錄對象以及從備忘錄對象中恢復(fù)它的狀態(tài)。Caretaker 負責(zé)保存?zhèn)渫洠撬荒懿僮鱾渫泴ο笾械臓顟B(tài)。當(dāng)用戶執(zhí)行操作時,我們先保存當(dāng)前的狀態(tài),然后執(zhí)行操作。如果用戶后來不滿意新的狀態(tài),他們可以方便地從舊的備忘錄中恢復(fù)狀態(tài)。

6. 觀察者模式(Observer)

觀察者模式(Observer Pattern)是一種行為型設(shè)計模式,當(dāng)一個對象的狀態(tài)發(fā)生變化時,依賴它的所有對象都會得到通知并被自動更新。以下是在C#中實現(xiàn)觀察者模式的一個簡單示例:

// 抽象觀察者
public interface IObserver
{
    void Update();
}
// 具體觀察者
public class ConcreteObserver : IObserver
{
    private string name;
    public ConcreteObserver(string name)
    {
        this.name = name;
    }
    public void Update()
    {
        Console.WriteLine($"{name} received an update!");
    }
}
// 抽象主題
public interface ISubject
{
    void RegisterObserver(IObserver observer);
    void RemoveObserver(IObserver observer);
    void NotifyObservers();
}
// 具體主題
public class ConcreteSubject : ISubject
{
    private List<IObserver> observers = new List<IObserver>();
    public void RegisterObserver(IObserver observer)
    {
        observers.Add(observer);
    }
    public void RemoveObserver(IObserver observer)
    {
        if (observers.Contains(observer))
        {
            observers.Remove(observer);
        }
    }
    public void NotifyObservers()
    {
        foreach (var observer in observers)
        {
            observer.Update();
        }
    }
    public void ChangeState()
    {
        // 觸發(fā)狀態(tài)變化,通知所有觀察者
        NotifyObservers();
    }
}

在這個代碼中,IObserver是抽象觀察者,定義了Update方法,ConcreteObserver是具體觀察者,實現(xiàn)了IObserver接口。ISubject是抽象主題,定義了RegisterObserver、RemoveObserverNotifyObservers方法,ConcreteSubject是具體主題,實現(xiàn)了ISubject接口。

以下是一個使用這個模式的示例:

class Program
{
    static void Main(string[] args)
    {
        ConcreteSubject subject = new ConcreteSubject();
        subject.RegisterObserver(new ConcreteObserver("Observer 1"));
        subject.RegisterObserver(new ConcreteObserver("Observer 2"));
        subject.RegisterObserver(new ConcreteObserver("Observer 3"));
        subject.ChangeState();
        Console.ReadLine();
    }
}

在這個例子中,我們創(chuàng)建了一個ConcreteSubject對象,并注冊了三個觀察者。然后我們通過ChangeState方法改變了主題的狀態(tài),這會觸發(fā)主題通知所有觀察者。

執(zhí)行流程如下:

  • 創(chuàng)建一個具體主題對象。
  • 創(chuàng)建幾個具體觀察者對象,并通過主題的RegisterObserver方法將這些觀察者注冊到主題中。
  • 通過主題的ChangeState方法改變主題的狀態(tài),這會觸發(fā)主題通知所有觀察者。

7. 狀態(tài)模式(State)

狀態(tài)模式在面向?qū)ο缶幊讨校且环N允許對象在其內(nèi)部狀態(tài)改變時改變其行為的設(shè)計模式。這種類型的設(shè)計模式屬于行為型模式。在狀態(tài)模式中,我們創(chuàng)建對象表示各種狀態(tài),以及一個行為隨狀態(tài)改變而改變的上下文對象。

以下是一個狀態(tài)模式的示例。這個示例中,我們將創(chuàng)建一個銀行賬戶,它有兩個狀態(tài):正常狀態(tài)(NormalState)和透支狀態(tài)(OverdrawnState)。當(dāng)用戶執(zhí)行操作(存款和取款)時,賬戶狀態(tài)將相應(yīng)地進行更改。

首先,我們定義一個表示狀態(tài)的接口:

public interface IAccountState
{
    void Deposit(Action addToBalance);
    void Withdraw(Action subtractFromBalance);
    void ComputeInterest();
}

然后,我們創(chuàng)建兩個表示具體狀態(tài)的類:

public class NormalState : IAccountState
{
    public void Deposit(Action addToBalance)
    {
        addToBalance();
        Console.WriteLine("Deposit in NormalState");
    }
    public void Withdraw(Action subtractFromBalance)
    {
        subtractFromBalance();
        Console.WriteLine("Withdraw in NormalState");
    }
    public void ComputeInterest()
    {
        Console.WriteLine("Interest computed in NormalState");
    }
}
public class OverdrawnState : IAccountState
{
    public void Deposit(Action addToBalance)
    {
        addToBalance();
        Console.WriteLine("Deposit in OverdrawnState");
    }
    public void Withdraw(Action subtractFromBalance)
    {
        Console.WriteLine("No withdraw in OverdrawnState");
    }
    public void ComputeInterest()
    {
        Console.WriteLine("Interest and fees computed in OverdrawnState");
    }
}

然后,我們創(chuàng)建一個Context類,它使用這些狀態(tài)來執(zhí)行其任務(wù):

public class BankAccount
{
    private IAccountState _state;
    private double _balance;
    public BankAccount(IAccountState state)
    {
        _state = state;
        _balance = 0;
    }
    public void Deposit(double amount)
    {
        _state.Deposit(() => _balance += amount);
        StateChangeCheck();
    }
    public void Withdraw(double amount)
    {
        _state.Withdraw(() => _balance -= amount);
        StateChangeCheck();
    }
    public void ComputeInterest()
    {
        _state.ComputeInterest();
    }
    private void StateChangeCheck()
    {
        if (_balance < 0.0)
            _state = new OverdrawnState();
        else
            _state = new NormalState();
    }
}

現(xiàn)在,你可以創(chuàng)建一個實例并運行一個Demo來測試這個狀態(tài)模式的代碼:

public class Program
{
    public static void Main(string[] args)
    {
        var account = new BankAccount(new NormalState());
        account.Deposit(1000); // Deposit in NormalState
        account.Withdraw(2000); // Withdraw in NormalState; No withdraw in OverdrawnState
        account.Deposit(100); // Deposit in OverdrawnState
        account.ComputeInterest(); // Interest and fees computed in OverdrawnState
        Console.ReadKey();
    }
}

這個程序首先在正常狀態(tài)下進行存款操作,然后嘗試進行取款操作。由于取款金額超過賬戶余額,所以賬戶進入透支狀態(tài),并阻止進一步的取款操作。但存款仍然被允許,以使賬戶回歸到正常狀態(tài)。計算利息的行為也根據(jù)賬戶的狀態(tài)變化而變化。

8. 策略模式(Strategy)

策略模式定義了一系列的算法,并將每一個算法封裝起來,使得它們可以相互替換。策略模式讓算法獨立于使用它的客戶而獨立變化。

以下是一個簡單的策略模式的C#實現(xiàn)。這個例子中,我們將創(chuàng)建一個排序策略,比如快速排序和冒泡排序,它們實現(xiàn)同一個接口,然后創(chuàng)建一個Context類,它使用這些策略來執(zhí)行排序操作。

首先,我們定義一個表示排序策略的接口:

public interface ISortStrategy
{
    void Sort(List<int> list);
}

然后,我們創(chuàng)建兩個表示具體策略的類:

public class QuickSort : ISortStrategy
{
    public void Sort(List<int> list)
    {
        list.Sort();  // Quick sort is in-place but here we are using built-in method
        Console.WriteLine("QuickSorted list ");
    }
}
public class BubbleSort : ISortStrategy
{
    public void Sort(List<int> list)
    {
        int n = list.Count;
        for (int i = 0; i < n - 1; i++)
            for (int j = 0; j < n - i - 1; j++)
                if (list[j] > list[j + 1])
                {
                    // swap temp and list[i]
                    int temp = list[j];
                    list[j] = list[j + 1];
                    list[j + 1] = temp;
                }
        Console.WriteLine("BubbleSorted list ");
    }
}

然后,我們創(chuàng)建一個Context類,它使用這些策略來執(zhí)行其任務(wù):

public class SortedList
{
    private List<int> _list = new List<int>();
    private ISortStrategy _sortstrategy;
    public void SetSortStrategy(ISortStrategy sortstrategy)
    {
        this._sortstrategy = sortstrategy;
    }
    public void Add(int num)
    {
        _list.Add(num);
    }
    public void Sort()
    {
        _sortstrategy.Sort(_list);
        // Print sorted list
        foreach (int num in _list)
        {
            Console.Write(num + " ");
        }
        Console.WriteLine();
    }
}

現(xiàn)在,你可以創(chuàng)建一個實例并運行一個Demo來測試這個策略模式的代碼:

public class Program
{
    public static void Main(string[] args)
    {
        SortedList sortedList = new SortedList();
        sortedList.Add(1);
        sortedList.Add(5);
        sortedList.Add(3);
        sortedList.Add(4);
        sortedList.Add(2);
        sortedList.SetSortStrategy(new QuickSort());
        sortedList.Sort();  // Output: QuickSorted list 1 2 3 4 5 
        sortedList.SetSortStrategy(new BubbleSort());
        sortedList.Sort();  // Output: BubbleSorted list 1 2 3 4 5 
        Console.ReadKey();
    }
}

這個程序首先創(chuàng)建了一個未排序的列表,然后它首先使用快速排序策略進行排序,接著又使用冒泡排序策略進行排序。

9. 模板方法模式(Template Method)

模板方法模式定義了一個操作中算法的骨架,將這些步驟延遲到子類中。模板方法使得子類可以不改變算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟。

以下是一個模板方法模式的示例。這個示例中,我們將創(chuàng)建一個烹飪食物的過程,這個過程有一些固定的步驟(例如準(zhǔn)備材料,清理),但是具體的烹飪步驟則取決于具體的食物。

首先,我們定義一個抽象的模板類:

public abstract class CookingProcedure
{
    // The 'Template method' 
    public void PrepareDish()
    {
        PrepareIngredients();
        Cook();
        CleanUp();
    }
    public void PrepareIngredients()
    {
        Console.WriteLine("Preparing the ingredients...");
    }
    // These methods will be overridden by subclasses
    public abstract void Cook();
    public void CleanUp()
    {
        Console.WriteLine("Cleaning up...");
    }
}

然后,我們創(chuàng)建兩個具體的子類,它們分別實現(xiàn)了具體的烹飪步驟:

public class CookPasta : CookingProcedure
{
    public override void Cook()
    {
        Console.WriteLine("Cooking pasta...");
    }
}
public class BakeCake : CookingProcedure
{
    public override void Cook()
    {
        Console.WriteLine("Baking cake...");
    }
}

現(xiàn)在,你可以創(chuàng)建一個實例并運行一個Demo來測試這個模板方法模式的代碼:

public class Program
{
    public static void Main(string[] args)
    {
        CookingProcedure cookingProcedure = new CookPasta();
        cookingProcedure.PrepareDish();
        Console.WriteLine();
        cookingProcedure = new BakeCake();
        cookingProcedure.PrepareDish();
        Console.ReadKey();
    }
}

在這個程序中,我們首先創(chuàng)建了一個CookPasta對象,然后調(diào)用其PrepareDish方法。然后,我們創(chuàng)建了一個BakeCake對象,再次調(diào)用其PrepareDish方法。這兩個對象雖然具有不同的Cook方法,但是它們的PrepareDish方法的結(jié)構(gòu)(即算法的骨架)是相同的。

10. 訪問者模式(Visitor)

訪問者模式(Visitor Pattern)是一種將算法與對象結(jié)構(gòu)分離的軟件設(shè)計模式。這種模式的基本想法就是通過所謂的"訪問者"來改變元素的操作。這樣一來,元素的類可以用于表示元素結(jié)構(gòu),而具體的操作則可以在訪問者類中定義。

以下是一個使用C#實現(xiàn)的訪問者模式示例,包括了詳細的注釋和執(zhí)行流程。

這個示例中有三個主要部分:訪問者(IVisitor)、可訪問元素(IElement)和元素結(jié)構(gòu)(ObjectStructure)。同時有具體訪問者(ConcreteVisitor)和具體元素(ConcreteElement)。

// 訪問者接口
public interface IVisitor
{
    void VisitConcreteElementA(ConcreteElementA concreteElementA);
    void VisitConcreteElementB(ConcreteElementB concreteElementB);
}
// 具體訪問者A
public class ConcreteVisitorA : IVisitor
{
    public void VisitConcreteElementA(ConcreteElementA concreteElementA)
    {
        Console.WriteLine($"{concreteElementA.GetType().Name} is being visited by {this.GetType().Name}");
    }
    public void VisitConcreteElementB(ConcreteElementB concreteElementB)
    {
        Console.WriteLine($"{concreteElementB.GetType().Name} is being visited by {this.GetType().Name}");
    }
}
// 具體訪問者B
public class ConcreteVisitorB : IVisitor
{
    public void VisitConcreteElementA(ConcreteElementA concreteElementA)
    {
        Console.WriteLine($"{concreteElementA.GetType().Name} is being visited by {this.GetType().Name}");
    }
    public void VisitConcreteElementB(ConcreteElementB concreteElementB)
    {
        Console.WriteLine($"{concreteElementB.GetType().Name} is being visited by {this.GetType().Name}");
    }
}
// 元素接口
public interface IElement
{
    void Accept(IVisitor visitor);
}
// 具體元素A
public class ConcreteElementA : IElement
{
    public void Accept(IVisitor visitor)
    {
        visitor.VisitConcreteElementA(this);
    }
}
// 具體元素B
public class ConcreteElementB : IElement
{
    public void Accept(IVisitor visitor)
    {
        visitor.VisitConcreteElementB(this);
    }
}
// 對象結(jié)構(gòu)
public class ObjectStructure
{
    private List<IElement> _elements = new List<IElement>();
    public void Attach(IElement element)
    {
        _elements.Add(element);
    }
    public void Detach(IElement element)
    {
        _elements.Remove(element);
    }
    public void Accept(IVisitor visitor)
    {
        foreach (var element in _elements)
        {
            element.Accept(visitor);
        }
    }
}

執(zhí)行流程如下:

  • 創(chuàng)建具體元素ConcreteElementA和ConcreteElementB的實例。
  • 創(chuàng)建對象結(jié)構(gòu)ObjectStructure的實例,并將步驟1創(chuàng)建的具體元素添加到對象結(jié)構(gòu)中。
  • 創(chuàng)建具體訪問者ConcreteVisitorA和ConcreteVisitorB的實例。
  • 調(diào)用對象結(jié)構(gòu)的Accept方法,傳入步驟3創(chuàng)建的具體訪問者,使具體訪問者訪問對象結(jié)構(gòu)中的所有元素。

以下是一個使用上述代碼的示例:

public class Program
{
    public static void Main()
    {
        ObjectStructure objectStructure = new ObjectStructure();
        objectStructure.Attach(new ConcreteElementA());
        objectStructure.Attach(new ConcreteElementB());
        ConcreteVisitorA visitorA = new ConcreteVisitorA();
        ConcreteVisitorB visitorB = new ConcreteVisitorB();
        objectStructure.Accept(visitorA);
        objectStructure.Accept(visitorB);
        Console.ReadKey();
    }
}

這個程序會打印出訪問者A和訪問者B分別訪問具體元素A和具體元素B的信息。

以上就是C#實現(xiàn)23種常見的設(shè)計模式的示例詳解的詳細內(nèi)容,更多關(guān)于C#設(shè)計模式的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C# 關(guān)于LoadLibrary的疑問詳解

    C# 關(guān)于LoadLibrary的疑問詳解

    這篇文章主要介紹了C# 關(guān)于LoadLibrary的疑問詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • C# Winform調(diào)用百度接口實現(xiàn)人臉識別教程(附源碼)

    C# Winform調(diào)用百度接口實現(xiàn)人臉識別教程(附源碼)

    這篇文章主要介紹了C# Winform調(diào)用百度接口實現(xiàn)人臉識別教程,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • 用C#做網(wǎng)絡(luò)爬蟲的步驟教學(xué)

    用C#做網(wǎng)絡(luò)爬蟲的步驟教學(xué)

    在本篇內(nèi)容里小編給大家分享的是關(guān)于用C#做網(wǎng)絡(luò)爬蟲的步驟和方法,需要的朋友們可以參考下。
    2018-12-12
  • C#自定義基于控制臺的Timer實例

    C#自定義基于控制臺的Timer實例

    這篇文章主要介紹了C#自定義基于控制臺的Timer實現(xiàn)方法,可以簡單模擬timer控件的相關(guān)功能,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-08-08
  • C#動態(tài)調(diào)整數(shù)組大小的方法

    C#動態(tài)調(diào)整數(shù)組大小的方法

    這篇文章主要介紹了C#動態(tài)調(diào)整數(shù)組大小的方法,涉及C#中靜態(tài)方法CreateInstance的使用技巧,非常具有實用價值,需要的朋友可以參考下
    2015-04-04
  • C#實現(xiàn)一鍵清空控件值的示例代碼

    C#實現(xiàn)一鍵清空控件值的示例代碼

    這篇文章主要為大家詳細介紹了如何利用C#語言實現(xiàn)一鍵清空控件值的功能,文中的示例代碼講解詳細,對我們學(xué)習(xí)C#有一定幫助,需要的可以參考一下
    2022-09-09
  • C#實現(xiàn)通過模板自動創(chuàng)建Word文檔的方法

    C#實現(xiàn)通過模板自動創(chuàng)建Word文檔的方法

    這篇文章主要介紹了C#實現(xiàn)通過模板自動創(chuàng)建Word文檔的方法,詳細講述了C#生成Word文檔的實現(xiàn)方法,是非常實用的技巧,需要的朋友可以參考下
    2014-09-09
  • C#調(diào)用dos窗口獲取相關(guān)信息的方法

    C#調(diào)用dos窗口獲取相關(guān)信息的方法

    這篇文章主要介紹了C#調(diào)用dos窗口獲取相關(guān)信息的方法,涉及C#調(diào)用dos窗口及進程操作的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-08-08
  • 基于C#實現(xiàn)屏幕取色器的示例詳解

    基于C#實現(xiàn)屏幕取色器的示例詳解

    這篇文章主要為大家詳細介紹了如何利用C#實現(xiàn)屏幕取色器,文中的示例代碼講解詳細,對我們學(xué)習(xí)C#有一定的幫助,感興趣的小伙伴可以了解一下
    2022-12-12
  • C#圖像處理之圖像平移的方法

    C#圖像處理之圖像平移的方法

    這篇文章主要介紹了C#圖像處理之圖像平移的方法,涉及C#操作圖形實現(xiàn)平移的相關(guān)技巧,需要的朋友可以參考下
    2015-04-04

最新評論