Copy On Write机制 引用大佬的blog:http://blog.csdn.net/lovelion/article/details/17517213 12.享元模式: 在java中,数据库连接池,线程池等即是用享元模式的应用 享元模式: 享元模式通过共享技术实现相同或相似对象的重用, 在逻辑上每一个出现的字符都有一个对象与之对应,然而在物理上它们却共享同一个享元对象 在享元模式中,存储这些共享实例对象的地方称为享元池(Flyweight Pool) 享元对象能做到共享的关键是区分了内部状态(Intrinsic State)和外部状态(Extrinsic State) 内部状态是存储在享元对象内部并且不会随环境改变而改变的状态,内部状态可以共享 外部状态是随环境改变而改变的、不可以共享的状态 正因为区分了内部状态和外部状态,我们可以将具有相同内部状态的对象存储在享元池中, 享元池中的对象是可以实现共享的,需要的时候就将对象从享元池中取出,实现对象的复用 享元模式结构较为复杂,一般结合工厂模式一起使用 在享元模式结构图中包含如下几个角色: [根据对象职责来定功能方法] Flyweight(抽象享元类):通常是一个接口或抽象类,在抽象享元类中声明了具体享元类公共的方法, 这些方法可以向外界提供享元对象的内部数据(内部状态),同时也可以通过这些方法来设置外部数据(外部状态)。 ConcreteFlyweight(具体享元类):它实现了抽象享元类,其实例称为享元对象; 在具体享元类中为内部状态提供了存储空间。 通常我们可以结合单例模式来设计具体享元类,为每一个具体享元类提供唯一的享元对象。 UnsharedConcreteFlyweight(非共享具体享元类):并不是所有的抽象享元类的子类都需要被共享, 不能被共享的子类可设计为非共享具体享元类;当需要一个非共享具体享元类的对象时可以直接通过实例化创建。 FlyweightFactory(享元工厂类):享元工厂类用于创建并管理享元对象,它针对抽象享元类编程, 将各种类型的具体享元对象存储在一个享元池中, 享元池一般设计为一个存储“键值对”的集合(也可以是其他类型的集合),可以结合工厂模式进行设计; 当用户请求一个具体享元对象时,享元工厂提供一个存储在享元池中已创建的实例或者创建一个新的实例 (如果不存在的话),返回新创建的实例并将其存储在享元池中。 --关键点 享元类的设计是享元模式的要点之一,在享元类中要将内部状态和外部状态分开处理, 通常将内部状态作为享元类的成员变量,而外部状态通过注入的方式添加到享元类中 外部状态extrinsicState在使用时由外部设置,不保存在享元对象中,即使是同一个对象,在每一次调用时也可以传入不同的外部状态 适用场景 在以下情况下可以考虑使用享元模式: (1) 一个系统有大量相同或者相似的对象,造成内存的大量耗费。 (2) 对象的大部分状态都可以外部化,可以将这些外部状态传入对象中。 (3) 在使用享元模式时需要维护一个存储享元对象的享元池,而这需要耗费一定的系统资源, 因此,应当在需要多次重复使用享元对象时才值得使用享元模式。 13.代理模式: 代理模式是一种对象结构型模式 核心关键点: 声明了真实主题和代理主题的共同接口,所以客户端通常需要针对抽象主题角色进行编程 与装饰模式很像,从两者的UML关系土中可以看出来的不同在于,代理模式中持有的被代理对象是直接被实例化的,而不像装饰模式是传值进去 代理模式的使用场景 1.远程代理(RMI) 2.虚拟代理(通过一个消耗资源较少的对象来代表一个消耗资源较多的对象,使用多线程完成资源较多对象的创建) 3.缓冲代理(为某一个操作的结果提供临时的缓存存储空间,以便在厚徐使用中能够共享这些结果 hibenate的load()方法) 4.保护代理(控制对一个对象的访问权限) 14.责任链模式 职责链模式通过建立一条链来组织请求的处理者 一个纯的职责链模式要求一个具体处理者对象只能在两个行为中选择一个:要么承担全部责任,要么将责任推给下家 核心关键点: 在顶级抽象类中会持有一个抽象类对象(用来指定下家处理)->会有很多个抽象类实现类都能处理同一个请求 责任(一个处理任务的方法,指定下家的方法) 责任链的创建(谁是起始,哪个是哪个的下家)在客户端!!! 适用场景: 1.有多个对象可以处理同一个请求,具体哪个对象处理该请求待运行时刻再确定,客户端只需将请求提交到链上,而无须关心请求的处理对象是谁以及它是如何处理的 2. 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。 3.可动态指定一组对象处理请求,客户端可以动态创建职责链来处理请求,还可以改变链中处理者之间的先后次序