《大话设计模式》学习小结
UML类图
依赖关系:动物新陈代谢依赖氧气、水 组合关系:翅膀是鸟必不可少的一部分 聚合关系:大雁是雁群的组成,但是大雁可以单独存在 实现接口:大雁的飞是接口飞翔的具体实现 继续关系:鸟继承动物 关联关系:企鹅和气候有关 |
《大话设计模式》
一. 简单工厂模式
工厂模式:需要谁,实例化谁
Operation oper = OperationFactory.createOperate(“+”); oper.NumberA = 1; oper.NumberB = 2; auto result = oper.GetResult(); |
二.策略模式
策略模式:一系列公共算法,策略用来封装变化
class CashContext { CashSuper cs = nullptr;
public CashContext(string type) { switch (type) //可以用函数map映射代替switch { case “算法1”: cs = new CashNormal(); break; } }
public double GetResult(double money) { return cs.acceptCash(money); } }
客户端: CashContext csuper = new CashContext(“选择的算法”) auto result = csuper.GetResult(); |
三. 装饰模式
装饰模式:一层一层装饰,每层加上特有的东西,然后调用基层。
abstract class Component { public abstract void Operation(); } class ConcreteComponent : Component { public override void Operation() { “具体对象的操作”; } }
abstract class Decorator:Component { protected Component component;
public void Set(Component component) { this.component = component; } public override void Operation() { if (component != null) { component.Operation(); } } }
class ConcreteDecoratorA:Decorator { private string addedState; public override void Operation() { base.Operation(); addedState = “New”; } }
客户端代码: { ConcreteComponent c = new ConcreteComponent(); ConcreteDecoratorA d1 = new ConcreteDecoratorA(); ConcreteDecoratorB d2 = new ConcreteDecoratorB(); d1.Set(c); d2.Set(d1); d2.Operation(); }
|
四.代理模式
代理模式:为其他对象提供一种代理以控制对这个对象的访问
class Proxy : Subject { RealSubject realSubject; public override void Request() { if (realRequest == null) { realSubject = new RealSubject(); } realSubject.Request(); } } |
五.工厂方法模式
工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。
客户端 IFactory operFactory = new AddFactory(); Operation oper = operFactory.CreateOperation(); oper.NumberA = 1; oper.NumberB = 2; auto result = oper.GetResult(); |
六.原型模式
原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
七. 模板方法模式
模板模式:定义一个操作中的算法骨架,而将一些步骤延迟到子类中
abstract class AbstractClass { public abstract void PrimitiveOperation1(); public abstract void PrimitiveOperation2();
public void TemplateMethod() { PrimitiveOperation1(); PrimitiveOperation2(); } }
客户端: { AbstractClass c; c = new ConcreteClassA(); c.TemplateMethod() } |
八、外观模式
外观模式:为子系统中的接口提供一个一致的界面,此模式定义了一个高层接口,使子系统易用。
九、建造者模式
建造者模式:将一个复杂对象的构建和它的表示分离,使得同样的构建过程可以创建不同的表示。
客户端: { Director director = new Director(); Builder b1 = new ConcreteBuilder1();
director.Construct(b1); Product p1 = b1.GetResult(); p1.show(); } |
十、观察者模式(pub/sub)
观察者模式(发布-订阅模式):定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状体发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
客户端: { ConcreteSubject s = new ConcreteSubject(); s.Attach (new ConcreteObserver(s, “X”)) s.Attach (new ConcreteObserver(s, “Y”)) s.SubjectState = “Go” s.Notify(); } |
委托事件(EventHandler):如果具体的观察者的处理函数不是同名,可以用委托事件技术解决。委托可以看作是对函数的抽象。
十一、抽象工厂模式
抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
更上一层楼:用反射+抽象工厂。
反射,理解为:在命名有规则的情况下,利用表达式替换的办法解决代码中switch分支。
十二、状态模式
状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中。
关键在一个状态的处理后设置状态的迁移。
十三、适配器模式
适配器模式:将一个类的接口转换成客户希望的另外一个接口。使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
客户端: { Target target = new Adapter(); target.Request(); } |
Tips:好的设计 > 重构 > 适配
十四、备忘录模式
备忘录模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
客户端: { Originator o = new Originator(); o.State = “on” Caretaker c = new Caretaker(); c.Memento = o.CreateMemento(); o.SetMemento(c.Memento); } |
十五、组合模式
组合模式:将对象组合成树形结构以表示部分-整体的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。
客户端: { Composite root = new Composite(“root”) root.Add(new Leaf()) root.Add(new Leaf())
Composite comp = new Composite(“Composite X”) comp.Add(new Leaf()) comp.Add(new Leaf())
root.Add(comp) } |
十六、迭代器模式
迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象内部的表示。
十七、单例模式(GetInstance)
单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
十八、桥接模式
桥接模式:将抽象部分和它的实现部分分离,使它们都可以独立地变化。
{ Abstraction ab = new RefinedAbstraction(); // 变化 ab.SetImplementor(new ConcreteImplementorA()); //变化 ab.Operation(); //统一 } |
十九、命令模式
命令模式:将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。
二十、职责链模式
职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和连接者之间的耦合关系。将对象连成一条链,并沿着链传递请求,直到有一个对象处理它为止。
二十一、中介者模式
中介者模式:用一个对象来封装一系列的对象交互。
二十二、享元模式
享元模式:运用共享技术有效地支持大量细粒度的对象。
享元模式可以避免大量非常相似类的开销。
二十三、解释器模式
解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来揭示语言中的句子。
二十四、访问者模式
访问者模式:表示一个作用于某对象结构中的各元素的操作。它使得可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
运用场景:比较稳定的数据结构,易于变化的算法。
二十五、 面向对象设计5原则(SOLID)
单一职责原则:就一个类而言,应该仅有一个引起它变化的原因。
开放-封闭原则:是说软件实体,应该可以扩展,但是不可修改。
里氏替代原则:子类型必须能够替换掉它们的父类型。
接口隔离原则:类不应该被迫依赖他们不使用的方法,一个接口应该拥有尽可能少的行为。
依赖倒转原则:高层模块不应该依赖低层模块。两个都应该依赖抽象。抽象不应该依赖细节。细节应该依赖抽象。