5.4 桥接模式(4.2)
桥接模式(bridge pattern)是一种策略式委派方式,其主要目标是避免类型爆炸。
问题描写叙述:如果类Client(比如Client表示一个会所)将对人/Person进行统一的处理,而Person类层次有(以人的职业划分其子类)教师、医生、律师……。另外,系统还须要将Person依照“地域” (或按年龄、收入……)划分,那么处于“武汉教师”、“广州律师”地位的类,其个数将等于地域的子类个数与Person(按职业划分的)子类个数的乘积。
怎样控制“武汉-教师”等等这些类型的数量并且还可以对他们统一的作为Person处理呢?5.4.1 替代多继承性
多继承性普遍存在。
类型X与很多的概念/类型之间存在Is-A关系,并且它的这些父类型彼此并没有必定联系,每个父类型只描写叙述X的一个方面,X须要(应该)继承多个父类才是适当的设计。比如Person(的职业)与地域/Region (还能够有年龄、收入等类层次),是独立的、无关的类型层次,则“武汉教师”与它们都存在As-A关系。
可是,Java中不同意类的多继承,一个可能的设计方案是:以Person类层次为基础时,将Region设计成接口。为每一种职业都提供一套各种地域版本号。10个职业,来自30个地方。则须要300个类——类型爆炸。为了控制类型爆炸。能够以Person(的职业)
为主(主体类),而将还有一个类型(辅助类)Region作为主体类的成员变量。
package delegate.bridge; /** * @author yqj2065 * @version 0.1 */ public abstract class Person{ protected Region where; public void setRegion(Region where) {//依赖注入或随意其它初始化方式 this.where = where; } //依照职业风格和方言介绍自己 public abstract void show(); }
package delegate.bridge; public interface Region{ public void say(String style); }
<pre name="code" class="java">package delegate.bridge; public class WHer implements Region { @Override public void say(String style){ System.out.println(style+"说:您呀好"); }
package delegate.bridge; public class Teacher extends Person{ @Override public void show(){ String myStyle="带着粉笔灰的味道"; this.where.say(myStyle); } }
package delegate.bridge; import tool.God; public class Client{ public static void test(){ Person p = (Person)God.create("Teacher"); p.setRegion( (Region)God.create("Region") ); p.show(); } }这一结构,使得系统中类的数量极大地降低。10个职业,来自30个地方,则须要10+30个类。
值得注意的是。(为每一种职业都提供一套各种地域版本号)300个类的时候。每一个类的say()方法有自己任一的版本号;而在10+30类的时候。不在有300种say()。
原来的完整的方法体被分成了两个阶段,作为Person.show(),全部的老师(无论是哪里的),将依照show()的代码反映其职业特点。而后调用Region.say(),不同的地域有自己的代码块。
因此,两个阶段的代码块组合成10*30种方法体。
桥接模式中,外界接触的是Person的接口show()。而Region.say()某种程度上意味着show()的实现部分。
5.4.2 桥接的作用
[GoF]关于桥接模式意图的描写叙述,即"decouple anabstraction from its implementation so that the two can varyindependently".(将抽象与它的实现分离。使它们都能够独立地变化),我觉得是较难理解的。
“抽象与它的实现分离”。少见的表达。,看《设计模式》的这一节。太累人了,不知道为什么那么别扭。
依照[编程导论]的术语体系,桥接的定义例如以下:
★桥接模式控制类型爆炸,通过辅助类使得主体类的方法多态化。1. show()方法的实现被多态化
主体类Person有教师、医生、律师……子类。它的方法show(),假设不调用地域/Region的say(),每一种子类如Teacher——尽管(每一个子类)有不同的实现方式,可是每一个子类的实现是固定的。除非Teacher派生WHTeacher或GDTeacher,才使得Teacher. show()有多种实现。
在桥接模式中,show()的方法体中因为调用了Region.say(),依照Region指向对象的实际类型,使得show()的实现能够在执行时刻进行配置(甚至能够在执行时刻改变它的实现)。
桥接模式的主要长处源于多态的长处。①主体类和辅助类能够独立地变化,此变化指遵循OCP的“两者都能够通过派生子类加以扩展”。依照Client代码的演示,Person与Region的子类能够进行随意的组合。
②外界接触的是Person的接口show()。
③桥接模式将多个独立维度可能导致的笛卡尔积式类型爆炸转换成辅助类的子类型的累积和。
其它,想到了再加。
最后编辑时间:2014.8.31