1.面向接口--组件间使用接口连接而不是具体实现类,修改实现时不需要修改另一个组件的引用代码,使组件间轻耦合
2.封装变化--典型:策略设计模式(玩具鸭会飞的例子,组合变化的接口,不强制实现,只需要修改变化的独立代码,解决了继承和接口实现方式应对变化时的大规模覆盖、强制实现)
3.多用组合(has-a),少用继承(is-a)--前者灵活性高,封装了变化(变化的代码在独立的类中),可灵活替换,不强制实现;后者不利于扩展:单根继承,应对变化需要自己覆盖方法,和定义更多方法。
4.工厂模式:替换new的方式创建具体实例,封装创建实例的可变性(简单工厂,仅仅被调用来创建实例的独立工厂类,比如Pizza工厂)。
工厂方法模式(PizzaStore加盟店的例子):提供创建对象的接口,一个抽象方法,工厂为抽象类(也可以不是,定义一个默认的创建某个具体产品实例的方法),具体实例化哪个类(产品)由子类实现。产品实现抽象接口(比如Pizza)。工厂方法可以传入参数产生不同类型产品,成为参数化工厂方法。
抽象工厂模式(Pizza原料工厂的例子):抽象工厂类定义一组生产(各种)原料(也是抽象的)的抽象方法,由子类工厂实现。具体产品(Pizza子类,Pizza是抽象产品)的构造函数传入不同的抽象工厂实例,利用抽象工厂类定义的一组原料生产方法进行组合,生产出不同的Pizza。产品(Pizza子类实现)生产只涉及抽象工厂,运行时自动使用实际工厂。
工厂方法&抽象工厂的区别:前者使用继承,在工厂方法实现中,创建抽象产品的具体产品实例;后者使用组合,在抽象工厂的实现中,创建一组抽象产品组件的具体组件实例,然后另一个客户端使用这个抽象工厂实现的这组创建组件方法,将组件组合成一个具体产品。
联系:抽象工厂的组件创建方法,使用的是工厂方法模式。
5.观察者模式:采用订阅-通知(取消订阅-不再通知)机制,面向接口,模块间解耦。注意少用继承,多用接口。继承可扩展性差。
使用设计模式的目的是尽量减少耦合的代码,封装变化,减少硬编码,提高代码灵活性、可重用性。也就是尽量在需要扩展、改变时,减少需要改变的类。改变封装在独立的类中,其他类不变。使用时模块化,模块间只需要简单地设置、覆盖、替换,即可完成功能扩展。