java设计模式4.适配器模式、装饰器模式

  • 适配器模式

把一个类的接口变换成客户端所期待的另外一种接口,从而使本来因接口不匹配而没法在一块儿工做的两个类可以工做。java

1. 类的适配器模式api

  • 目标角色:指望的接口,对于类的适配器模式,此角色不能够是具体类。
  • 源角色:须要适配的接口。
  • 适配器角色:把源接口转换成目标接口,此角色必须是具体类。
public interface Target { void fun2(); }
public class Adaptee { public void fun1(){ } }
// 适配器Adapter扩展了Adaptee,同时也实现了接口Target。这样Adapter的类型是Adaptee同时也提供Target要求的方法。
public class Adapter extends Adaptee implements Target { @Override public void fun2() { // TODO Auto-generated method stub
 } }

2. 对象的适配器模式缓存

  • 目标角色:指望的接口,能够是具体或抽象的类。
  • 源角色: 须要适配的接口。
  • 适配器角色:把源接口转换成目标接口,此角色必须是具体类。
public class Adapter implements Target { private Adaptee adaptee; public Adapter(Adaptee adaptee){ this.adaptee = adaptee; } public void fun1(){ adaptee.fun1(); } @Override public void fun2() { // TODO Auto-generated method stub
 } }

能够看出,对象适配器与类适配器的区别是使用对象组合代替了类型继承。这样一个适配器能够把多种不一样的源适配器到同一个目标。但与类适配器相比,要想置换源类的方法就不太容易,若是必定要置换,能够先作好一个源类的子类置换掉方法,而后将子类看成真正的源进行适配。不过要是想增长一些新的方法则很方便,并且新增长的方法能够同时适用于全部的源。

ide

  • 装饰器模式

装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。使用原来被装饰的类的一个子类的实例,把客户端的调用委派到被装饰类。this

  • 抽象构建角色:给出一个抽象接口,以规范准备接收附加责任的对象。
  • 具体构建角色:定义一个将要接收附加责任的类。
  • 装饰角色:持有一个构建对象的实例,并定义一个与抽象构建接口一致的接口。
  • 具体装饰角色:负责给构建对象贴上附加的责任。

具体装饰角色实现了构建接口,对于每个实现的方法都委派给父类的构建角色,关键在于它功能的加强,而不是单纯地委派。spa

  • 示例:IO设计

java api的io类库中对于适配器装饰器的应用随处可见,这里以读取文件为例,看一下其中的相关的几个类。设计

// 读取一个文件内容
BufferedReader in = new BufferedReader(new FileReader(new File("test.txt")));

BufferedReader是一个典型的装饰器模式,它实现了Reader接口,同时也拥有Reader子类的一个实例,这里也就是FileReader,而后将全部的读取任务都委托给了FileReader的实例,可是增长了缓存读取功能。code

咱们一般会说InputStreamReader是从byte输入流到char输入流的一个适配器,但其实起到适配器做用的是StreamDecoder,它拥有InputStream的实例同时实现了Reader接口,而InputStreamReader在此基础上进一步装饰了StreamDecoder。对象

说一个让java初学者纠结的一个问题,io流关闭问题:因为使用的装饰器模式,对于io流的close,咱们只要调用最外层的close方法就能够了。好比BufferedReader会将close的操做委托给reader实例,这个实例正常是InputStreamReader的实现,而后InputStreamReader又委托给StreamDecoder,最后StreamDecoder又会委托给InputStream的实现类,最终实现了IO流关闭,反过来若是提早调用了委托类的close方法,那么上层的读取也会失败。

blog

#笔记内容参考《java与模式》

相关文章
相关标签/搜索