【设计模式】学习进度
设计原则:
1、找出应用中可能需要变化之处,把他们独立出来,不要和那些不需要的代码混在一起。
2、针对接口编程,而不是针对实现编程。
3、多用组合,少用继承。
4、为了交互对象之间的松耦合设计而努力。
5、类应该对扩展开放,对修改关闭。
6、要依赖抽象,不要依赖具体类。
7、最少知识原则:只和你的密友谈话。
8、好莱坞原则:别打电话给我,我会打电话给你。
9、一个类应该只有一个引起变化的原因。
设计模式:
1、策略模式:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
eg 鸭子
2、观察者模式:定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
eg 气象台
3、装饰对象:动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
装饰者和被装饰者具有共同的超类。
eg starbuzz
4、工厂模式
所有工厂模式都用来封装对象的创建。
(1)简单工厂:只是把具体制造不同种类pizza的过程放到工厂里。
(2)工厂方法模式(Factory Method):定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
通过让子类决定该创建的对象是什么,来达到将对象创建的过程封装的目的。
eg 不同地方做不同地方特色口味的pizza
创建者Creator:通常包含依赖子抽象产品的代码,而抽象产品由子类制造,创建者不需要真的知道在制造哪种具体产品。
产品类Product
产品类和创建者类平行。
(3)抽象工厂模式:提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
每一个具体工厂都能生产一个产品家族。客户创建产品时,只需要使用某一个具体工厂,而不需实例化任何产品对象。
eg 不同地区有不同的工厂来制造不同的调料(调料包括很多不同种类,也就是产品家族)
5、单件模式:确保一个类只有一个实例,并提供一个全局访问点。
6、命令模式:将请求封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。
eg:遥控器控制不同的家用电器
客户:创建具体命令,并设置命令接收者。
命令接口:execute方法。
具体命令:实现execute方法,其中包括一系列接收者的动作。
调用者:持有命令对象,在某时间点调用命令对象的execute方法。
实现了请求调用者和请求接收者的解耦。
7、适配器模式与外观模式
(1)适配器模式:将一个类的接口,转换成客户期望的另一个接口,适配器让原本接口不兼容的类可以合作无间。
客户:依据目标接口实现的。
适配器:实现了目标接口,并持有被适配者的实例。
被适配者
eg:火鸡适配成鸭子接口。
枚举适配到迭代器。
(2)外观模式:提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。
eg:家庭影院
8、模板方法模式:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。(好莱坞原则)
eg:泡茶和泡咖啡
9、迭代器与组合模式
(1)迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。
eg:两种不同的菜单,ArrayList和数组如何统一。
重点是不让客户知道Aggregate的实现细节,只给客户一个迭代器。
新的问题:子菜单的加入。
为了解决子菜单的问题,并且更有弹性地在菜单的各个项之间游走,引入组合模式。
(2)组合模式:允许你将对象组合成树形结构来表现“整体/部分”层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。
Component为Leaf和Composite提供了接口。Composite代表组件的行为。Client通过Component接口访问Leaf和Composite。
Component是个抽象类,其中方法都有默认的实现。
组合模式以单一责任设计原则换取透明性(transparency)。透明性体现在让组件的接口同时包含管理子节点和叶节点的操作,客户就可以将组合和叶节点一视同仁。组合模式是一个很典型的折衷案例。
eg:为菜单项和菜单设置统一的抽象类MenuComponent,用树形结构表示。Waitress通过MenuComponent访问菜单和菜单项。可以创建一个Component的迭代器类,用来无差别地统一迭代菜单项和菜单。
组合模式最重要的优点就是客户无需区分Composite和Leaf,只要针对Component来实现功能即可。