备忘录模式,组合模式,迭代器模式,单例模式,桥接模式总结
备忘录模式(Memento): 在不破坏封装性的前提下,捕获一个对象
的内部状态,并在该对象之外保存这个状态。这样以后就可将该
对象恢复到原先保存的状态。
Originator(发起人):负责创建一个备忘录(Memento),用以记录当前
时刻它的内部状态,并可使用备忘录恢复内部状态。
Originator可根据需要决定Memento存储Originator的哪些内部
状态。
Memento(备忘录):负责存储Originator对象的状态,并可防止Originator
以外的其他对象访问备忘录Memento.备忘录有两个接口,
Caretaker只能看到备忘录的窄接口,它只能将备忘录传递给其他对
象。Originator能够看到一个宽接口,允许它访问返回到先前状态
所需的所有数据。
Caretaker(管理者):负责保存好备忘录Memento,不能对备忘录的
内容进行操作或检查。
要保存的细节给封装在了Memento中了,哪一天要更改保存的细节也不用影响客户端了。
那么这个备忘录模式都用在一些什么场合呢?
Memento模式比较适用于功能比较复杂的,但需要维护或记录属性历史的类,或者需要保存
的属性只是众多属性中的一小部分时,Originator可以根据保存的Memento信息还原到前
一状态。如果在某个系统中使用命令模式时,需要实现命令的撤销功能,那么命令模式
可以使用备忘录模式来存储可撤销操作的状态。使用备忘录可以把复杂的对象内部信息对其他的对象屏蔽起来。当角色的状态改变的时候,有可能这个状态无效,这时候就可以使用暂时存储起来的备忘录将状态复原
-------------------------------------------------------------------
组合模式
整体与部分可以被一致对待
组合模式(Composite),将对象组合成树形结构以表示'部分-整体'的层次结构。
透明方式与安全方式
透明方式,也就是说在Component中声明所有用来管理子对象的方法,其中包括
Add,Remove等。这样实现Component接口的所有子类都具备了Add和Remove.这样
做的好处就是叶节点和枝节点对于外界没有区别,它们具备完全一致的行为接口。
但问题也很明显,因为Leaf类本身不具备Add(),Remove()方法的功能,所以实现
它是没有意义.
安全方式:也就是在Component接口中不去声明Add和Remove方法,那么子类的Leaf
也就不需要去实现它,而是在Composite声明所有用来管理子类对象的方法,
不过由于不够透明,所以树叶和树枝类将不具有相同的接口,客户端的调用
需要做相应的判断,带来了不便。
需求中是体现部分与整体层次的结构时,以及你希望用户可以忽略组合对象与单个对象
的不同,统一地使用组合结构中的所有对象时,就应该考虑用组合模式。
组合模式这样就定义了包含基本对象,组合对象的类层次结构。基本对象可以被组合成更
复杂的组合对象,而这个组合对象又可以被组合,这样不断地递归下去,客户代码中,
任何用到基本对象的地方都可以使用组合对象了。
用户是不用关心到底是处理一个叶节点还是处理一个组合组件,也就用不着为定义组合而
写一些选择判断语句了。组合模式让客户可以一致地使用组合结构和单个对象。
-------------------------------------------------------------------
迭代器模式
提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。
当你需要访问一聚集对象,而且不管这些对象是什么都需要遍历的时候,你就应该考虑
用迭代器模式。你需要对聚集有多种方式遍历时,可以考虑用迭代器模式。为遍历不同
的聚集结构提供如开始,下一个,是否结束,当前哪一项等统一的接口。
研究历史是为了更好地迎接未来
迭代器(Iterator)模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,
这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。
--------------------------------------------------------------------
单例模式
所有类都有构造方法,不编码则系统默认生成空的构造方法,若有显示定义的构造方法,
默认的构造方法就会失效。单例模式(Singleton),保证一个类仅有一个实例,并提供一个
访问它的全局访问点。通常我们可以让一个全局变量使得一个对象被访问,但它不能防止
你实例化多个对象。一个最好的办法就是,让类自身负责保存它的唯一实例。这个类可以
保证没有其他实例可以被创建,并且可以提供一个访问该实例的方法。
单例模式因为Singleton类封装它的唯一实例,这样它可以严格地控制客户怎样访问它以
及何时访问它。简单地说就是对唯一实例的受控访问。
多线程单例和双重锁定(Double-Check Locking)。
静态初始化的方式是在自己被加载时就将自己实例化,所以被形象地称之为饿汉式单例
类,
在第一次被引用时,才会将自己实例化,所以就被称为懒汉式单例类。
--------------------------------------------------------------------
对象的继承关系是在编译时就定义好了,所以无法在运行进改变从父类继承的
实现。子类的实现与它父类有非常紧密的依赖关系,以至于以父类实现中的任何
变化必然会导致子类发生变化。当你需要复用子类时,如果继承下来实现不适合
解决新的问题,则父类必须重写或被其他更适合的类替换。这种依赖关系限制了
灵活性并最终限制了复用性。
合成/聚合复用原则(CARP),尽量使用合成/聚合,
尽量不要使用类继承。聚合表示一种弱的‘拥有’关系,体现的是A对象可以包含
B对象,但B对象不是A对象的一部分;合成则是一种强的‘拥有’关系,体现了严格
的部分和整体的关系,部分和整体的生命周期一样。
合成/聚合复用原则的好处是,优先使用对象的合成/聚合将有助于你保持每个类被
封装,并被集中在单个任务上。这样类和类继承层次会保持较小规模,并且不太可能
增长为不可控制的庞然大物。
--------------------------------------------------------------------
桥接模式(Bridge),将抽象部分与它的实现部分分离,使它们都可以独立地变化。
什么叫抽象与它的实现分离,这并不是说,让抽象类与其派生类分离,因为这没有
任何意义。实现指的是抽象类和的派生类用来实现自己的对象。实现方式有多种,
其核心意图就是把这些实现独立出来。让它们各自地变化。
我的理解就是实现系统可能有角度分类,每一种分类都有可能变化,那么就把这种
多角度分离出来让它们独立变化,减少它们之间的耦合。
只要真正深入地理解了设计原则,很多设计模式其实就是原则的应用而已,或许在不
知不觉中就在使用设计模式了。