Java软件体系结构设计模式之结构模式(11种)
  结构模式主要用来:
  1)处理把责任委托给其他对象的对象。这样一来会引入一种耦合度低的分层体系结构;
  2)在不同情况下方便对象间的通信。比如说某个对象通过通常的方式无法访问,或者由于接口不兼容导致某个对象不可用时;
  3)提供了组织一个聚合对象的方式,从而使其完整地被创建;并且结构模式还提供了及时回收系统资源的方式。
  (一)装饰器
  描述:不是通过继承方式而是以对客户端透明的方式扩展一个对象的功能。
  1)装饰器模式用于动态地扩展一个对象的功能,而不需要改变原始的类代码或使用继承。这一点是通过在一个实际对象的外围创建一个被称为装饰器的封装对象来做到的。
  2)装饰器模式建议生成一个包围在一个对象外面的封装类,通过对象组合而不是继承来实现功能的扩展。
  3)装饰器对象必须提供与它所封装的对象完全相同的接口。当客户对象创建了一个装饰器的实例之后,它们将调用完全一样的接口,以与原始对象完全相同的方式来跟装饰器对象进行交互。
  4)一个装饰器对象可以包含另一个装饰器对象,并将调用转达给它。使用这种方法,新的装饰器,即新的功能可以通过封装一个已有的装饰器对象来实现。
  (二)适配器
  描述:允许把一个类的接口转换成客户端希望的另一个接口。这样可以让具有不同接口的多个类一起工作。
  1)一般说来,一个类的客户对象通过类提供的接口来访问它的服务。有些时候,一个类可以提供客户对象需要的功能,但它的接口却不同于客户对象的期望。这种情况的出现可能有多种原因,比如已有的接口太过详细,或者还不够详细,又或者这些接口使用的术语与客户对象所寻求的有所不同。
  在这样的情况下,已有的接口需要被转换为客户对象所期望的另一个接口,以保留已有类的可重用性。没有这样的转换过程,客户对象将不能够使用该类提供的服务。这一点可以通过使用适配器模式来作用。
  2)适配器模式建议在接口不相容的对象的周围定义一个封装类。这个封装类的对象称为适配器,而它所封装的对象称为一个适配源。适配器提供客户所期望的接口。适配器的接口实现将客户对象的调用转换为对适配源类接口的调用。
  以上讨论中使用的术语“接口”:不是指Java编程语言中的接口概念,虽然一个类的接口可以使用Java接口来声明;也不是指由Windows和GUI控件组成的典型GUI应用当中的用户界面;而是指一个类对外显示的编程接口,这些接口将提供给其他类使用。例如,如果一个类被设计为一个抽象类或Java接口的形式,它所声明的方法集构成了这个类的接口。
  3)适配器:类适配器和对象适配器。
  4)类适配器被设计为适配源类的一个子类的形式。除了继承自适配源类外,适配器类还实现客户对象所期望的接口。当客户对象调用一个适配器方法的时候,适配器在内部调用它继承来的一个适配器源方法。
  5)对象适配器:一个对象适配器拥有适配源对象的一个引用。与类适配器相似,对象适配器也实现客户对象期望的接口。当客户对象调用一个对象适配器方法的时候,对象适配器将通过它拥有的适配源实例的引用调用一个合适的适配源方法。
  在Java应用当中:使用对象适配器,不能对使用protected访问标识符声明的方法进行适配,除非将适配器设计在与适配源相同的包中。(因为这样做的话,适配器才能访问到适配源中protected访问标识符声明的方法。)
  (三)责任链
  描述:避免一个请求的发送对象和接收对象的互相耦合。允许一个发送对象把它的请求传递给一串对象(对象链),而且不必知道哪个对象终将处理这个请求。
  1)责任链(CoR)模式建议在发出请求的对象和该请求的潜在处理对象集之间建立一种低耦合的关联关系。
  2)当存在多于一个对象可以处理或完成客户的请求的时候,CoR模式建议以某种顺序的次序为其中的每个对象提供处理客户的请求的机会。在这种情况下使用CoR模式,可以将所有这些潜在的处理对象安排为一种链的形式,链当中的每个对象都拥有一个指向下一个对象的指针。链当中的第一个对象接受客户的请求,并且做出对请求进行处理或者将请求继续传给下一个对象的决定。这样,客户的请求会顺次地从链当中的一个对象流向另一对象,直至某个对象对它进行处理,或者直到请求到达链的末端而没有得到处理。
  (四)外观
  描述:为一个由类组成的子系统提供了一个高层接口,使得这个子系统更易使用。
  1)外观模式用来处理子系统。一个子系统包含多个类,它们协同合作提供一系列的相关特性(功能)。
  2)外观也是一个类,它把客户对象所需要的子系统的功能简化到简单的接口上。有了外观对象,客户不需要和子系统中具体完成某个功能的类直接交互,而是简单地调用外观对象所提供的接口。外观对象把所有子系统的功能接管过来,客户对象和外观对象打交道,外观对象去调用具体的功能。
  3)在使用外观模式时,下面是一些需要注意的问题:
  3.1)外观类不提供超出原来子系统的其他额外功能;3.2)不要从外观类的方法里返回内部类的引用。
  4)外观模式的目的在于提供一种高层次的接口。所以外观类的接口方法好是一种综合的商业事务层次的方法,而不是原来的个别低层次方法的简单包装。
  (五)代理
  描述:允许一个独立的对象被用作一个替代者以提供对一个对象的受控访问,而通常方法下这个对象是不可访问的。
  1)有时候,客户对象可能无法以正常的方式去直接访问服务提供者对象(又称做目标对象)。这样的情况下,我们可以使用代理模式,这时客户对象不是直接去访问目标对象,而是通过一个代理对象去访问。这个代理对象可以允许不同的客户对象以一种更为普通和直接的方式来间接访问到目标对象。
  2)代理对象和目标对象有同样的调用接口,它代替客户去和目标对象打交道,并负责处理和目标对象之间交流上的特别细节。这样做的好处是,客户对象不需要满足目标对象的特别需要可以轻松地访问它所提供地服务。客户对象调用代理的某个方法,代理对象随即把这些调用转发给目标对象。因为代理对象和目标对象的接口是一样的,客户对象可能根本不需要知道自己实际上是在和一个代理打交道。所有原来不方便的地方,不论是因为目标对象是一个远程对象,还是因为目标对象尚未初始化,或者是目标对象需要特别的认证,这些问题统统由代理对象自己去设法解决。换句话说,代理对象好像是在客户对象和(一个遥不可及的)目标对象之间的一个透明通道。
  3)在不同的环境下需要不同特性的代理对象。
  4)所有的代理对象都有下面两种特性:1. 它是客户对象和目标对象之间的一个中;2. 它接受客户对象的请求,并把它转发给目标对象。
  5)其中,在Java中,远程方法调用(RMI)概念大量地使用了远程代理模式。
  RMI允许客户对象访问远程对象,好像它们都在本地一样。
  一般来说,客户对象是无法用普通方式来直接调用远程对象的方法的。
  (六)桥接
  描述:允许一个抽象接口和它的实现相分离。这样减少了两者的一来关系,允许两者可以被独立修改。
  1)桥接模式进一步把一个抽象体(abstraction)的接口和实现分离开来。在这里,抽象体指的是把对象的和某种具体用途相关的属性和行为分离出来的表现形式。从这个意义上来说,一个对象是一系列抽象体的集合,其中每一个抽象体只包含该项功能的相关属性和行为。彼此之间没有相互干扰。
  一个抽象体的方法(行为)可以有一个或多个实现方式。在具体实现上,抽象体可以被定义为一个接口,然后有一个或多个实例类来实现它。