Fork me on GitHub

设计模式一(Design Patterns)

设计模式是编程历史上经过人们反复验证、使用而总结出来的一套编程模板,能够帮助我们写出低偶、高效、安全、高扩展的代码。
设计模式有很多种,而且还因不同的编程语言而异,但是常用的设计模式有23种,主要分为以下三类:

设计模式的分类

创建型模式

我们知道创建对象(一切皆对象)时需要消耗很多的系统资源,在莫名其妙的地方创建莫名其妙的对象,会让你的系统、应用莫名
其妙,说人话就是在不合适宜的时间或地方,创建对象或频繁的创建对象都会让你的应用消耗太多的资源,从而影响性能和稳定性
所以人们在软件工程生产过程中就总结出来了一套专门解决对象创建的设计模式。
简单工厂模式(Simple Factory);
工厂方法模式(Factory Method);
抽象工厂(abstract Factory);
创建者模式(builder);
原型模式(Prototype);
单例模式(Singleton);

结构型模式

当对象创建的问题被我们解决了之后,我们将面临如何组织这些对象,由于单纯的继承关系等已经无法满足复杂和多样的对象,我
们需要结构化统一的去组织我们的对象,结构型模式就是为了解决这些问题的。
外观模式(Facade);
适配器模式(Adapter);
代理模式(Proxy);
装饰模式(Decorator);
桥模式(Bridge);
组合模式(Composite);
享元模式(Flyweight);

行为模式

创建和组织问题都解决了,接下来就是行为问题了,如何让对象间能够高效的协作,行为模式能够很好的解决这些问题。
模板方法模式(Template Mothod);
状态模式(State);
策略模式(Strategy);
职责链模式(Chain of Responsibility);
命令模式(Command);
访问模式(Visitor);
调停者模式(Mediator);
备忘录模式(Memento);
迭代器模式(Iterator);
解释器模式(Interpreter);

以上除了简单工厂模式外就是GOF总结的常用的23种设计模式,下一篇将分类介绍这些设计模式。

设计模式的原则

开闭原则(Open Close Principle)

开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。

里氏代换原则(Liskov Substitution Principle)

里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。—— From Baidu 百科

依赖倒转原则(Dependence Inversion Principle)

面向过程开发开发时,上层依赖与下层,当下层发现大的变化时上层也需要随之而变化,大大降低了模块的复用性;而面向抽象开发时,程序实现细节依赖与抽象,当抽象不发生变化而实现细节发生变化时,客户程序不需要变化,大大降低了客户程序与实现细节的低偶合。这种原则的宗旨就是:高层次模块不应该依赖与低层次模块,而都应该依赖与抽象;抽象不应该依赖与具体实现,具体实现应该依赖与抽象。

接口隔离原则(Interface Segregation Principle)

这个原则的意思是:使用多个隔离的接口,比使用单个接口要好,一个类对另一个类的依赖性应是建立在最小的接口上的,不应该将不同的角色都放进同一个接口中,这是对接口的污染。不强迫客户依赖于它们不用的方法,如果强迫依赖这些不用的方法,那就会面临客户程序需要随这些方法的改变所带来的改变。

迪米特法则(最少知道原则)(Demeter Principle)

为什么叫最少知道原则,就是说:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。如果两个类不必彼此直接通信,那么这两个类不应该直接相互作用,如果其中一个类需要调用另一个类的方法,可以通过第三者转发这个调用,这就是所谓的只与直接朋友通信,而什么是直接朋友,每个对象都会与其他对象有耦合关系,只要两个对象之间有耦合关系,我们就说这两个对象之间是朋友关系。耦合的方式很多,依赖、关联、组合、聚合等。其中,我们称出现成员变量、方法参数、方法返回值中的类为直接的朋友,而出现在局部变量中的类则不是直接的朋友。也就是说,陌生的类最好不要作为局部变量的形式出现在类的内部。

合成复用原则(Composite Reuse Principle)

原则是尽量使用合成/聚合的方式,而不是使用继承。这里我们需要理解清楚什么时候使用继承,什么时候使用继承和聚合呢,“IS-A”代表一个类是另外一个类的一种时使用继承关系,“has-a”代表一个类是另外一个类的一种角色,而不是另外一个类的特殊种类时使用聚合。
例如:如果我们把“人”当成一个类,然后把“雇员”,“经理”,“学生”当成是“人”的子类。错误在于把“角色”的等级结构和“人”的等级结构混淆了。“经理”,”雇员”,“学生”是一个人的角色,一个人可以同时拥有上述角色。如果按继承来设计,那么如果一个人是雇员,就不可能是经理,也不可能是学生,显然不合。正确的设计是有个抽象类“角色”,“人”可以拥有多个“角色”(聚合),“雇员”,“经理”,“学生”是“角色”的子类。