学习设计模式使用的书本为《head first 设计模式》
根据教材写的各模式的示例代码放在GitHub上,后续会将仓库地址放上来。
定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。
将可能产生变化的部分方法(鸭子的fly行为)封装起来,成为一个接口(FlyBehavior)。而后对于一些具体的实现,创建相应的类(FlyWithWings)。并在使用类(Duck)中加入一个私有的接口类型(FlyBehavior)变量,在特定的时候将该变量赋值为具体的对象。
定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
以报纸订阅为例。使用一个接口(接口1)代表对观察者的控制,其中定义注册、删除和更新所有观察者方法。使用另一个接口(接口2)表示观察者,其中定义更新方法。观察者类实现接口2,实现特定的更新方法。而主题类实现接口1,并包含一个观察者接口列表。
当注册、删除时,向该观察者接口列表增删对象。当更新时,循环调用每一个观察者接口对象的更新方法。
在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
还是依赖于Java中父类变量可以指向子类对象的特性,通过声明一个统一的基类,然后通过这个基类派生出特定的主题类以及各种装饰器类。然后在装饰器中定义一个父类变量,再将被装饰的主题类赋值给这个变量,从而可以在装饰器中调用主题类的方法,通过对这些方法的覆盖,达到装饰的效果。
因为共有同一个父类,故装饰后的装饰器类可以在需要主题类的位置替代出现。但是同样存在一定的局限性,那就是只能以父类的形式使用,不能以想要的特定主题类使用。
工厂模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
工厂模式定义了两个接口(接口或抽象类),一个产品接口、一个工厂接口。其中通过实现产品接口定义具体的产品类,通过实现工厂接口定义具体的工厂类。
通过这样的模式,能给与子类一定的自由,如:工厂类生产何种产品,产品类的属性、如何初始化等。但同时也能对子类的一定部分进行约束,如:工厂类中如何加工产品等。
确保一个类只有一个实例,并提供一个全局访问点。
通过将类的构造函数定义成私有函数,然后声明一个公有全局函数构造和获取唯一的实例。
该模式可以保证数据库连接、缓存等对象为唯一的。节约资源以及确保程序安全。
当使用单例模式时,一旦设计到多线程,可能导致单例模式被破坏。
可以使用"急切"创建实例,即一开始就初始化单例对象。
可以使用“双重检查加锁”
将“请求”封装成对象,以便使用不同的请求、队列或日志来参数化其他对象。命令模式也可支持撤销操作。
定义一个 “命令”接口,然后创建不同的命令类—实现“命令”接口,命令类将接口中的方法实现—通过调用实体类的方法。然后控制类通过设置对应的命令接口对象,可以实现控制类中的方法在赋值了不同的命令接口对象时,可以完成不同动作。
如:一个拥有7个按钮的万能遥控器,通过设置不同的命令对象,可以使这七个按钮完成特定的动作。设置开灯命令对象时,按钮可以完成开灯动作等。
将一个类的接口,转换成客户期望的另一个接口。适配器可以让原本接口不兼容的类可以合作无间。
当一个某种场景需要A类对象作为参数,而实际参数却是属于B类。此时需要一个适配器将B类参数适配为A类。此时,可以定义一个适配器类—继承A类,并包含一个B类对象(或直接继承A、B类)。则,该适配器类即可用于A类对应的场景,又完成了B类的资源的调用。即实现了B类在A类场景的使用。
提供了一个统一的接口,用来访问子系统种的一群接口。外观定义了一个高层接口,让子系统更容易使用。
一个系统可能拥有多个部分、多个类、多个接口。有时一个完整的功能可能涉及到这个系统的多个部分,一个个调用可能比较麻烦,所以通过外观模式对这些部分进行一个统一封装,封装成一个统一的接口,简化这个过程。但是同时也不会妨碍对那些部分的访问和调用,只是提供一个更方便的接口。
在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
父类中的一个方法实现了骨架,其中的一些部分被封装成抽象方法或普通方法。允许子类实现父类的这些抽象方法或覆盖普通方法。其中抽象方法实现了子类定义算法的某些步骤。
其中覆盖的普通方法,称为钩子方法。钩子方法可以实现子类对父类定义的模板方法的控制。
提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。
当有两种或两种以上的集合(数组、队列…)需要用于同一场合,可以通过申明一个拥有遍历集合功能的方法的迭代器接口,然后通过实现这个接口创建每个集合类的特定迭代器类。然后通过该迭代器类,即可对不同的集合类使用相同的方法(hasNext、next)进行遍历。
组合模式允许你将对象组合成树形结构来表现“整体 / 部分”层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。
如上图所示,当一个集合的元素既可能是元素项,也可能是另一个集合 — 即结构可能为树形时。通过定义一个共有的component接口,其中定义集合中元素项、集合项可能用到的方法。然后根据该接口派生出元素项类和集合项类。
其中,元素项(叶子节点)包含自己的属性、实现自身需要的方法。集合项(组合节点)包含属性以外,还包含一个component对象数组,存储该集合的元素。并实现集合项需要的方法。当需要遍历时,组合节点遍历自身所有节点,并调用每个节点对应方法。