一.接口型模式的介绍:
类的接口是类允许其他类对象访问的方法与字段集,接口代表一种承诺,即方法需要实现接口方法名表示的操作,类的实现
就是位于方法体中的代码。
接口与抽象类的关键区别:虽然类只能声明扩展一个类,却可以声明实现多个接口。
接口在不同场景下的使用模式:
适配器模式:适配类的接口以匹配客户端期待的接口;
外观模式:为一组类提供一个简单接口;
合成模式:为单个对象与复合对象提供统一的接口;
桥接模式:解除抽象与现实之间的耦合,使得两者能够独立演化。
二、适配器(Adapter)模式:
适配器模式的意图在于,使用不同接口类所提供的服务为客户端提供它所期望的接口。
1.接口适配:
当客户端子接口中定义了它所期待的行为时,就可以运用适配器模式,提供一个实现该接口的类,
并同时令其成为现有类的接口。倘若没有定义客户端期待的接口,也可以运用适配器模式,但必须
使用“对象适配器”。
2.类与对象适配器:
类的适配器是通过子类进行适配。在类的适配器中,新的适配类实现了需要的接口,并继承自现有的类。
当你需要适配的一组方法并非被定义在接口中时,这种方式就不奏效了。此时可以创建一个对象适配器,
它使用委派而非继承。
newClass类的实例同时也RequireClass类的实例,换言之,newClass类满足了客户端的要求。
newClass类通过使用exitstringClass实例对象,也可以将ExistringClass类适配为符合客户端
的需要。
具体代码示例:
适配器模式使我们可以重用一个现有的类,以满足客户端的需要。当客户端通过接口表达其需求时,
通常可以创建一个实现了该接口的新类,同时使该类继承自现有类。这种方式是类的适配器,它能够
将客户端的调用转换为对现有类方法的调用。
当客户端没有指定它所需要的接口时,就可以使用适配器模式。可能需要创建一个新的客户端子类,
它将使用现有类的实例。这种方式通过创建一个对象适配器。将客户端的调用指向现有类的实例。
如果我们不需要重写客户单可能调用的方法时,这种方式存在一定的危险性。
三、外观模式:
面向对象编程的最大优势,在于它能防止应用程序成为混乱纠缠的小块程序,理想状态下,
面向对象系统应该是将其他可复用的工具类中的行为组织在一起的最小的类。
工具包或子系统的开发人员通常会将设计良好的类组织为包,而不是提供给应用程序。
Java类库中包通常可以当做工具包(toolkits),以保证我们能够随意地开发各种特定领域的应用程序。
简化工具包的另一途径是使用外观(facede)模式。只需少量代码,就能提供典型的、无修饰用法的类库中的类。
一个外观就是一个类,它包含的功能介于工具包与完整的应用程序之间,为工具包或子系统的类提供简单的用法。
外观模式的意图是为子系统提供一个接口,便于它的使用。
1.重构到外观模式:
外观模式常见于一些常规的应用程序开发。如根据关注点将分解为不同的类,就可以提取一个类,它的主要职责
是为了子系统提供简便的访问方式,从而完成对系统的重构。
2.小结:
整体而言,应该对子系统中的类进行重构,直到每个类都有一个明确的目的。这可以使代码更容易维护,
但也可能使用该子系统的用户变得无所适从。为了让调用这些代码的开发人员使用更方便,可以为子系统
提供示例程序或者外观类通常示例程序可以独立运行,却无法重用,仅用与演示使用子系统的方法。
外观类则是克配置、可重用的类,提供了高层次的接口,使得子系统的使用更加方便。
四、合成(Composite)模式:
合成模式是一组对象的组合,这些对象可以是容器对象,表现为组的概念;另外一些对象则代表了单对象,
或称叶子对象。在对组合进行建模时,必须注意两个重要的概念。第一个概念是组对象允许包含单对象,也可以
再包含其他的组对象(常见的错误是将组对象设计为只允许包含叶子对象)。第二个概念则是要为组合对象
和单对象定义共同的行为。结合这两个概念,就可以为组对象与单对象定义统一的类型,并将该组对象建模
为包含同等类型对象的集合。
合成模式的意图是为了保证客户端调用单对象与组合对象的一致性。
1.常规组合:
图5.1展现了经典的组合结构。leaf类和composite类都实现自一个抽象的component通用接口,同时,
composite对象又包含了其他component和leaf对象的集合。
2.组合、树、环:
在合成结构中,如一个节点拥有对其他节点的应用,则该节点就是一棵树。
a应用b,b引用c,这一系列的引用导致出现了一条从a到c的路径。环(cycle)指的是路径中
包含了出现两次的节点。若对象c反向引用a的话,将会在对象模型中出现一个环。
五、桥接(Bridge)模式:
桥接模式关注抽象的设计。抽象是指包含了一组抽象方法的类,这些抽象方法可能包含多个实现。
实现抽象的一般做法是创建类的层次结构,该层次的顶部是一个包含抽象方法的抽象类;该类的每个子类
都提供这些抽象方法的不同实现。但是,当需要对该层次进行子类话时,这一做法就存在不足。
创建一个桥,然后把这些抽象方法移到接口中。这样,抽象就将依赖于接口的实现。
桥接模式的意图是将抽象与抽象方法的实现互相分离来实现解耦,以便二者可以互相独立地变化。
1.常规抽象:桥接模式的一种方法
从某种意义上说,如认为每个类都是实体模型的近似化、理想化或者简单化,那么几乎每个类都是
一个抽象。但在讨论桥接模式时,我们用“抽象”这个词专指依赖一组抽象操作的类。
2.从抽象到桥接模式:
将抽象从抽象方法的实现中分离出来,使得两个类层次结构能够独立变化。
3.使用桥接模式的驱动器:
驱动器是抽象的。应用程序的执行结果取决于当前执行的事哪个驱动器。每个驱动器都是
适配器(Adapter)模式的一个实例。他们通过调用具有不同接口的类提供的服务,向客户提供
期望的接口。使用驱动器的整体设计就是一个桥接模式的实例。这样的设计将应用程序的开发从
驱动器的开发中分离出来,驱动器实现了应用程序所依赖的抽象方法。
基于驱动器的设计迫使你为被驱动出来的机器或设计出一个通用、抽象的模型。这样做的好处是,
抽象端的代码可以被应用到任何可能被执行的驱动器中。
4.数据库驱动:
JDBC是执行结构化SQL语句的应用程序接口(API)。该接口的实现类就是JDBC驱动程序,
依赖于该接口的应用程序是抽象的,它可以工作在任何提供了JDBC驱动的数据库中。JDBC架构
将抽象与实现相互分离,因而两者可以独立地变化。
JDBC架构清晰地区分了驱动程序员与应用程序员的角色。我们可以抽象的超类建立驱动程序子类,
每个子类负责驱动不同的子系统。在这种情形下,一旦需要更好的灵活性,就可以使用桥接模式。
5.小结:
抽象是指依赖于抽象方法的类。最简单的抽象例子是一个抽象的类层次结构,在该结构下,
超类的具体方法依赖于其他抽象方法。如想将最初的类层次结构分解为另一种类层次结构,就必须
将这些抽象方法移到另一个类层次结构中。此时就应该运用桥接模式,完成抽象方法实现与抽象的分离。