设计模式小结

首先是面向对象的几个原则:

1.开闭原则OCP(对扩展开放,对修改关闭)

2.里氏代换原则LSP(子类重写方法访问权限不能小于父类) 

ps:关于重写(override)和重载(overload)
重载是在同一个类中定义几种方法名相同,参数类型和个数不同的方法
重写是指子类继承父类时重写父类方法,方法名,参数类型和个数都必须相同,
jdk1.5之后,允许返回值不同,但返回值类型必须是父类该方法返回值的子类,(例如,父类返回object,子类返回string)
View Code

3.依赖倒置原则DIP(高层次的模块不应该依赖于低层次的模块,它们都应该依赖于抽象。抽象不应该依赖于具体,具体应该依赖于抽象)

简单来说就是低层模块的改变不应该影响到高层模块,两者应相对独立,这样代码复用性才高,多用一个抽象层接口实现两个模块的独立
View Code

4.接口隔离原则ISP(建立单一接口,不要建立庞大臃肿的接口,尽量细化接口,接口中的方法尽量少。也就是说,我们要为各个类建立专用的接口,而不要试图去建立一个很庞大的接口供所有依赖它的类去调用) 

  采用接口隔离原则对接口进行约束时,要注意以下几点:
1.接口尽量小,但是要有限度。对接口进行细化可以提高程序设计灵活性是不争的事实,但是如果过小,则会造成接口数量过多,使设计复杂化。所以一定要适度。
2.为依赖接口的类定制服务,只暴露给调用的类它需要的方法,它不需要的方法则隐藏起来。只有专注地为一个模块提供定制服务,才能建立最小的依赖关系。
3.提高内聚,减少对外交互。使接口用最少的方法去完成最多的事情。
View Code

5.合成/聚合复用原则CARP(组合/聚合和继承是实现复用的两个基本途径。合成复用原则是指尽量使用合成/聚合,而不是使用继承。)

聚合表示整体与部分的关系,表示“含有”,整体由部分组合而成,部分可以脱离整体作为一个独立的个体存在。
组合则是一种更强的聚合,部分组成整体,而且不可分割,部分不能脱离整体而单独存在。
在合成关系中,部分和整体的生命周期一样,组合的新的对象完全支配其组成部分,包括他们的创建和销毁。一个合成关系中成分对象是不能与另外一个合成关系共享。

组合/聚合和继承是实现复用的两个基本途径。合成复用原则是指尽量使用合成/聚合,而不是使用继承。

       只有当以下的条件全部被满足时,才应当使用继承关系。

         1. 子类是超类的一个特殊种类,而不是超类的一个角色,也就是区分“Has-A”和“Is-A”.只有“Is-A”关系才符合继承关系,“Has-A”关系应当使用聚合来描述。

         2 .永远不会出现需要将子类换成另外一个类的子类的情况。如果不能肯定将来是否会变成另外一个子类的话,就不要使用继承。

         3 .子类具有扩展超类的责任,而不是具有置换掉或注销掉超类的责任。如果一个子类需要大量的置换掉超类的行为,那么这个类就不应该是这个超类的子类。
View Code

6.最小知识原则(迪米特法则)PLK(一个对象应当对其他对象有尽可能少的了解,不和陌生人说话)

优先考虑将一个类设置成不变类;尽量降低一个类的访问权限;尽量降低成员的访问权限。
View Code

设计模式就是实现了这些原则,从而达到了代码复用和可维护性的目的


设计模式共23种,分3种类型:

创建型:单例模式,工厂模式,抽象工厂模式,原型模式,建造者模式

结构型:适配器模式,桥接模式,装饰模式,组合模式,外观模式,享元模式,代理模式

行为型:模板方法模式,命令模式,迭代器模式,观察者模式,中介者模式,备忘录模式,解释器模式,状态模式,策略模式,职责链模式,访问者模式


详细介绍:(具体举例参考这位大神:http://www.cnblogs.com/shaosks/archive/2012/03/01/2375570.html)

1.策略模式

定义:策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以互相替换。策略模式让算法独立于使用它的客户而独立变化。

应用场景:

1. 多个类只区别在表现行为不同,可以用Strategy模式,在运行时动态选择具体要执行的行为。

2.需要在不同情况下使用不同的策略,或者策略还可能在未来使用其它方式实现。

3.对客户隐藏具体策略(算法)的实现细节,彼此完全独立。

优点:

1.  提供了一种替代继承的方法,而且既保持了继承的优点(代码重用),还比继承更灵活,因为算法是独立的,可以灵活扩展。

2.  避免程序中使用多重条件转移语句,使系统更灵活,并易于扩展。

3.  遵守大部分GRASP原则和常用设计原则,高内聚,低耦合。

缺点:

1.因为每个具体策略类都会产生一个新类,所以会增加系统需要维护的类的数量。
View Code

2.观察者模式

定义:观察者模式定义了对象间一对多依赖关系,使得当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新

应用场景:
对一个对象状态的更新,需要其他对象同步更新,而且其他对象的数量动态可以变化。
对象仅需要将自己的更新通知给其他对象,而不需要知道其他对象的细节。

优点:(subject和obserer是例子中的2个接口)
Subject 和obserer之间是松耦合的,分别可以各自独立改变。
Subject在发送广播通知的时候,无须指定具体的Observer,Observer可以自己决定是否需要订阅Subject的通知。
遵守大部分GRASP原则和常用设计原则,高内聚,低耦合。

缺点:
如果一个Subject被大量的Observer订阅的话,在广播通知的时候可能会有效率问题。
View Code

3.迭代器模式

就是提供一种访问集合对象的方法,而又无需暴露该对象的内部细节
View Code

4.适配器模式

类适配方式中,是通过类的继承来实现的,同时也具有接口的所有行为,这些就违背了面向对象设计原则中的类的单一职责原则,而对象适配器则是通过对象组合的方式来实现的,则符合面向对象的精神,所以推荐用对象适配的模式。

实现要点:

Adapter模式主要应用于“希望复用一些现存的类,但是接口又与复用环境要求不一致的情况”,在代码复用,类库迁移等方面非常有用。
Adapter模式有对象适配器和类适配器两种形式的实现结构,但是类适配器采用“多继承”的实现方式,带来了不良的高耦合,而对象适配器采用“对象组合”的方式,更符合松耦合。
Adapter模式本身要求我们尽可能的使用“面向接口编程”风格,这样才能在后期很方便的适配。
View Code

5.单例模式

要点:
1.一个类只能有一个实例
2.它只能自行创建这个实例
3.它必须自行向系统提供这个实例

实现要点:
1.单例模式是限制而不是改进类的创建。
2.单例模式一般不要支持Icloneable接口,因为这可能导致多个对象实例,与单例模式的初衷违背。
3.单例模式一般不要支持序列化,这也可能导致多个对象实例。
4.单例模式只考虑了对象创建的管理,没有考虑到销毁的管理,就支持垃圾回收的平台和对象的开销来讲,我们一般没必要对其销毁进行特殊的管理。
5.理解和扩展单例模式的核心是“如果控制用户使用new对一个类的构造器的任意调用”

应用场景:
1.每台计算机可以有若个干打印机,但只能有一个Printer Spooler,避免两个打印机作业同时输出到打印机。
2.PC机中可能有几个串口,但只能有一个Com1口的实例。
3.系统中只能有一个窗口管理器
4..NET Remoting中服务器激活对象中Singleton对象,确保所有客户程序的请求只有一个实例来处理。
 
优点:
实例控制:Singleton会阻止其他对象实例化其自己的Singleton对象的副本,从而确保所有对象都访问唯一实例。
灵活性:因为类控制了实例化过程,所以类可以更加灵活修改实例化过程。

缺点:
对象生存期:Singleton不能够解决删除单个对象的问题。在提供内存管理的语言中(例如基于.NET Framework的语言),只有Singleton类能够导致实例被取消分配,因为它包含对该实例的私有引用。在某些语言中(例如C++),其他类可以删除。但这样会导致Singleton类中出现悬浮引用。
View Code

 未完待续...

原文地址:https://www.cnblogs.com/li-mei/p/5817736.html