面向对象设计模式是"好的面向对象设计",所谓“好的面向对象设计”是那些可以满足“应对变化,提高复用”的设计。
Gof
软件经常要面对变化
敏捷软件开发
使用 设计模式的目的是为了减少 需求变化带来的影响 (少写代码)
三大设计原则
1)针对接口编程,而不是针对实现编程
- 客户(调用程序的程序、客户程序)无需知道所使用对象的特定类型,只需要知道对象拥有客户所期望的接口。
2)优先使用对象组合,而不是类继承
- 类继承通常为了“白箱复用”,对象组合通常为了“黑箱复用”。继承在某种程序上破坏了封装性,子类父类耦合度高;而对象组合则只要求被组合的对象具有良好定义的接口,耦合度低。
3)封装变化点
- 使用封装来创建对象之间的分界层,让设计者可以在分界层的一侧进行修改,而不会对另一侧产生不良的影响,从而实现层次间的松耦合。
4) 使用重构得到模式
- 设计模式的应用不宜先入为主,一上来就使用设计模式是对设计模式的最大误用。没有一步到位的设计模式。敏捷软件开发初中提倡的“Refactoring to Patterns”是目前普遍公众的最好的使用设计模式的方法。
单例模式
在软件系统中,经常有这样一些特殊的类,必须保证它们在系统中只存在一个实例,才能确保它们的逻辑正确性、以及良好的效率。
如何绕过常规的构造器,提供一种机制来保证一个类只有一个实例?
这应该是类设计者的责任,而不是使用者(调用者)的责任。
public class Singleton { private static Singleton instance; private Singleton(){}; public static Singleton Instance { get
{ if(instance==null) { instance = new Singleton(); } return instance; } } }
Singleton模式中的实例构造器可以设置为protected以允许子类派生。
Singleton模式一般不要支持ICloneable接口,因为这可能会导致多个对象实例,与Singleton模式的初衷违背。
Singleton模式一般不要支持序列化,因为这也有可能导致多个对象实例,同样与Singleton模式的初衷违背。
Singleton模式只考虑到了对象创建的管理,没有考虑对象销毁的管理。就支持垃圾回收的平台和对象的开销来说,我们一般没有必要对其销毁进行特殊的管理。
不能应对多线程环境:在多线程环境下,使用Singleton模式仍然有可能得到Singleton类的多个实例对象。
Abstract Factory 抽象工厂(创建型模式)
面向接口编程 ——依赖接口,而非实现
变化点
在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作;同时,由于需求的变化,往往存在更多系列对象的创建工作。
如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“多系列具体对象创建工作”的紧耦合?
提供一个接口,让该接口负责创建一系列“相关或者相互依赖的对象”,无需指定它们具体的类。
发布-订阅模型(观察者模式)
定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。
示例: 账户取钱后,发送通知。发送手机短信、邮件、发送通知等。
接口 是面向 对象的核心思想
使用面向对象的抽象,Observer模式使得我们可以独立地改变目标与观察者,从而使二者之间的依赖关系达到松耦合。
目标发送通知时,无需指定观察者,通知会自动传播。