适配器(Adapter)模式
当在设计了一个或多个具体的类之后再进行相关标准接口的定义工作时,这些类可能没有很好的实现这个接口。比如,这些类中的某些方法的名字很可能与那些在接口中定义的方法有许多不同。如果你无法通过修改这些具体类来改正这些问题的话,则可以通过创建一个适配器(Adapter)来消除这种不兼容性。
假设你拥有一个Performer类,该类包括了一个名为performance的方法,并且满足了作为一个Runnable对象运行所需要的所有条件(除了方法名的差别之外),这时,你可以通过创建一个适配器使其他的类可以在一个线程中使用它。
这只是许多用来创建适配器常用方法中的一种,这种方法也是《Design Patter》中提到的几种相关模式的基础。一个Proxy是一个和它的代理有一致接口的适配器。一个Compositer维护了一组代理对象,这些代理对象有同样的接口。
在这种基于代理的组合方式中,这个可以被公开访问的主体类会把对所有方法的访问转送给他所代理的一个或是多个对象。并将会到的返回在转交给调用者。当然,这个过程中也许会根据代理的调用做一些微小的转换(改变方法名称,强制转换参数类型以及过滤结果等等)。
仅仅通过将这个被代理的调用包装在这个控制操作中,适配器便可以用来提供before/after控制。比如,假设我们拥有一个实现类,称为TankImpl,则可以实现如下的AdaptedTank,并把原先类的构造函数:
new TankImpl(…)
替换为:
new AdapedTank(new TankImpl(…))
这样,这个类就可以替代原来的类在应用程序中使用了。
class AdaptedTank implements Tank{
proteced final Tank delegate;
public AdaptedTank (Tank t) {delegate=t;}
public float getCapacity() {return delegate.getCapacity();}
public float getVolume() {return delegate.getVolume();}
protected void checkVolumeInVariant() throws AssertionError{
float v=getVolume();
float c=getCapacity();
if(!(v>=0.0 && v<=c))
throw new AssertionError();
}
public synchronized void transferWater(float amount) throws OverflowExcetion, UnderflowException {
checkVolumeInVariant(); //before-check
try{
delegate.transferWater(amount);
}
catch(OverflowExcetion ex) { throw ex; }
catch(UnderflowException ex) { throw ex; }
finally{
checkVolumeInVariant(); //after-check
}
}
}
参考
Java并发编程—设计原则与模式 1.4.1节
