结构型模式
外观(Façade)模式
代理(Proxy)模式
适配器(Adapter)模式
合成体(Composite)模式
装饰器(Decorator)模式
模式 | 主要功能 |
Façade | 为子系统提供简化接口 |
Proxy | 提供一个中间对象,控制对另一个对象访问 |
Adapter | 允许调用者使用不兼容接口对象 |
Composite | 将对象合成体到一个部分-整体树状结构中 |
Decorator | 动态地为对象附加新功能 |
4.1 Façade模式
提供一个简单的、具有子系统高层接口的 Facade 类
• 客户使用Façade对象来代替与每个子系统对象的单独通信
• Façade包含用于操作顺序、状态管理和与每个子系统对象进行通信的逻辑
• 也可能允许Client直接与其它子系统类进行通信,以获取更多功能
4.1.1 Façade 模式结构
4.1.2 Façade 模式解决方案
4.1.3 Façade 模式序列图
4.1.4 应用Façade模式:推论
优点:
• 对客户隐藏子系统组件,从而降低了客户代码耦合性
• 可减少分布环境中的网络开销
• 对客户与子系统解耦
缺点:
• 引入了一个额外的间接层,会对性能有所影响
4.2 Agent模式
不希望调用者或调用者无法直接访问具体类。
• 远程对象
• 受限对象
• 性能对象
4.2.1 Agent模式结构
4.2.2 Agent模式应用(一)
4.2.3 Agent模式应用(二)
4.2.4 Agent模式推论
优点:
• 代理对于客户来说是透明的
• 代理简化了客户的访问
• 代理提供了一个扩展能力的点
• 代理可以控制或限制对实际对象的访问
缺点:
• 引入了一个额外的间接层,会对性能有所影响
• 与代理的交互不一定总是透明的
4.3 Adapter模式
Adapter与硬件适配器类似
4.3.1 Adapter模式结构
• 使用所需接口创建Adapter类:
• Client 对象调用Adapter上的方法
• Adapter 对象进而调用 Adaptee 类上同样的方法必要时,Adapter 对象可以提供更加复杂的方法或更多方法
• 在对象适配器策略中,Adapter 有一个对 Adaptee 的引用
• 在类适配器策略中,Adapter 是Adaptee 的一个子类
4.3.2 Adapter具体应用
代码实例
1 import java.util.ArrayList;
2 public class Library3SearchEngineAdapter
3 implements Searchable {
4 private Library3SearchEngine adaptee =
5 new Library3SearchEngine();
6 public ArrayList searchByAuthor(String author) {
7 //... full implementation/search by author
8 return results;
9 }
10 public ArrayList searchByCallNumber(String callNum) {
11 return adaptee.searchByCallNumber(callNum);
12 }
13 public ArrayList searchByTitle(String title) {
14 char t[] = title.toCharArray();
15 return adaptee.titleSearch(t);
16 }
17 }
4.3.3 适配器模式:推论
优点:
• 客户类没有因必须使用不同的接口而变得复杂
• 被适配类(Adaptee)不需要修改
• 客户可以使用带有或不带有适配器的被适配类
适配器策略的缺点:
• 必须创建一个附加的对象
• 请求是要转发的,会引起一点儿开销的增加
4.4 合成体模式
为单独对象和合成对象的类提供一个通用接口
4.4.1合成体结构
4.4.2 合成体应用
1 public class Clerk implements Employee
2 {
3 private double basePayRate;
4 private double individualBonus;
5 private int overtimeHours;
6
7 public double calculateDeptPay() {
8 return calculatePay();
9 }
10 public double calculatePay() {
11 double pay = // ... calculate individual pay
12 return pay;
13 }
14 }
1 public class Manager implements Employee {
2 private Employee subordinates[];
3 public void addSubordinate(Employee e) {
4 // ... add e to the subordinates array
5 }
6 public double calculateDeptPay() {
7 double totalPay = calculatePay();
8 for (int i=0; i<subordinates.length; i++) {
9 totalPay += subordinates[i].calculateDeptPay();
10 }
11 return totalPay;
12 }
13 public double calculatePay() {
14 double pay = // ... calculate individual pay
15 return pay;
16 }
17 . . .
18 }
4.4.3 应用合成体模式推论
优点:
• 统一对待合成体对象和部分对象
• 合成体的层次结构可以有任意层数
• 合成体的层次结构具有极高的可扩展性
缺点:
• 组件接口可能不得不提供对合成对象有意义而对部分对象无意义的方法
4.5 Decorator模式
为某些类添加附件功能,如果通过直接创建子类来添加要扩展的功能会导致
• 子类代码过于庞大
• 子类代码的重复
通过Decorator可以解决
• 允许以简单的方式进行扩展
• 允许动态的添加或删除一些功能
• 保持高内聚
4.5.1 Decorator结构
从以上结构可以看出
• 将附加功能从ConcreteComponent类转移到Decorator类
• Decorator 类将一个功能添加到另一个类
• Decorator 类持有其所装饰的ConcreteComponent类的Component类型的引用
• Decorator方法实现其功能并将调用传递到其所装饰的Component类
• 在处理需要装饰的类时,Decorator链对调用者来说是透明的
4.5.1 Decorator应用
4.5.2 时序图
4.5.3 代码实例
1 PayCalculator calc1 = new BasePayCalculator();
2 PayCalculator calc2 = new CanadianTaxCalculator(calc1);
3 PayCalculator calc3 = new RetirementFundCalculator(calc2);
4 calc3.calculatePay();
4.5.4 Decorator在Java编程中的经典应用
4.5.5 Decorator模式推论
优点:
• 可以动态地修改对象的状态和行为
• 由于是基类的添加物,不会修改或破坏继承的层次
• 可以嵌套多个装饰器以添加新的状态和行为
缺点:
• 装饰器类对象和被装饰的对象是不同的,使用不当会出现对象身份的问题
• 要创建许多小对象,会略微降低性能