23种设计模式
1,Chain of Responsibility(职责链,对象模式)
创建型类模式将对象的部分创建工作延迟到子类,而创建型对象模式则将它延迟到另一个对象中
意图:提供一个接口以创建一系列相关或相互依赖的对象,而无需指向它们具体的类
使用场景:抽象工厂模式适用于需要创建一组相关或相互依赖的对象,并且这些对象的创建方式可能会发生变化的场景
结构:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _11_抽象工厂模式 { class Program { static void Main(string[] args) { AbstractFactory factory=new SQLServerFactory(); IProductA proA= factory.CreateProductA(); proA.GetProductA(); Console.ReadLine(); } } //抽象工厂:创建所有的产品接口 public abstract class AbstractFactory { public abstract IProductA CreateProductA(); public abstract IProductB CreateProductB(); } //具体工厂。Access数据库访问工厂 public class AccessFactory : AbstractFactory { public override IProductA CreateProductA() { return new Access_ProductA1(); } public override IProductB CreateProductB() { return new Access_ProductB1(); } } //具体工厂。SQLServer数据库访问工厂 public class SQLServerFactory : AbstractFactory { public override IProductA CreateProductA() { return new SQLServer_ProductA(); } public override IProductB CreateProductB() { return new SQLServer_ProductB(); } } //ProductA接口 public interface IProductA { void GetProductA(); } //具体ProductA public class Access_ProductA1 : IProductA { public void GetProductA() { Console.WriteLine("access数据库访问tProductA"); } } //具体ProductA public class SQLServer_ProductA : IProductA { public void GetProductA() { Console.WriteLine("SQLServer数据库访问tProductA"); } } //ProductB接口 public interface IProductB { void GetProductB(); } //具体ProductB public class Access_ProductB1 : IProductB { public void GetProductB() { Console.WriteLine("access数据库访问tProductB"); } } //具体ProductB public class SQLServer_ProductB : IProductB { public void GetProductB() { Console.WriteLine("SQLServer数据库访问tProductB"); } } } 抽象工厂模式代码
使用案例:跨平台开发:在跨平台开发中,需要根据不同的操作系统和硬件平台使用不同的API。使用抽象工厂模式,可以为每个平台创建一个工厂,这样可以轻松地编写跨平台的代码。
意图:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
使用场景:当需要创建复杂对象并且需要控制对象的构造过程时,使用 Builder 模式可以提供一种清晰、简洁的解决方案
结构:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _9_建造者模式 { class Program { static void Main(string[] args) { Builder bui = new ConcreteBuilder(); Director dir = new Director(); dir.Construct(bui); bui.GetResult().GetProduct(); Console.ReadLine(); } } //具体产品 public class Product { private List<string> strList = new List<string>(); public void Add(string p) { strList.Add(p); } public void GetProduct() { foreach (var list in strList) { Console.WriteLine(list); } } } //抽象建造者 public abstract class Builder { public abstract void BuilderPartA(); public abstract void BuilderPartB(); public abstract Product GetResult(); } //具体建造者 public class ConcreteBuilder : Builder { private Product pro = new Product(); public override void BuilderPartA() { pro.Add("部件1"); } public override void BuilderPartB() { pro.Add("部件2"); } public override Product GetResult() { return pro; } } //指挥者 public class Director { public void Construct(Builder bui) { bui.BuilderPartA(); bui.BuilderPartB(); } } }
使用案例:在asp.net core框架中的应用:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; public class Program { public static void Main(string[] args) { CreateWebHostBuilder(args).Build().Run(); } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>(); }
意图:定义一个用户创建对象的接口,让子类决定实例化那个类。Factory Method使一个类的实例化延迟到其子类
使用场景:将一个类的实例化延迟到其子类
结构:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public interface IProduct { } public class ConcreteProduce : IProduct { } public interface ICreator { IProduct FactoryMethod(); } public class ConcreteCreator : ICreator { public IProduct FactoryMethod() { return new ConcreteProduce(); } }
使用案例:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象
应用场景:利用原有对象进行拷贝来创建新的对象
结构:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _6_原型模式 { class Program { static void Main(string[] args) { Resume r = new Resume("Hunter"); r.SetPersonalInfo("男","22"); r.SetWorkExperience("2014-2015", "xx公司"); Resume r2 = (Resume)r.Clone(); r2.SetWorkExperience("2014-2016", "xx公司"); r.Display(); r2.Display(); Console.ReadLine(); } } public class Resume : ICloneable { private string name; private string sex; private string age; private string timeArea; public string company; public Resume(string name) { this.name = name; } //设置个人信息 public void SetPersonalInfo(string sex, string age) { this.sex = sex; this.age = age; } //设置工作经历 public void SetWorkExperience(string timeArea, string company) { this.timeArea = timeArea; this.company = company; } //显示 public void Display() { Console.WriteLine("{0} {1} {2}", name, sex, age); Console.WriteLine("工作经历:{0} {1}", timeArea, company); } //克隆 public object Clone() { //创建当前对象的浅表副本。方法是创建一个新对象, //然后将当前对象的非静态字段复制到该新对象。 //如果字段是值类型的,则对该字段执行逐位复制。 //如果字段是引用类型,则复制引用但不复制引用的对象, //因此,原始对象及其副本引用同一个对象 return (object) this.MemberwiseClone(); } } } 原型模式代码
使用案例:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// 定义原型接口 public interface ICloneable<T> { T Clone(); } // 实现原型类 public class Person : ICloneable<Person> { public string Name { get; set; } public int Age { get; set; } public Person Clone() { return new Person { Name = this.Name, Age = this.Age }; } } // 创建原型对象 var person1 = new Person { Name = "Alice", Age = 20 }; // 复制原型对象 var person2 = person1.Clone(); person2.Name = "Bob"; person2.Age = 25; Console.WriteLine($"Person 1: {person1.Name}, {person1.Age}"); Console.WriteLine($"Person 2: {person2.Name}, {person2.Age}");
意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点
应用场景:一个类仅有一个实例
结构:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _16_单例模式 { class Program { static void Main(string[] args) { Singleton s = Singleton.GetInstance(); Singleton s1 = Singleton.GetInstance(); Console.WriteLine(s==s1); Console.ReadLine(); } } //单例模式 public class Singleton { private static Singleton instance; private Singleton() { } public static Singleton GetInstance() { if (instance == null) { instance = new Singleton(); } return instance; } } //双重锁定 public class Singleton2 { public static Singleton2 instance; private readonly static object o=new object(); private Singleton2() { } public static Singleton2 GetInstance() { if (instance == null) { lock (o) { if (instance == null) { instance = new Singleton2(); } } } return instance; } } } 单例模式代码
使用案例:
单例模式相对于之前类级别锁的好处是,不用创建那么多 Logger 对象,一方面节省内存空间,另一方面节省系统文件句柄
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class Logger { private FileWriter writer; private static final Logger instance = new Logger(); private Logger() { File file = new File("/Users/wangzheng/log.txt"); writer = new FileWriter(file, true); //true表示追加写入 } public static Logger getInstance() { return instance; } public void log(String message) { writer.write(mesasge); } } // Logger类的应用示例: public class UserController { public void login(String username, String password) { // ...省略业务逻辑代码... Logger.getInstance().log(username + " logined!"); } } public class OrderController { public void create(OrderVo order) { // ...省略业务逻辑代码... Logger.getInstance().log("Created a order: " + order.toString()); } } 单例模式相对于之前类级别锁的好处是,不用创建那么多 Logger 对象,一方面节省内存空间,另一方面节省系统文件句柄
结构型模式涉及如何组装类和对象以获得更大的结构。
结构型类模式采用继承机制来组合接口实现;结构型对象模式不是对接口的实现进行组合,而是描述了如何对一些对象进行组合,从而实现新功能的一些方法
意图:将一个类的接口转换成客户希望的另一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的哪些类可以一起工作
应用场景:解决接口之前不匹配的问题
结构:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _13_适配器模式 { class Program { static void Main(string[] args) { Target t=new Adapter(); t.Request(); Console.ReadLine(); } } //客户所期待的接口 public class Target { public virtual void Request() { Console.WriteLine("普通请求"); } } //适配器 public class Adapter : Target { private Adaptee ada=new Adaptee() ; public override void Request() { ada.SpecificRequest(); } } //需要适配的对象 public class Adaptee { public void SpecificRequest() { Console.WriteLine("特殊请求"); } } } 适配器模式代码
使用案例:
意图:将抽象部分与它的实现部分分离,使得它们可以独立变化
应用场景:抽象与实现分离
结构:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
namespace ConsoleApp1 { public interface IMsgSender { void Send(string message); } /// <summary> /// 发送到手机 /// </summary> public class TelephoneMsgSender : IMsgSender { public void Send(string message) { Console.WriteLine(message); } } /// <summary> /// 发送到邮箱 /// </summary> public class EmailMsgSender: IMsgSender { public void Send(string message) { Console.WriteLine(message); } } /// <summary> /// 发送到微信 /// </summary> public class WechatMsgSender: IMsgSender { public void Send(string message) { Console.WriteLine(message); } } /// <summary> /// 通知 /// </summary> public abstract class Notification { protected IMsgSender _msgSender; public Notification(IMsgSender msgSender) { _msgSender = msgSender; } public abstract void notify(string message); } /// <summary> /// 严重通知 /// </summary> public class SevereNotification : Notification { public SevereNotification(IMsgSender msgSender) : base(msgSender) { } public override void notify(string message) { _msgSender.Send(message); } } /// <summary> /// 紧急情况通知 /// </summary> public class UrgencyNotification : Notification { public UrgencyNotification(IMsgSender msgSender) : base(msgSender) { } public override void notify(string message) { _msgSender.Send(message); } } /// <summary> /// 正常通知 /// </summary> public class NormalNotification : Notification { public NormalNotification(IMsgSender msgSender) : base(msgSender) { } public override void notify(string message) { _msgSender.Send(message); } } /// <summary> /// 不重要的通知 /// </summary> public class TrivialNotification : Notification { public TrivialNotification(IMsgSender msgSender) : base(msgSender) { } public override void notify(string message) { _msgSender.Send(message); } } } IMsgSender msgSender = new TelephoneMsgSender(); Notification notification = new SevereNotification(msgSender); notification.notify("通知"); Console.ReadLine();
意图:将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使得用户对单个对象和组合对象的使用具有一致性
应用场景:树形结构
结构:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _15_组合模式 { class Program { static void Main(string[] args) { Component com = new Composite("中国"); Component com1=new Composite("湖北"); Component com11 = new Leaf("荆门"); Component com12 = new Leaf("武汉"); com1.Add(com11); com1.Add(com12); com.Add(com1); com.Display(2); Console.ReadLine(); } } //组合中的对象声明接口 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 Composite : Component { public Composite(string name) : base(name) { } private List<Component> children = new List<Component>(); 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 (var component in children) { component.Display(depth + 2); } } } //叶节点 public class Leaf : Component { public Leaf(string name) : base(name) { } public override void Add(Component c) { throw new NotImplementedException(); } public override void Remove(Component c) { throw new NotImplementedException(); } public override void Display(int depth) { Console.WriteLine(new string('+', depth) + name); } } } 组合模式代码
意图:动态的给一个对象添加一些额外的职责。就添加功能来说,Decorator模式相比生成子类更为灵活
应用场景:给对象添加额外的职责
结构:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _3_装饰模式 { class Program { static void Main(string[] args) { ConcreteComponent con = new ConcreteComponent(); ConcreteDecoratorA conA = new ConcreteDecoratorA(); ConcreteDecoratorB conB = new ConcreteDecoratorB(); conA.SetComponent(con); conB.SetComponent(conA); conB.Operation(); Console.ReadLine(); } } //抽象对象类 public abstract class Component { public abstract void Operation(); } //具体对象类 public class ConcreteComponent : Component { public override void Operation() { Console.WriteLine("具体对象类"); } } //装饰类 public abstract class Decorator : Component { private Component component; public void SetComponent(Component component) { this.component = component; } public override void Operation() { if (component != null) component.Operation(); } } public class ConcreteDecoratorA : Decorator { public override void Operation() { base.Operation(); Console.WriteLine("具体的职责A"); } } public class ConcreteDecoratorB : Decorator { public override void Operation() { base.Operation(); Console.WriteLine("具体的职责B"); } } } 装饰模式代码
意图:为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用
应用场景:为多个子系统提供一个统一的接口,减少相互之间的依赖
结构:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _8_外观模式 { class Program { static void Main(string[] args) { Facade f = new Facade(); f.MethodA(); f.MethodB(); Console.ReadLine(); } } //外观类 public class Facade { private SubSystemOne one; private SubSystemTwo two; private SubSystemThree three; private SubSystemFour four; public Facade() { one = new SubSystemOne(); two = new SubSystemTwo(); three = new SubSystemThree(); four = new SubSystemFour(); } public void MethodA() { Console.WriteLine("方法组一"); one.MethodOne(); two.MethodTwo(); } public void MethodB() { Console.WriteLine("方法组二"); three.MethodThree(); four.MethodFour(); } } //子系统类 public class SubSystemOne { public void MethodOne() { Console.WriteLine("子系统方法1"); } } public class SubSystemTwo { public void MethodTwo() { Console.WriteLine("子系统方法2"); } } public class SubSystemThree { public void MethodThree() { Console.WriteLine("子系统方法3"); } } public class SubSystemFour { public void MethodFour() { Console.WriteLine("子系统方法4"); } } } 外观模式代码
意图:运用共享技术有效地支持大量细粒度的对象
应用场景:当一个系统中存在大量重复对象的时候,我们就可以利用享元模式
结构:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; // 定义享元接口 interface IShape { void Draw(int x, int y); } // 实现享元类 class Circle : IShape { private string color; public Circle(string color) { this.color = color; } public void Draw(int x, int y) { Console.WriteLine($"在坐标 ({x}, {y}) 画了一个 {color} 的圆形"); } } // 实现享元工厂类 class ShapeFactory { private Dictionary<string, IShape> shapes = new Dictionary<string, IShape>(); public IShape GetCircle(string color) { if (shapes.TryGetValue(color, out IShape shape)) { Console.WriteLine($"使用已存在的 {color} 圆形"); return shape; } else { IShape newShape = new Circle(color); shapes[color] = newShape; Console.WriteLine($"创建新的 {color} 圆形"); return newShape; } } } // 客户端代码 class Program { static void Main(string[] args) { ShapeFactory factory = new ShapeFactory(); IShape redCircle = factory.GetCircle("红色"); redCircle.Draw(1, 2); IShape blueCircle = factory.GetCircle("蓝色"); blueCircle.Draw(3, 4); IShape greenCircle = factory.GetCircle("绿色"); greenCircle.Draw(5, 6); IShape redCircle2 = factory.GetCircle("红色"); redCircle2.Draw(7, 8); } } 创建新的 红色 圆形 在坐标 (1, 2) 画了一个 红色 的圆形 创建新的 蓝色 圆形 在坐标 (3, 4) 画了一个 蓝色 的圆形 创建新的 绿色 圆形 在坐标 (5, 6) 画了一个 绿色 的圆形 使用已存在的 红色 圆形 在坐标 (7, 8) 画了一个 红色 的圆形
意图:为其他对象提供一种代理以控制对这个对象的访问
应用场景:代理对象访问
结构:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _4_代理模式 { class Program { static void Main(string[] args) { Proxy pro = new Proxy(); pro.Request(); Console.ReadLine(); } } //接口 public interface Subject { void Request(); } //真实对象 public class RealSubject : Subject { public void Request() { Console.WriteLine("请求访问"); } } //代理 public class Proxy : Subject { private RealSubject realSubject; public void Request() { if (realSubject == null) realSubject = new RealSubject(); //额外职责 Console.WriteLine("额外职责"); realSubject.Request(); } } } 代理模式代码
1,Chain of Responsibility(职责链,对象模式)
意图:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止
应用场景:处理管道
结构:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _19_职责链模式 { class Program { static void Main(string[] args) { Handle h1 = new ConcreteHandleA(); Handle h2 = new ConcreteHandleB(); h1.SetSuccessor(h2); h1.HandleRequest(11); Console.ReadLine(); } } //定义处理请求的接口 public abstract class Handle { protected Handle handle; public void SetSuccessor(Handle successor) { handle = successor; } public abstract void HandleRequest(int request); } //具体处理者 public class ConcreteHandleA : Handle { public override void HandleRequest(int request) { if (request < 10) { Console.WriteLine("ConcreteHandleA处理"); } else { //后继者处理 handle.HandleRequest(request); } } } //具体处理者 public class ConcreteHandleB : Handle { public override void HandleRequest(int request) { if (request > 10) { Console.WriteLine("ConcreteHandleB处理"); } else { throw new Exception("异常"); } } } } 职责链模式代码
意图:将一个请求封装为一个对象,从而使你可用不同的请求对象对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作
应用场景:将请求封装为对象
结构:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _18_命令模式 { class Program { static void Main(string[] args) { Reciver r = new Reciver(); Invoker inv = new Invoker(); Commend comA = new ConcreteCommendA(r); Commend comB = new ConcreteCommendB(r); inv.SetCommend(comA); inv.SetCommend(comB); inv.Notify(); Console.ReadLine(); } } //接受者(厨师) public class Reciver { public void ActionA() { Console.WriteLine("做鱼香肉丝"); } public void ActionB() { Console.WriteLine("做番茄操蛋"); } } //抽象命令 public abstract class Commend { protected Reciver reciver; public Commend(Reciver reciver) { this.reciver = reciver; } public abstract void Execute(); } //具体的命令(做鱼香肉丝) public class ConcreteCommendA : Commend { public ConcreteCommendA(Reciver reciver) : base(reciver) { } public override void Execute() { reciver.ActionA(); } } //具体的命令(做番茄操蛋) public class ConcreteCommendB : Commend { public ConcreteCommendB(Reciver reciver) : base(reciver) { } public override void Execute() { reciver.ActionB(); } } //调用者(服务员) public class Invoker { private List<Commend> commends = new List<Commend>(); public void SetCommend(Commend c) { Console.WriteLine(string.Format("下单时间{0}",DateTime.Now)); commends.Add(c); } public void RemoveCommend(Commend c) { Console.WriteLine(string.Format("取消时间{0}", DateTime.Now)); commends.Remove(c); } public void Notify() { foreach (var commend in commends) { commend.Execute(); } } } } 命令模式代码
意图:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子
应用场景:解释对象
结构:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _22_解释器模式 { class Program { static void Main(string[] args) { Context con = new Context(); con.Message = "Hunter"; AbstractExpression abe1=new InExpression(); abe1.Interperter(con); Console.WriteLine(con.Message); AbstractExpression abe2 = new DeExpression(); abe2.Interperter(con); Console.WriteLine(con.Message); Console.ReadLine(); } } //需要解释的类 public class Context { public string Message { get; set; } } //抽象解释器 public abstract class AbstractExpression { public abstract void Interperter(Context con); } //加密 public class InExpression : AbstractExpression { public override void Interperter(Context con) { con.Message = "加密之后的字符"; } } //解密 public class DeExpression : AbstractExpression { public override void Interperter(Context con) { con.Message = "解密之后的字符"; } } } 解释器模式代码
意图:提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示
应用场景:顺序访问集合的各个元素
结构:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections; public class MyCollection : IEnumerable { private int[] items; public MyCollection(int[] items) { this.items = items; } public IEnumerator GetEnumerator() { for (int i = 0; i < items.Length; i++) { yield return items[i]; } } } public class Program { public static void Main() { MyCollection collection = new MyCollection(new int[] { 1, 2, 3, 4, 5 }); foreach (int item in collection) { Console.WriteLine(item); } } }
意图:提用一个中介对象来封装一系列的对象交互。中介者是各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变他们之间的交互
应用场景:中介对象来封装一系列的对象交互
结构:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using Microsoft.AspNetCore.Mvc; namespace ConsoleApp1 { public interface IMediator { void RegisterComponent(IComponent component); void Notify(string message, IComponent sender); } public class ConcreteMediator : IMediator { private readonly List<IComponent> _components = new List<IComponent>(); public void RegisterComponent(IComponent component) { _components.Add(component); } public void Notify(string message, IComponent sender) { foreach (var component in _components) { if (component != sender) { component.Receive(message); } } } } public interface IComponent { void Send(string message); void Receive(string message); } public class ConcreteComponentA : IComponent { private readonly IMediator _mediator; public ConcreteComponentA(IMediator mediator) { _mediator = mediator; } public void Send(string message) { _mediator.Notify(message, this); } public void Receive(string message) { Console.WriteLine($"Component A received message: {message}"); } } public class ConcreteComponentB : IComponent { private readonly IMediator _mediator; public ConcreteComponentB(IMediator mediator) { _mediator = mediator; } public void Send(string message) { _mediator.Notify(message, this); } public void Receive(string message) { Console.WriteLine($"Component B received message: {message}"); } } public class HomeController : Controller { private readonly IMediator _mediator; public HomeController(IMediator mediator) { _mediator = mediator; } public IActionResult Index() { var componentA = new ConcreteComponentA(_mediator); var componentB = new ConcreteComponentB(_mediator); _mediator.RegisterComponent(componentA); _mediator.RegisterComponent(componentB); componentA.Send("Hello from component A"); componentB.Send("Hello from component B"); return View(); } } }
意图:在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
应用场景:这可以用于实现“撤销”和“重做”等功能,或者在发生意外情况时还原对象状态
结构:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//备忘录类 public class Memento { public string State { get; } public Memento(string state) { State = state; } } //原始对象类 public class Originator { private string _state; public string State { get => _state; set { Console.WriteLine($"Setting state to {value}"); _state = value; } } public Memento SaveState() { Console.WriteLine("Saving state..."); return new Memento(_state); } public void RestoreState(Memento memento) { Console.WriteLine("Restoring state..."); _state = memento.State; } } //备忘录管理类 public class Caretaker { public Memento Memento { get; set; } } //使用备忘录模式 var originator = new Originator(); var caretaker = new Caretaker(); originator.State = "State 1"; caretaker.Memento = originator.SaveState(); originator.State = "State 2"; //还原状态 originator.RestoreState(caretaker.Memento);
意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新
应用场景:发布通知
结构:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _10_观察者模式 { class Program { static void Main(string[] args) { ConcreteSubject conS = new ConcreteSubject(); ConcreteObserver conO = new ConcreteObserver("具体观察者",conS); conS.Attach(conO); conS.State = "主题状态变化了"; conS.Notify(); Console.ReadLine(); } } //抽象观察者 public abstract class Observer { public abstract void Update(); } //具体观察者 public class ConcreteObserver:Observer { private Subject subject; private string name; public ConcreteObserver(string name, Subject subject) { this.name = name; this.subject = subject; } public override void Update() { Console.WriteLine("{0}。{1}通知到了", subject.State,name); } } //抽象主题 public abstract class Subject { private List<Observer> observerList = new List<Observer>(); public void Attach(Observer ob) { observerList.Add(ob); } public void Detach(Observer ob) { observerList.Remove(ob); } public void Notify() { foreach (var observer in observerList) { observer.Update(); } } public abstract string State { get; set; } } //具体主题 public class ConcreteSubject : Subject { private string _state; public override string State { get { return _state; } set { _state = value; } } } } 观察者模式代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; namespace ObserverPattern { public class MyObservable : IObservable<string> { private List<IObserver<string>> observers; public MyObservable() { observers = new List<IObserver<string>>(); } public IDisposable Subscribe(IObserver<string> observer) { if (!observers.Contains(observer)) { observers.Add(observer); } return new Unsubscriber(observers, observer); } private class Unsubscriber : IDisposable { private List<IObserver<string>> _observers; private IObserver<string> _observer; public Unsubscriber(List<IObserver<string>> observers, IObserver<string> observer) { _observers = observers; _observer = observer; } public void Dispose() { if (_observer != null && _observers.Contains(_observer)) { _observers.Remove(_observer); } } } public void NotifyObservers(string message) { foreach (var observer in observers) { observer.OnNext(message); } } } public class MyObserver : IObserver<string> { private IDisposable unsubscriber; public virtual void Subscribe(IObservable<string> provider) { unsubscriber = provider.Subscribe(this); } public virtual void Unsubscribe() { unsubscriber.Dispose(); } public virtual void OnCompleted() { Console.WriteLine("Observer completed"); } public virtual void OnError(Exception e) { Console.WriteLine("Observer error: {0}", e.Message); } public virtual void OnNext(string value) { Console.WriteLine("Observer got value: {0}", value); } } class Program { static void Main(string[] args) { MyObservable observable = new MyObservable(); MyObserver observer1 = new MyObserver(); MyObserver observer2 = new MyObserver(); observer1.Subscribe(observable); observer2.Subscribe(observable); observable.NotifyObservers("Hello World!"); observer1.Unsubscribe(); observable.NotifyObservers("Goodbye World!"); Console.ReadKey(); } } }
意图:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类
应用场景:发布通知
结构:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// 定义状态接口 public interface IOrderState { void Process(Order order); } // 实现具体状态类 public class NewOrderState : IOrderState { public void Process(Order order) { // 处理新订单 order.State = new ProcessingOrderState(); } } public class ProcessingOrderState : IOrderState { public void Process(Order order) { // 处理正在处理的订单 order.State = new CompletedOrderState(); } } public class CompletedOrderState : IOrderState { public void Process(Order order) { // 处理已完成的订单 } } // 将状态机封装到订单中 public class Order { public IOrderState State { get; set; } public Order() { State = new NewOrderState(); } public void ProcessOrder() { State.Process(this); } } // 在程序中使用状态模式 public class Program { static void Main(string[] args) { var order = new Order(); order.ProcessOrder(); // 处理新订单 order.ProcessOrder(); // 处理正在处理的订单 order.ProcessOrder(); // 处理已完成的订单 } }
意图:定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
应用场景:封装算法
结构:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class PaymentProcessor { private readonly IPaymentStrategy _paymentStrategy; public PaymentProcessor(IPaymentStrategy paymentStrategy) { _paymentStrategy = paymentStrategy; } public void ProcessPayment(double amount) { _paymentStrategy.ProcessPayment(amount); } } public interface IPaymentStrategy { void ProcessPayment(double amount); } public class CreditCardPaymentStrategy : IPaymentStrategy { private readonly string _cardNumber; private readonly string _expiryDate; private readonly string _cvv; public CreditCardPaymentStrategy(string cardNumber, string expiryDate, string cvv) { _cardNumber = cardNumber; _expiryDate = expiryDate; _cvv = cvv; } public void ProcessPayment(double amount) { Console.WriteLine($"Processing credit card payment of {amount} with card number {_cardNumber}..."); // 与处理信用卡付款的实际逻辑 } } public class PayPalPaymentStrategy : IPaymentStrategy { private readonly string _emailAddress; private readonly string _password; public PayPalPaymentStrategy(string emailAddress, string password) { _emailAddress = emailAddress; _password = password; } public void ProcessPayment(double amount) { Console.WriteLine($"Processing PayPal payment of {amount} with email address {_emailAddress}..."); // 与处理PayPal付款的实际逻辑 } } var creditCardPayment = new CreditCardPaymentStrategy("1234567890123456", "10/23", "123"); var paymentProcessor = new PaymentProcessor(creditCardPayment); paymentProcessor.ProcessPayment(100.00); var payPalPayment = new PayPalPaymentStrategy("johndoe@example.com", "p@ssword"); paymentProcessor = new PaymentProcessor(payPalPayment); paymentProcessor.ProcessPayment(50.00);
意图:定义一个操作骨架,而将一些步骤延迟到子类中。TemplateMethod使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
应用场景:定义一个操作骨架
结构:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 模板方法模式 { class Program { static void Main(string[] args) { AbstractClass ab=new ConcreteClassA(); ab.TemplateMethod(); Console.ReadLine(); } } //模板类 public abstract class AbstractClass { public abstract void PrimitiveOperation1(); public abstract void PrimitiveOperation2(); public void TemplateMethod() { PrimitiveOperation1(); PrimitiveOperation2(); Console.WriteLine("模板"); } } //具体类A public class ConcreteClassA : AbstractClass { public override void PrimitiveOperation1() { Console.WriteLine("具体类A-PrimitiveOperation1"); } public override void PrimitiveOperation2() { Console.WriteLine("具体类A-PrimitiveOperation2"); } } //具体类B public class ConcreteClassB : AbstractClass { public override void PrimitiveOperation1() { Console.WriteLine("具体类B-PrimitiveOperation1"); } public override void PrimitiveOperation2() { Console.WriteLine("具体类B-PrimitiveOperation2"); } } } 模板方法模式代码
意图:表示一个作用于某对象结构中的各个元素操作。它使得你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
应用场景:你可以定义一个访问者接口,用于在不同的控制器上执行操作,然后在应用程序中的不同地方使用该接口来执行特定操作
结构:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// 定义访问者接口 public interface IVisitor { void Visit(ControllerA controller); void Visit(ControllerB controller); } // 定义被访问元素(控制器) public abstract class BaseController { public abstract void Accept(IVisitor visitor); } public class ControllerA : BaseController { public override void Accept(IVisitor visitor) { visitor.Visit(this); } } public class ControllerB : BaseController { public override void Accept(IVisitor visitor) { visitor.Visit(this); } } // 实现访问者接口 public class Visitor : IVisitor { public void Visit(ControllerA controller) { // 执行 ControllerA 特定操作 } public void Visit(ControllerB controller) { // 执行 ControllerB 特定操作 } } // 使用访问者模式 var controllerA = new ControllerA(); var controllerB = new ControllerB(); var visitor = new Visitor(); controllerA.Accept(visitor); controllerB.Accept(visitor);