C# 23种设计模式详解与示例
C# 23种设计模式详解与示例
- 一、创建型模式(5种)
- 1. 单例模式 (Singleton)
- 2. 工厂方法模式 (Factory Method)
- 3. 抽象工厂模式 (Abstract Factory)
- 4. 建造者模式 (Builder)
- 5. 原型模式 (Prototype)
- 二、结构型模式(7种)
- 6. 适配器模式 (Adapter)
- 7. 桥接模式 (Bridge)
- 8. 组合模式 (Composite)
- 9. 装饰器模式 (Decorator)
- 10. 外观模式 (Facade)
- 11. 享元模式 (Flyweight)
- 12. 代理模式 (Proxy)
- 三、行为型模式(11种)
- 13. 责任链模式 (Chain of Responsibility)
- 14. 命令模式 (Command)
- 15. 解释器模式 (Interpreter)
- 16. 迭代器模式 (Iterator)
- 17. 中介者模式 (Mediator)
- 18. 备忘录模式 (Memento)
- 19. 观察者模式 (Observer)
- 20. 状态模式 (State)
- 21. 策略模式 (Strategy)
- 22. 模板方法模式 (Template Method)
- 23. 访问者模式 (Visitor)
- 总结
设计模式是软件设计中常见问题的典型解决方案,它们是可以重复使用的设计模板。GoF(Gang of Four)提出的23种设计模式分为三大类:创建型、结构型和行为型。下面我将详细解释每种模式,并提供C#示例。
一、创建型模式(5种)
1. 单例模式 (Singleton)
目的:确保一个类只有一个实例,并提供全局访问点。
public sealed class Singleton
{private static Singleton _instance;private static readonly object _lock = new object();private Singleton() { }public static Singleton GetInstance(){if (_instance == null){lock (_lock){if (_instance == null){_instance = new Singleton();}}}return _instance;}
}// 使用
var instance1 = Singleton.GetInstance();
var instance2 = Singleton.GetInstance();
Console.WriteLine(instance1 == instance2); // 输出 True
2. 工厂方法模式 (Factory Method)
目的:定义一个创建对象的接口,但让子类决定实例化哪个类。
public interface IProduct
{string Operation();
}public class ConcreteProductA : IProduct
{public string Operation() => "Result of ConcreteProductA";
}public abstract class Creator
{public abstract IProduct FactoryMethod();public string SomeOperation(){var product = FactoryMethod();return $"Creator: {product.Operation()}";}
}public class ConcreteCreatorA : Creator
{public override IProduct FactoryMethod() => new ConcreteProductA();
}// 使用
Creator creator = new ConcreteCreatorA();
Console.WriteLine(creator.SomeOperation());
3. 抽象工厂模式 (Abstract Factory)
目的:提供一个接口,用于创建相关或依赖对象的家族,而不需要指定具体类。
public interface IAbstractFactory
{IProductA CreateProductA();IProductB CreateProductB();
}public interface IProductA { string UsefulFunctionA(); }
public interface IProductB { string UsefulFunctionB(); }public class ConcreteFactory1 : IAbstractFactory
{public IProductA CreateProductA() => new ConcreteProductA1();public IProductB CreateProductB() => new ConcreteProductB1();
}// 使用
IAbstractFactory factory = new ConcreteFactory1();
var productA = factory.CreateProductA();
var productB = factory.CreateProductB();
Console.WriteLine(productA.UsefulFunctionA());
Console.WriteLine(productB.UsefulFunctionB());
4. 建造者模式 (Builder)
目的:将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。
public class Product
{public List<string> Parts { get; } = new List<string>();public void Add(string part) => Parts.Add(part);public string ListParts() => $"Parts: {string.Join(", ", Parts)}";
}public interface IBuilder
{void BuildPartA();void BuildPartB();Product GetProduct();
}public class ConcreteBuilder : IBuilder
{private Product _product = new Product();public void BuildPartA() => _product.Add("PartA");public void BuildPartB() => _product.Add("PartB");public Product GetProduct(){var result = _product;_product = new Product(); // 重置return result;}
}// 使用
var builder = new ConcreteBuilder();
builder.BuildPartA();
builder.BuildPartB();
var product = builder.GetProduct();
Console.WriteLine(product.ListParts());
5. 原型模式 (Prototype)
目的:通过复制现有对象来创建新对象,而不是新建。
public abstract class Prototype
{public int Id { get; }protected Prototype(int id) => Id = id;public abstract Prototype Clone();
}public class ConcretePrototype1 : Prototype
{public ConcretePrototype1(int id) : base(id) { }public override Prototype Clone() => new ConcretePrototype1(Id);
}// 使用
var original = new ConcretePrototype1(1);
var clone = original.Clone();
Console.WriteLine($"Original ID: {original.Id}, Clone ID: {clone.Id}");
二、结构型模式(7种)
6. 适配器模式 (Adapter)
目的:将一个类的接口转换成客户希望的另一个接口。
public interface ITarget
{string GetRequest();
}public class Adaptee
{public string GetSpecificRequest() => "Specific request";
}public class Adapter : ITarget
{private readonly Adaptee _adaptee;public Adapter(Adaptee adaptee) => _adaptee = adaptee;public string GetRequest() => $"This is '{_adaptee.GetSpecificRequest()}'";
}// 使用
Adaptee adaptee = new Adaptee();
ITarget target = new Adapter(adaptee);
Console.WriteLine(target.GetRequest());
7. 桥接模式 (Bridge)
目的:将抽象部分与其实现部分分离,使它们都可以独立变化。
public interface IImplementation
{string OperationImplementation();
}public class ConcreteImplementationA : IImplementation
{public string OperationImplementation() => "ConcreteImplementationA";
}public abstract class Abstraction
{protected IImplementation _implementation;protected Abstraction(IImplementation implementation) => _implementation = implementation;public abstract string Operation();
}public class ExtendedAbstraction : Abstraction
{public ExtendedAbstraction(IImplementation implementation) : base(implementation) { }public override string Operation() => $"Extended: {_implementation.OperationImplementation()}";
}// 使用
IImplementation implementation = new ConcreteImplementationA();
Abstraction abstraction = new ExtendedAbstraction(implementation);
Console.WriteLine(abstraction.Operation());
8. 组合模式 (Composite)
目的:将对象组合成树形结构以表示"部分-整体"的层次结构。
public abstract class Component
{public abstract string Operation();public virtual void Add(Component component) => throw new NotImplementedException();public virtual void Remove(Component component) => throw new NotImplementedException();public virtual bool IsComposite() => true;
}public class Leaf : Component
{public override string Operation() => "Leaf";public override bool IsComposite() => false;
}public class Composite : Component
{protected List<Component> _children = new List<Component>();public override void Add(Component component) => _children.Add(component);public override void Remove(Component component) => _children.Remove(component);public override string Operation(){var results = new List<string>();foreach (var child in _children)results.Add(child.Operation());return $"Branch({string.Join("+", results)})";}
}// 使用
var leaf1 = new Leaf();
var leaf2 = new Leaf();
var composite = new Composite();
composite.Add(leaf1);
composite.Add(leaf2);
Console.WriteLine(composite.Operation());
9. 装饰器模式 (Decorator)
目的:动态地给一个对象添加一些额外的职责。
public abstract class Component
{public abstract string Operation();
}public class ConcreteComponent : Component
{public override string Operation() => "ConcreteComponent";
}public abstract class Decorator : Component
{protected Component _component;public Decorator(Component component) => _component = component;public override string Operation() => _component.Operation();
}public class ConcreteDecoratorA : Decorator
{public ConcreteDecoratorA(Component component) : base(component) { }public override string Operation() => $"ConcreteDecoratorA({base.Operation()})";
}// 使用
Component component = new ConcreteComponent();
Component decorated = new ConcreteDecoratorA(component);
Console.WriteLine(decorated.Operation());
10. 外观模式 (Facade)
目的:为子系统中的一组接口提供一个一致的界面。
public class Subsystem1
{public string Operation1() => "Subsystem1: Ready!";public string OperationN() => "Subsystem1: Go!";
}public class Subsystem2
{public string Operation1() => "Subsystem2: Get ready!";public string OperationZ() => "Subsystem2: Fire!";
}public class Facade
{private Subsystem1 _subsystem1;private Subsystem2 _subsystem2;public Facade(Subsystem1 s1, Subsystem2 s2){_subsystem1 = s1;_subsystem2 = s2;}public string Operation(){var result = new List<string>();result.Add(_subsystem1.Operation1());result.Add(_subsystem2.Operation1());result.Add(_subsystem1.OperationN());result.Add(_subsystem2.OperationZ());return string.Join("\n", result);}
}// 使用
var subsystem1 = new Subsystem1();
var subsystem2 = new Subsystem2();
var facade = new Facade(subsystem1, subsystem2);
Console.WriteLine(facade.Operation());
11. 享元模式 (Flyweight)
目的:运用共享技术有效地支持大量细粒度的对象。
public class Flyweight
{private string _sharedState;public Flyweight(string sharedState) => _sharedState = sharedState;public void Operation(string uniqueState) => Console.WriteLine($"Shared: {_sharedState}, Unique: {uniqueState}");
}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];}
}// 使用
var factory = new FlyweightFactory();
var flyweight1 = factory.GetFlyweight("shared1");
flyweight1.Operation("unique1");
var flyweight2 = factory.GetFlyweight("shared1");
flyweight2.Operation("unique2");
12. 代理模式 (Proxy)
目的:为其他对象提供一种代理以控制对这个对象的访问。
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 void Request(){if (_realSubject == null)_realSubject = new RealSubject();_realSubject.Request();}
}// 使用
ISubject subject = new Proxy();
subject.Request();
三、行为型模式(11种)
13. 责任链模式 (Chain of Responsibility)
目的:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。
public interface IHandler
{IHandler SetNext(IHandler handler);object Handle(object request);
}public abstract class AbstractHandler : IHandler
{private IHandler _nextHandler;public IHandler SetNext(IHandler handler){_nextHandler = handler;return handler;}public virtual object Handle(object request){return _nextHandler?.Handle(request);}
}public class MonkeyHandler : AbstractHandler
{public override object Handle(object request){if ((request as string) == "Banana")return $"Monkey: I'll eat the {request}.";return base.Handle(request);}
}// 使用
var monkey = new MonkeyHandler();
var squirrel = new SquirrelHandler();
monkey.SetNext(squirrel);
Console.WriteLine(monkey.Handle("Banana"));
14. 命令模式 (Command)
目的:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化。
public interface ICommand
{void Execute();
}public class SimpleCommand : ICommand
{private string _payload;public SimpleCommand(string payload) => _payload = payload;public void Execute() => Console.WriteLine($"SimpleCommand: {_payload}");
}public class Invoker
{private ICommand _onStart;private ICommand _onFinish;public void SetOnStart(ICommand command) => _onStart = command;public void SetOnFinish(ICommand command) => _onFinish = command;public void DoSomethingImportant(){_onStart?.Execute();_onFinish?.Execute();}
}// 使用
var invoker = new Invoker();
invoker.SetOnStart(new SimpleCommand("Say Hi!"));
invoker.DoSomethingImportant();
15. 解释器模式 (Interpreter)
目的:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
public interface IExpression
{bool Interpret(string context);
}public class TerminalExpression : IExpression
{private string _data;public TerminalExpression(string data) => _data = data;public bool Interpret(string context) => context.Contains(_data);
}public class OrExpression : IExpression
{private IExpression _expr1;private IExpression _expr2;public OrExpression(IExpression expr1, IExpression expr2){_expr1 = expr1;_expr2 = expr2;}public bool Interpret(string context) => _expr1.Interpret(context) || _expr2.Interpret(context);
}// 使用
IExpression expr1 = new TerminalExpression("John");
IExpression expr2 = new TerminalExpression("Married");
IExpression orExpr = new OrExpression(expr1, expr2);
Console.WriteLine(orExpr.Interpret("John is here")); // true
16. 迭代器模式 (Iterator)
目的:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。
public interface IIterator
{bool HasNext();object Next();
}public interface IAggregate
{IIterator CreateIterator();
}public class ConcreteAggregate : IAggregate
{private List<object> _items = new List<object>();public IIterator CreateIterator() => new ConcreteIterator(this);public int Count => _items.Count;public object this[int index]{get => _items[index];set => _items.Insert(index, value);}
}public class ConcreteIterator : IIterator
{private ConcreteAggregate _aggregate;private int _current = 0;public ConcreteIterator(ConcreteAggregate aggregate) => _aggregate = aggregate;public bool HasNext() => _current < _aggregate.Count;public object Next() => _aggregate[_current++];
}// 使用
var aggregate = new ConcreteAggregate();
aggregate[0] = "Item A";
aggregate[1] = "Item B";
var iterator = aggregate.CreateIterator();
while (iterator.HasNext())Console.WriteLine(iterator.Next());
17. 中介者模式 (Mediator)
目的:用一个中介对象来封装一系列的对象交互。
public interface IMediator
{void Notify(object sender, string ev);
}public class ConcreteMediator : IMediator
{public Component1 Component1 { get; set; }public Component2 Component2 { get; set; }public void Notify(object sender, string ev){if (ev == "A"){Console.WriteLine("Mediator reacts on A and triggers:");Component2.DoC();}else if (ev == "D"){Console.WriteLine("Mediator reacts on D and triggers:");Component1.DoB();}}
}public class BaseComponent
{protected IMediator _mediator;public BaseComponent(IMediator mediator = null) => _mediator = mediator;public void SetMediator(IMediator mediator) => _mediator = mediator;
}public class Component1 : BaseComponent
{public void DoA(){Console.WriteLine("Component 1 does A.");_mediator.Notify(this, "A");}public void DoB(){Console.WriteLine("Component 1 does B.");_mediator.Notify(this, "B");}
}// 使用
var mediator = new ConcreteMediator();
var c1 = new Component1(mediator);
var c2 = new Component2(mediator);
mediator.Component1 = c1;
mediator.Component2 = c2;
c1.DoA();
18. 备忘录模式 (Memento)
目的:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
public class Memento
{private string _state;public Memento(string state) => _state = state;public string GetState() => _state;
}public class Originator
{private string _state;public void SetState(string state){Console.WriteLine($"Setting state to {state}");_state = state;}public Memento Save() => new Memento(_state);public void Restore(Memento memento){_state = memento.GetState();Console.WriteLine($"State restored to: {_state}");}
}public class Caretaker
{private List<Memento> _mementos = new List<Memento>();private Originator _originator;public Caretaker(Originator originator) => _originator = originator;public void Backup() => _mementos.Add(_originator.Save());public void Undo(){if (_mementos.Count == 0) return;var memento = _mementos.Last();_mementos.Remove(memento);_originator.Restore(memento);}
}// 使用
var originator = new Originator();
var caretaker = new Caretaker(originator);
originator.SetState("State #1");
caretaker.Backup();
originator.SetState("State #2");
caretaker.Undo();
19. 观察者模式 (Observer)
目的:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
public interface IObserver
{void Update(ISubject subject);
}public interface ISubject
{void Attach(IObserver observer);void Detach(IObserver observer);void Notify();
}public class Subject : ISubject
{public int State { get; set; }private List<IObserver> _observers = new List<IObserver>();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 void SomeBusinessLogic(){State = new Random().Next(0, 10);Notify();}
}public class ConcreteObserver : IObserver
{public void Update(ISubject subject){if ((subject as Subject).State < 3)Console.WriteLine("ConcreteObserver: Reacted to the event.");}
}// 使用
var subject = new Subject();
var observer = new ConcreteObserver();
subject.Attach(observer);
subject.SomeBusinessLogic();
20. 状态模式 (State)
目的:允许一个对象在其内部状态改变时改变它的行为。
public class Context
{private State _state;public Context(State state) => TransitionTo(state);public void TransitionTo(State state){Console.WriteLine($"Context: Transition to {state.GetType().Name}");_state = state;_state.SetContext(this);}public void Request1() => _state.Handle1();public void Request2() => _state.Handle2();
}public abstract class State
{protected Context _context;public void SetContext(Context context) => _context = context;public abstract void Handle1();public abstract void Handle2();
}public class ConcreteStateA : State
{public override void Handle1(){Console.WriteLine("ConcreteStateA handles request1.");Console.WriteLine("ConcreteStateA wants to change the state of the context.");_context.TransitionTo(new ConcreteStateB());}public override void Handle2() => Console.WriteLine("ConcreteStateA handles request2.");
}// 使用
var context = new Context(new ConcreteStateA());
context.Request1();
context.Request2();
21. 策略模式 (Strategy)
目的:定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。
public interface IStrategy
{object DoAlgorithm(object data);
}public class ConcreteStrategyA : IStrategy
{public object DoAlgorithm(object data){var list = data as List<string>;list.Sort();return list;}
}public class Context
{private IStrategy _strategy;public Context(IStrategy strategy) => _strategy = strategy;public void SetStrategy(IStrategy strategy) => _strategy = strategy;public void DoSomeBusinessLogic(){var result = _strategy.DoAlgorithm(new List<string> { "a", "b", "c" });Console.WriteLine(string.Join(",", result));}
}// 使用
var context = new Context(new ConcreteStrategyA());
context.DoSomeBusinessLogic();
context.SetStrategy(new ConcreteStrategyB());
context.DoSomeBusinessLogic();
22. 模板方法模式 (Template Method)
目的:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。
public abstract class AbstractClass
{public void TemplateMethod(){this.BaseOperation1();this.RequiredOperations1();this.BaseOperation2();this.Hook1();}protected void BaseOperation1() => Console.WriteLine("AbstractClass says: I am doing the bulk of the work");protected void BaseOperation2() => Console.WriteLine("AbstractClass says: But I let subclasses override some operations");protected abstract void RequiredOperations1();protected virtual void Hook1() { }
}public class ConcreteClass1 : AbstractClass
{protected override void RequiredOperations1() => Console.WriteLine("ConcreteClass1 says: Implemented Operation1");
}// 使用
AbstractClass abstractClass = new ConcreteClass1();
abstractClass.TemplateMethod();
23. 访问者模式 (Visitor)
目的:表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
public interface IComponent
{void Accept(IVisitor visitor);
}public class ConcreteComponentA : IComponent
{public void Accept(IVisitor visitor) => visitor.VisitConcreteComponentA(this);public string ExclusiveMethodOfConcreteComponentA() => "A";
}public interface IVisitor
{void VisitConcreteComponentA(ConcreteComponentA element);void VisitConcreteComponentB(ConcreteComponentB element);
}public class ConcreteVisitor1 : IVisitor
{public void VisitConcreteComponentA(ConcreteComponentA element){Console.WriteLine($"{element.ExclusiveMethodOfConcreteComponentA()} + ConcreteVisitor1");}public void VisitConcreteComponentB(ConcreteComponentB element){Console.WriteLine($"{element.SpecialMethodOfConcreteComponentB()} + ConcreteVisitor1");}
}// 使用
var components = new List<IComponent>
{new ConcreteComponentA(),new ConcreteComponentB()
};var visitor1 = new ConcreteVisitor1();
foreach (var component in components)component.Accept(visitor1);
总结
这23种设计模式为解决特定问题提供了经过验证的解决方案。在实际开发中,应根据具体场景选择合适的设计模式,而不是为了使用模式而使用模式。设计模式的目标是提高代码的可维护性、可扩展性和可重用性。