詳細講解23種設計模式

tokengo發表於2023-03-01

工廠方法模式(Factory Method Pattern)

工廠方法模式是一種建立型設計模式,它定義了一個用於建立物件的介面,但由子類決定要例項化的類是哪一個。工廠方法把物件的例項化推遲到子類。

程式碼示例:

csharpCopy codepublic interface IProduct
{
    void Operation();
}

public class ProductA : IProduct
{
    public void Operation()
    {
        Console.WriteLine("Product A operation");
    }
}

public class ProductB : IProduct
{
    public void Operation()
    {
        Console.WriteLine("Product B operation");
    }
}

public abstract class Creator
{
    public abstract IProduct FactoryMethod();
}

public class ConcreteCreatorA : Creator
{
    public override IProduct FactoryMethod()
    {
        return new ProductA();
    }
}

public class ConcreteCreatorB : Creator
{
    public override IProduct FactoryMethod()
    {
        return new ProductB();
    }
}

抽象工廠模式(Abstract Factory Pattern)

抽象工廠模式是一種建立型設計模式,它提供一個介面,用於建立相關或依賴物件的家族,而不需要指定具體類。

程式碼示例:

csharpCopy codepublic interface IProductA
{
    void OperationA();
}

public interface IProductB
{
    void OperationB();
}

public class ProductA1 : IProductA
{
    public void OperationA()
    {
        Console.WriteLine("Product A1 operation");
    }
}

public class ProductA2 : IProductA
{
    public void OperationA()
    {
        Console.WriteLine("Product A2 operation");
    }
}

public class ProductB1 : IProductB
{
    public void OperationB()
    {
        Console.WriteLine("Product B1 operation");
    }
}

public class ProductB2 : IProductB
{
    public void OperationB()
    {
        Console.WriteLine("Product B2 operation");
    }
}

public interface IAbstractFactory
{
    IProductA CreateProductA();
    IProductB CreateProductB();
}

public class ConcreteFactory1 : IAbstractFactory
{
    public IProductA CreateProductA()
    {
        return new ProductA1();
    }

    public IProductB CreateProductB()
    {
        return new ProductB1();
    }
}

public class ConcreteFactory2 : IAbstractFactory
{
    public IProductA CreateProductA()
    {
        return new ProductA2();
    }

    public IProductB CreateProductB()
    {
        return new ProductB2();
    }
}

單例模式(Singleton Pattern)

單例模式是一種建立型設計模式,它確保一個類只有一個例項,並提供全域性訪問點。

程式碼示例:

csharpCopy codepublic sealed class Singleton
{
    private static Singleton instance = null;

    private Singleton() { }

    public static Singleton Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new Singleton();
            }

            return instance;
        }
    }
}

建造者模式(Builder Pattern)

建造者模式是一種建立型設計模式,它可以將一個複雜物件的構建過程和它的表示分離,使得同樣的構建過程可以建立不同的表示。

程式碼示例:

csharpCopy codepublic class Product
{
    public string PartA { get; set; }
    public string PartB { get; set; }
    public string PartC { get; set; }

    public override string ToString()
    {
        return $"{PartA}, {PartB}, {PartC}";
    }
}

public interface IBuilder
{
    void BuildPartA();
    void BuildPartB();
    void BuildPartC();
    Product GetResult();
}

public class ConcreteBuilder : IBuilder
{
    private Product product = new Product();

    public void BuildPartA()
    {
        product.PartA = "Part A";
    }

    public void BuildPartB()
    {
        product.PartB = "Part B";
    }

    public void BuildPartC()
    {
        product.PartC = "Part C";
    }

    public Product GetResult()
    {
        return product;
    }
}

public class Director
{
    private IBuilder builder;

    public Director(IBuilder builder)
    {
        this.builder = builder;
    }

    public void Construct()
    {
        builder.BuildPartA();
        builder.BuildPartB();
        builder.BuildPartC();
    }
}

原型模式(Prototype Pattern)

原型模式是一種建立型設計模式,它允許透過複製現有物件來建立新物件,而不是透過例項化的方式。

程式碼示例:

csharpCopy codepublic class Prototype : ICloneable
{
    public string Value { get; set; }

    public object Clone()
    {
        return MemberwiseClone();
    }
}

介面卡模式(Adapter Pattern)

介面卡模式是一種結構型設計模式,它可以將一種類的介面轉換成客戶端希望的另一種介面。介面卡模式允許介面不相容的類能夠合作。

程式碼示例:

csharpCopy codepublic interface ITarget
{
    void Request();
}

public class Adaptee
{
    public void SpecificRequest()
    {
        Console.WriteLine("Adaptee specific request");
    }
}

public class Adapter : ITarget
{
    private readonly Adaptee adaptee;

    public Adapter(Adaptee adaptee)
    {
        this.adaptee = adaptee;
    }

    public void Request()
    {
        adaptee.SpecificRequest();
    }
}

橋接模式(Bridge Pattern)

橋接模式是一種結構型設計模式,它可以將一個大類或一系列緊密相關的類拆分為抽象和實現兩個獨立的層次結構,從而能在開發時分別使用。

程式碼示例:

csharpCopy codepublic interface IImplementor
{
    void OperationImp();
}

public class ConcreteImplementorA : IImplementor
{
    public void OperationImp()
    {
        Console.WriteLine("ConcreteImplementorA OperationImp");
    }
}

public class ConcreteImplementorB : IImplementor
{
    public void OperationImp()
    {
        Console.WriteLine("ConcreteImplementorB OperationImp");
    }
}

public abstract class Abstraction
{
    protected IImplementor implementor;

    protected Abstraction(IImplementor implementor)
    {
        this.implementor = implementor;
    }

    public abstract void Operation();
}

public class RefinedAbstraction : Abstraction
{
    public RefinedAbstraction(IImplementor implementor) : base(implementor)
    {
    }

    public override void Operation()
    {
        implementor.OperationImp();
    }
}

組合模式(Composite Pattern)

組合模式是一種結構型設計模式,它允許將物件組合成樹形結構來表現整體-部分關係。組合能讓客戶端統一處理單個物件和物件組合。

程式碼示例:

csharpCopy codepublic abstract class Component
{
    protected readonly string name;

    public Component(string name)
    {
        this.name = name;
    }

    public abstract void Operation();
}

public class Leaf : Component
{
    public Leaf(string name) : base(name)
    {
    }

    public override void Operation()
    {
        Console.WriteLine($"Leaf {name} Operation");
    }
}

public class Composite : Component
{
    private readonly List<Component> children = new List<Component>();

    public Composite(string name) : base(name)
    {
    }

    public override void Operation()
    {
        Console.WriteLine($"Composite {name} Operation");

        foreach (var child in children)
        {
            child.Operation();
        }
    }

    public void Add(Component component)
    {
        children.Add(component);
    }

    public void Remove(Component component)
    {
        children.Remove(component);
    }
}

橋接模式(Bridge Pattern)

橋接模式是一種結構型設計模式,它將抽象與實現分離,以便它們可以獨立地進行變化。

程式碼示例:

csharpCopy codepublic interface IImplementor
{
    void OperationImp();
}

public class ConcreteImplementorA : IImplementor
{
    public void OperationImp()
    {
        Console.WriteLine("ConcreteImplementorA OperationImp");
    }
}

public class ConcreteImplementorB : IImplementor
{
    public void OperationImp()
    {
        Console.WriteLine("ConcreteImplementorB OperationImp");
    }
}

public abstract class Abstraction
{
    protected IImplementor implementor;

    public Abstraction(IImplementor implementor)
    {
        this.implementor = implementor;
    }

    public abstract void Operation();
}

public class RefinedAbstraction : Abstraction
{
    public RefinedAbstraction(IImplementor implementor) : base(implementor)
    {
    }

    public override void Operation()
    {
        implementor.OperationImp();
    }
}

外觀模式(Facade Pattern)

外觀模式是一種結構型設計模式,它為複雜的子系統提供簡單的介面,從而使子系統更易於使用。

程式碼示例:

csharpCopy codepublic class SubsystemA
{
    public void OperationA()
    {
        Console.WriteLine("SubsystemA OperationA");
    }
}

public class SubsystemB
{
    public void OperationB()
    {
        Console.WriteLine("SubsystemB OperationB");
    }
}

public class Facade
{
    private readonly SubsystemA subsystemA;
    private readonly SubsystemB subsystemB;

    public Facade(SubsystemA subsystemA, SubsystemB subsystemB)
    {
        this.subsystemA = subsystemA;
        this.subsystemB = subsystemB;
    }

    public void Operation()
    {
        subsystemA.OperationA();
        subsystemB.OperationB();
    }
}

享元模式(Flyweight Pattern)

享元模式是一種結構型設計模式,它透過共享盡可能多的資料來最小化記憶體使用和計算開銷。享元模式適用於需要大量物件的情況,同時又要求物件能夠輕量化。

程式碼示例:

csharpCopy codepublic class FlyweightFactory
{
    private readonly Dictionary<char, Flyweight> flyweights = new Dictionary<char, Flyweight>();

    public Flyweight GetFlyweight(char key)
    {
        if (!flyweights.TryGetValue(key, out var flyweight))
        {
            flyweight = new ConcreteFlyweight(key);
            flyweights[key] = flyweight;
        }

        return flyweight;
    }
}

public abstract class Flyweight
{
    public abstract void Operation();
}

public class ConcreteFlyweight : Flyweight
{
    private readonly char intrinsicState;

    public ConcreteFlyweight(char intrinsicState)
    {
        this.intrinsicState = intrinsicState;
    }

    public override void Operation()
    {
        Console.WriteLine($"ConcreteFlyweight {intrinsicState} Operation");
    }
}

public class UnsharedConcreteFlyweight : Flyweight
{
    private readonly string extrinsicState;

    public UnsharedConcreteFlyweight(string extrinsicState)
    {
        this.extrinsicState = extrinsicState;
    }

    public override void Operation()
    {
        Console.WriteLine($"UnsharedConcreteFlyweight {extrinsicState} Operation");
    }
}
``

組合模式(Composite Pattern)

組合模式是一種結構型設計模式,允許你將物件組合成樹狀結構,並且能像使用獨立物件一樣使用它們。

適用場景:

1.當你想表示物件的部分-整體層次結構時。

2.當你希望使用者可以忽略組合物件與單個物件的不同,統一地使用組合結構中的所有物件時。

組合模式中的關鍵類:

  1. Component(元件):是組合中的物件宣告介面,在適當情況下,實現所有類共有的介面預設行為。宣告一個介面用於訪問和管理 Component 子部件。
  2. Leaf(葉子):在組合中表示子節點物件,葉子節點沒有子節點。
  3. Composite(容器):定義有枝節點行為,用來儲存子部件,在 Component 介面中實現與子部件有關的操作,比如增加 Add 和刪除 Remove。

程式碼示例:

下面是一個組合模式的示例,我們以一個目錄結構為例來實現組合模式。目錄中可以包含檔案和資料夾,資料夾中又可以包含檔案和資料夾。

csharpCopy code// 抽象構件
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);
}

// 葉子節點
public class Leaf : Component
{
    public Leaf(string name) : base(name) { }

    public override void Add(Component c)
    {
        Console.WriteLine("不能向葉子節點新增節點");
    }

    public override void Remove(Component c)
    {
        Console.WriteLine("不能從葉子節點移除節點");
    }

    public override void Display(int depth)
    {
        Console.WriteLine(new string('-', depth) + name);
    }
}

// 容器節點
public class Composite : Component
{
    private List<Component> children = new List<Component>();

    public Composite(string name) : base(name) { }

    public override void Add(Component c)
    {
        children.Add(c);
    }

    public override void Remove(Component c)
    {
        children.Remove(c);
    }

    public override void Display(int depth)
    {
        Console.WriteLine(new string('-', depth) + name);

        foreach (Component component in children)
        {
            component.Display(depth + 2);
        }
    }
}

// 客戶端程式碼
class Client
{
    static void Main(string[] args)
    {
        Composite root = new Composite("C:");
        Composite windows = new Composite("Windows");
        Composite programFiles = new Composite("Program Files");
        Leaf file1 = new Leaf("a.txt");
        Leaf file2 = new Leaf("b.txt");
        Leaf file3 = new Leaf("c.txt");

        root.Add(windows);
        root.Add(programFiles);
        windows.Add(file1);
        windows.Add(file2);
        programFiles.Add(file3);

        root.Display(0);

        Console.ReadKey();
    }
}

Proxy(代理模式)

代理模式為其他物件提供一種代理以控制對這個物件的訪問。代理類與實際類具有相同的介面,這樣就可以使用代理來代替實際類,使得在不改變原始程式碼的情況下增加了一些額外的功能。常用的代理模式有遠端代理、虛擬代理、保護代理、快取代理等。

程式碼示例:

csharpCopy code// 實際類
public class RealSubject : ISubject
{
    public void Request()
    {
        Console.WriteLine("RealSubject: Handling Request.");
    }
}

// 代理類
public class Proxy : ISubject
{
    private readonly RealSubject _realSubject;

    public Proxy(RealSubject realSubject)
    {
        _realSubject = realSubject;
    }

    public void Request()
    {
        if (CheckAccess())
        {
            _realSubject.Request();

            LogAccess();
        }
    }

    private bool CheckAccess()
    {
        Console.WriteLine("Proxy: Checking access prior to firing a real request.");

        return true;
    }

    private void LogAccess()
    {
        Console.WriteLine("Proxy: Logging the time of request.");
    }
}

// 介面類
public interface ISubject
{
    void Request();
}

// 使用代理
static void Main(string[] args)
{
    var realSubject = new RealSubject();
    var proxy = new Proxy(realSubject);

    proxy.Request();
}

Command(命令模式)

命令模式是一種行為型模式,它透過將請求封裝為一個物件來實現請求的傳送者和接收者之間的解耦。命令物件包含了要執行的操作以及其相關的資料,可以把命令物件看成是一個操作的載體。常用的命令模式有簡單命令、複雜命令、佇列請求等。

程式碼示例:

csharpCopy code// 命令介面
public interface ICommand
{
    void Execute();
}

// 具體命令
public class ConcreteCommand : ICommand
{
    private readonly Receiver _receiver;

    public ConcreteCommand(Receiver receiver)
    {
        _receiver = receiver;
    }

    public void Execute()
    {
        _receiver.Action();
    }
}

// 接收者
public class Receiver
{
    public void Action()
    {
        Console.WriteLine("Receiver: Action.");
    }
}

// 傳送者
public class Invoker
{
    private ICommand _command;

    public void SetCommand(ICommand command)
    {
        _command = command;
    }

    public void ExecuteCommand()
    {
        _command.Execute();
    }
}

// 使用命令模式
static void Main(string[] args)
{
    var receiver = new Receiver();
    var command = new ConcreteCommand(receiver);
    var invoker = new Invoker();

    invoker.SetCommand(command);
    invoker.ExecuteCommand();
}

責任鏈模式(Chain of Responsibility Pattern)

責任鏈模式是一種行為型設計模式,它透過將請求的傳送者和接收者解耦,使多個物件都有機會處理這個請求。將這些物件連成一條鏈,並沿著這條鏈傳遞請求,直到有一個物件處理為止。

在責任鏈模式中,每個處理器都只關心它自己能夠處理的請求,並把它轉發給下一個處理器。這樣,請求者與處理器之間的耦合就被解除了,可以動態地改變請求的處理順序或者增加/刪除處理器。

程式碼示例:

下面是一個簡單的例子,用來演示使用責任鏈模式實現不同等級的員工申請加薪請求的處理:

csharpCopy codeabstract class Approver
{
    protected Approver successor;

    public void SetSuccessor(Approver successor)
    {
        this.successor = successor;
    }

    public abstract void ProcessRequest(Request request);
}

class Manager : Approver
{
    public override void ProcessRequest(Request request)
    {
        if (request.Type == RequestType.RaiseSalary && request.Amount <= 500)
        {
            Console.WriteLine($"Manager approved the request for raise of amount {request.Amount}");
        }
        else if (successor != null)
        {
            successor.ProcessRequest(request);
        }
    }
}

class DepartmentHead : Approver
{
    public override void ProcessRequest(Request request)
    {
        if (request.Type == RequestType.RaiseSalary && request.Amount <= 1000)
        {
            Console.WriteLine($"Department head approved the request for raise of amount {request.Amount}");
        }
        else if (successor != null)
        {
            successor.ProcessRequest(request);
        }
    }
}

class CEO : Approver
{
    public override void ProcessRequest(Request request)
    {
        if (request.Type == RequestType.RaiseSalary && request.Amount <= 5000)
        {
            Console.WriteLine($"CEO approved the request for raise of amount {request.Amount}");
        }
        else
        {
            Console.WriteLine($"The request for raise of amount {request.Amount} cannot be approved by anyone.");
        }
    }
}

class Request
{
    public RequestType Type { get; set; }
    public int Amount { get; set; }
}

enum RequestType
{
    RaiseSalary
}

static void Main(string[] args)
{
    Manager manager = new Manager();
    DepartmentHead departmentHead = new DepartmentHead();
    CEO ceo = new CEO();

    manager.SetSuccessor(departmentHead);
    departmentHead.SetSuccessor(ceo);

    Request request1 = new Request() { Type = RequestType.RaiseSalary, Amount = 400 };
    manager.ProcessRequest(request1);

    Request request2 = new Request() { Type = RequestType.RaiseSalary, Amount = 1500 };
    manager.ProcessRequest(request2);

    Request request3 = new Request() { Type = RequestType.RaiseSalary, Amount = 6000 };
    manager.ProcessRequest(request3);
}

輸出結果:

pythonCopy codeManager approved the request for raise of amount 400
Department head approved the request for raise of amount 1500
The request for raise of amount 6000 cannot be approved by anyone.

迭代器模式(Iterator Pattern)

描述:迭代器模式是一種行為型設計模式, 它可以在不暴露集合底層表現形式(列表、棧和樹等)的情況下遍歷集合中所有的元素。 示例:

csharpCopy codepublic class IteratorPatternExample
{
    static void Main(string[] args)
    {
        var collection = new ConcreteAggregate<string>();
        collection[0] = "One";
        collection[1] = "Two";
        collection[2] = "Three";
        collection[3] = "Four";

        var iterator = collection.CreateIterator();
        Console.WriteLine("Iterating over collection:");
        while (iterator.MoveNext())
        {
            var element = iterator.Current;
            Console.WriteLine(element);
        }
    }
}

public interface IIterator<T>
{
    bool MoveNext();
    T Current { get; }
    void Reset();
}

public interface IAggregate<T>
{
    IIterator<T> CreateIterator();
}

public class ConcreteAggregate<T> : IAggregate<T>
{
    private List<T> _items = new List<T>();
    public IIterator<T> CreateIterator()
    {
        return new ConcreteIterator<T>(this);
    }

    public int Count { get { return _items.Count; } }

    public T this[int index]
    {
        get { return _items[index]; }
        set { _items.Insert(index, value); }
    }
}

public class ConcreteIterator<T> : IIterator<T>
{
    private ConcreteAggregate<T> _aggregate;
    private int _currentIndex = 0;

    public ConcreteIterator(ConcreteAggregate<T> aggregate)
    {
        _aggregate = aggregate;
    }

    public T Current
    {
        get { return _aggregate[_currentIndex]; }
    }

    public bool MoveNext()
    {
        if (_currentIndex < _aggregate.Count)
        {
            _currentIndex++;
            return true;
        }
        return false;
    }

    public void Reset()
    {
        _currentIndex = 0;
    }
}

中介者模式(Mediator Pattern)

中介者模式用於降低多個物件之間的通訊複雜性。該模式定義一箇中介者物件,使得各個物件不需要顯式地相互引用,從而降低耦合度,同時可以獨立地改變物件之間的互動。

程式碼示例:

csharpCopy codepublic abstract class Mediator
{
    public abstract void Send(string message, Colleague colleague);
}

public class ConcreteMediator : Mediator
{
    private ConcreteColleague1 colleague1;
    private ConcreteColleague2 colleague2;

    public ConcreteColleague1 Colleague1
    {
        set { colleague1 = value; }
    }

    public ConcreteColleague2 Colleague2
    {
        set { colleague2 = value; }
    }

    public override void Send(string message, Colleague colleague)
    {
        if (colleague == colleague1)
        {
            colleague2.Notify(message);
        }
        else
        {
            colleague1.Notify(message);
        }
    }
}

public abstract class Colleague
{
    protected Mediator mediator;

    public Colleague(Mediator mediator)
    {
        this.mediator = mediator;
    }

    public abstract void Send(string message);
    public abstract void Notify(string message);
}

public class ConcreteColleague1 : Colleague
{
    public ConcreteColleague1(Mediator mediator) : base(mediator) { }

    public override void Send(string message)
    {
        mediator.Send(message, this);
    }

    public override void Notify(string message)
    {
        Console.WriteLine("Colleague1 gets message: " + message);
    }
}

public class ConcreteColleague2 : Colleague
{
    public ConcreteColleague2(Mediator mediator) : base(mediator) { }

    public override void Send(string message)
    {
        mediator.Send(message, this);
    }

    public override void Notify(string message)
    {
        Console.WriteLine("Colleague2 gets message: " + message);
    }
}

備忘錄模式(Memento Pattern)

備忘錄模式用於儲存一個物件的狀態,以便在以後可以恢復到該狀態。該模式有三個角色:備忘錄(Memento)負責儲存物件的狀態,原發器(Originator)負責建立備忘錄和恢復備忘錄,管理者(Caretaker)負責儲存和恢復備忘錄。

程式碼示例:

csharpCopy codepublic class Memento
{
    private string state;

    public Memento(string state)
    {
        this.state = state;
    }

    public string State
    {
        get { return state; }
    }
}

public class Originator
{
    private string state;

    public string State
    {
        get { return state; }
        set { state = value; }
    }

    public Memento CreateMemento()
    {
        return new Memento(state);
    }

    public void SetMemento(Memento memento)
    {
        state = memento.State;
    }
}

public class Caretaker
{
    private Memento memento;

    public Memento Memento
    {
        get { return memento; }
        set { memento = value; }
    }
}

觀察者模式(Observer Pattern)

  1. 觀察者模式(Observer Pattern):定義了一種一對多的依賴關係,讓多個觀察者物件同時監聽某一個主題物件,當主題物件發生變化時,所有依賴它的觀察者都會自動收到通知並進行更新。
csharpCopy codepublic interface IObserver
{
    void Update(ISubject subject);
}

public interface ISubject
{
    void Attach(IObserver observer);
    void Detach(IObserver observer);
    void Notify();
}

public class ConcreteSubject : ISubject
{
    private List<IObserver> observers = new List<IObserver>();
    private int state;

    public void Attach(IObserver observer)
    {
        observers.Add(observer);
    }

    public void Detach(IObserver observer)
    {
        observers.Remove(observer);
    }

    public void Notify()
    {
        foreach (var observer in observers)
        {
            observer.Update(this);
        }
    }

    public int GetState()
    {
        return state;
    }

    public void SetState(int state)
    {
        this.state = state;
        Notify();
    }
}

public class ConcreteObserver : IObserver
{
    private string name;

    public ConcreteObserver(string name)
    {
        this.name = name;
    }

    public void Update(ISubject subject)
    {
        Console.WriteLine($"{name} received the message from {subject.GetType().Name}, the new state is {((ConcreteSubject)subject).GetState()}");
    }
}

class Program
{
    static void Main(string[] args)
    {
        ISubject subject = new ConcreteSubject();
        IObserver observer1 = new ConcreteObserver("Observer 1");
        IObserver observer2 = new ConcreteObserver("Observer 2");

        subject.Attach(observer1);
        subject.Attach(observer2);

        ((ConcreteSubject)subject).SetState(1);

        subject.Detach(observer1);

        ((ConcreteSubject)subject).SetState(2);

        Console.ReadLine();
    }
}

狀態模式(State Pattern)

狀態模式(State Pattern)是一種行為型設計模式,它允許物件在內部狀態發生改變時改變它的行為。狀態模式透過將複雜的條件語句轉換為物件的形式,使得程式碼更加靈活、可維護和可擴充套件。

在狀態模式中,一個物件的行為取決於其內部狀態,物件會根據不同的狀態來執行不同的操作。這種模式是一種行為型模式。

在狀態模式中,主要有三種角色:上下文(Context)、抽象狀態(State)、具體狀態(ConcreteState)。其中,上下文是一個包含狀態的物件,抽象狀態是一個定義所有具體狀態的介面,具體狀態是實現狀態的具體類。

下面以電視遙控器為例,使用狀態模式進行設計。當電視遙控器處於不同狀態時,它會對按下的按鈕產生不同的響應,例如當電視遙控器處於開機狀態時,按下“換臺”按鈕會切換頻道;當電視遙控器處於關機狀態時,按下“換臺”按鈕則沒有任何響應。

首先,定義一個抽象狀態介面:

csharpCopy codepublic interface ITvState
{
    void TurnOn();
    void TurnOff();
    void NextChannel();
    void PrevChannel();
}

接下來,定義具體的狀態類,這裡定義了兩個具體狀態類,分別代表電視開機狀態和電視關機狀態:

csharpCopy codepublic class TvOnState : ITvState
{
    public void TurnOn()
    {
        Console.WriteLine("電視已經開機");
    }

    public void TurnOff()
    {
        Console.WriteLine("電視關機");
    }

    public void NextChannel()
    {
        Console.WriteLine("下一個頻道");
    }

    public void PrevChannel()
    {
        Console.WriteLine("上一個頻道");
    }
}

public class TvOffState : ITvState
{
    public void TurnOn()
    {
        Console.WriteLine("電視開機");
    }

    public void TurnOff()
    {
        Console.WriteLine("電視已經關機");
    }

    public void NextChannel()
    {
        Console.WriteLine("電視已經關機,無法切換頻道");
    }

    public void PrevChannel()
    {
        Console.WriteLine("電視已經關機,無法切換頻道");
    }
}

最後,定義上下文類,它包含了當前電視的狀態,並提供了一些介面供外界使用:

csharpCopy codepublic class TvContext
{
    private ITvState state;

    public TvContext()
    {
        state = new TvOffState();
    }

    public void SetState(ITvState state)
    {
        this.state = state;
    }

    public void TurnOn()
    {
        state.TurnOn();
        SetState(new TvOnState());
    }

    public void TurnOff()
    {
        state.TurnOff();
        SetState(new TvOffState());
    }

    public void NextChannel()
    {
        state.NextChannel();
    }

    public void PrevChannel()
    {
        state.PrevChannel();
    }
}

現在,我們就可以使用上下文類來操作電視遙控器了,例如:

csharpCopy codeTvContext context = new TvContext();

context.TurnOn();
context.NextChannel();
context.NextChannel();
context.PrevChannel();
context.TurnOff();

輸出結果為:

Copy code電視開機
下一個頻道
下一個頻道
上一個頻道
電視關機

策略模式(Strategy Pattern)

策略模式(Strategy Pattern)是一種行為設計模式,它允許在執行時選擇演算法的行為。該模式定義了一組演算法,將每個演算法封裝起來,並使它們之間可以相互替換。

下面是使用C#實現策略模式的示例程式碼:

csharpCopy code// 抽象策略
public interface IStrategy
{
    void Execute();
}

// 具體策略
public class ConcreteStrategyA : IStrategy
{
    public void Execute()
    {
        Console.WriteLine("執行策略A");
    }
}

// 具體策略
public class ConcreteStrategyB : IStrategy
{
    public void Execute()
    {
        Console.WriteLine("執行策略B");
    }
}

// 上下文
public class Context
{
    private IStrategy _strategy;

    public Context(IStrategy strategy)
    {
        _strategy = strategy;
    }

    public void SetStrategy(IStrategy strategy)
    {
        _strategy = strategy;
    }

    public void ExecuteStrategy()
    {
        _strategy.Execute();
    }
}

// 客戶端程式碼
public class Client
{
    public static void Main()
    {
        // 建立上下文並設定初始策略
        Context context = new Context(new ConcreteStrategyA());

        // 執行策略A
        context.ExecuteStrategy();

        // 切換策略
        context.SetStrategy(new ConcreteStrategyB());

        // 執行策略B
        context.ExecuteStrategy();
    }
}

在這個示例中,IStrategy是抽象策略,定義了策略的介面。ConcreteStrategyAConcreteStrategyB是具體策略,實現了策略介面。Context是上下文,維護了一個策略物件,並且提供了一些方法來使用該策略。Client是客戶端程式碼,使用上下文物件來執行策略。在客戶端程式碼中,我們首先建立了一個上下文物件並設定了一個初始策略。然後我們執行了策略A,接著我們切換了策略並執行了策略B。

模板方法模式(Template Method Pattern)

在模板方法模式中,有一個抽象類定義了一些抽象的方法和模板方法,模板方法是一個固定的演算法流程,而抽象的方法則需要子類去實現。模板方法模式的目的是讓子類可以不改變一個演算法的結構即可重定義該演算法的某些特定步驟。

下面是一個簡單的示例程式碼:

csharpCopy codeusing System;

abstract class AbstractClass
{
    public void TemplateMethod()
    {
        Operation1();
        Operation2();
    }

    public abstract void Operation1();
    public abstract void Operation2();
}

class ConcreteClassA : AbstractClass
{
    public override void Operation1()
    {
        Console.WriteLine("ConcreteClassA.Operation1");
    }

    public override void Operation2()
    {
        Console.WriteLine("ConcreteClassA.Operation2");
    }
}

class ConcreteClassB : AbstractClass
{
    public override void Operation1()
    {
        Console.WriteLine("ConcreteClassB.Operation1");
    }

    public override void Operation2()
    {
        Console.WriteLine("ConcreteClassB.Operation2");
    }
}

class Program
{
    static void Main(string[] args)
    {
        AbstractClass c1 = new ConcreteClassA();
        AbstractClass c2 = new ConcreteClassB();

        c1.TemplateMethod();
        c2.TemplateMethod();

        Console.ReadKey();
    }
}

在上面的程式碼中,AbstractClass 是一個抽象類,它有一個 TemplateMethod 方法,該方法呼叫了兩個抽象方法 Operation1Operation2。具體的子類 ConcreteClassAConcreteClassB 分別實現了這兩個抽象方法,並且可以在模板方法中按照特定的流程呼叫它們。

當我們執行這個程式時,輸出如下:

Copy codeConcreteClassA.Operation1
ConcreteClassA.Operation2
ConcreteClassB.Operation1
ConcreteClassB.Operation2

這表明模板方法模式確實在兩個具體的子類中分別執行了它們的 Operation1Operation2 方法,但是並沒有改變模板方法的演算法流程。

訪問者模式(Visitor Pattern)

訪問者模式(Visitor Pattern)是一種行為型設計模式,它允許你定義演算法(訪問者),並將其與一組物件分離。訪問者模式最常見的應用場景是在物件結構比較穩定的情況下,需要對物件結構中的物件進行各種不同的操作,且經常新增新的操作。

下面是一個使用訪問者模式的示例程式碼:

csharpCopy codeusing System;
using System.Collections.Generic;

// 訪問者介面
interface IVisitor
{
    void Visit(ConcreteElementA elementA);
    void Visit(ConcreteElementB elementB);
}

// 抽象元素類
abstract class Element
{
    public abstract void Accept(IVisitor visitor);
}

// 具體元素類 A
class ConcreteElementA : Element
{
    public override void Accept(IVisitor visitor)
    {
        visitor.Visit(this);
    }

    public void OperationA()
    {
        Console.WriteLine("ConcreteElementA.OperationA()");
    }
}

// 具體元素類 B
class ConcreteElementB : Element
{
    public override void Accept(IVisitor visitor)
    {
        visitor.Visit(this);
    }

    public void OperationB()
    {
        Console.WriteLine("ConcreteElementB.OperationB()");
    }
}

// 具體訪問者類
class ConcreteVisitor : IVisitor
{
    public void Visit(ConcreteElementA elementA)
    {
        elementA.OperationA();
    }

    public void Visit(ConcreteElementB elementB)
    {
        elementB.OperationB();
    }
}

// 物件結構類
class ObjectStructure
{
    private List<Element> elements = new List<Element>();

    public void Attach(Element element)
    {
        elements.Add(element);
    }

    public void Detach(Element element)
    {
        elements.Remove(element);
    }

    public void Accept(IVisitor visitor)
    {
        foreach (Element element in elements)
        {
            element.Accept(visitor);
        }
    }
}

// 客戶端程式碼
class Client
{
    static void Main()
    {
        ObjectStructure objectStructure = new ObjectStructure();
        objectStructure.Attach(new ConcreteElementA());
        objectStructure.Attach(new ConcreteElementB());

        ConcreteVisitor visitor = new ConcreteVisitor();
        objectStructure.Accept(visitor);

        Console.ReadKey();
    }
}

在上面的示例中,IVisitor 定義了訪問者的介面,包含了對每個具體元素類的訪問方法。Element 是抽象元素類,定義了 Accept 方法,接受訪問者的訪問。ConcreteElementAConcreteElementB 是具體元素類,實現了 Accept 方法,並且定義了各自的操作方法。ConcreteVisitor 是具體訪問者類,實現了 IVisitor 介面,實現了對每個具體元素的操作。ObjectStructure 是物件結構類,包含了元素物件集合,並提供了 Accept 方法,接受訪問者的訪問。客戶端程式碼透過建立 ObjectStructure 物件,向其中新增具體元素物件,並建立 ConcreteVisitor 物件進行訪問操作。

來著token的分享

技術交流群:737776595

相關文章