使用模式最好的方式是:“把模式装进脑子里,然后在你的设计和已有的应用中,寻找何处可以使用它们。”以往是代码复用,现在是经验复用。
设计模式让开发人员之间有共享的词汇。设计模式也可以把思考框架的层级提高到模式级别。
基本准则
找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
换句话说,如果每次新的需求一来,都会使某方面的代码发生 变化,那么你就可以确定,这部分的代码需要被抽出来,和其 他稳定的代码有所区分。 这个原则的另一种思考方式:“把会变化的部分取出并 封装起来,以便以后可以轻易地改动或扩充此部分,而不影响 不需要变化的其他部分”。
针对接口编程,而不是针对实现编程。
针对接口编程”真正的意思是“针对超类型(supertype)编程”。“针对接口编程”, 关键就在多态。利用多态,程序可以针对超类型编程,执行时会根据 实际状况执行到真正的行为,不会被绑死在超类型的行为 上。“针对超类型编程”这句话,可以更明确地说成“变 量的声明类型应该是超类型,通常是一个抽象类或者是一 个接口,如此,只要是具体实现此超类型的类所产生的对 象,都可以指定给这个变量。这也意味着,声明类时不用 理会以后执行时的真正对象类型!”
多用组合,少用继承
使用组合建立系统具有很大的弹性,不仅可将算法簇封装成类,更可以“在运行时动态改变行为”,只要组合的行为对象符合正确的接口标准即可。
对修改封闭,对扩展开放
依赖抽象,不要依赖具体类
实例
重点
继承是一种is-a关系,当用继承的时候,肯定是需要利用多态的特性。如果用不到多态的特性,继承的关系是无用的。 继承不要用于代码复用。继承关系的耦合度很高,一处修改导致处处需要修改。这个时候就需要组合。
- 继承是一种is-a关系,在写代码的时候就要指明具体继承哪个类,所以在编译期就确定了关系。并且从基类继承来的实现是无法在运行期动态改变的,因此降低了应用的灵活性。
-
组合是一种has-a的关系,在写代码的时候可以采用面向接口编程。所以,类的组合关系一般在运行期确定。
- 继承结构中,父类的内部细节对于子类是可见的。所以我们通常也可以说通过继承的代码复用是一种白盒式代码复用。
- 组合是通过对现有的对象进行拼装(组合)产生新的、更复杂的功能。因为在对象之间,各自的内部细节是不可见的,所以我们也说这种方式的代码复用是黑盒式代码复用。
继承要慎用,其使用场合仅限于你确信使用该技术有效的情况。一个判断方法是,问一问自己是否需要从新类向基类进行向上转型。如果是必须的,则继承是必要的。反之则应该好好考虑是否需要继承。《Java编程思想》
只有当子类真正是超类的子类型时,才适合用继承。换句话说,对于两个类A和B,只有当两者之间确实存在is-a关系的时候,类B才应该继续类A。《Effective Java》