适配器模式定义:Adapter Pattern将一个类的接口,转换成客户期望的另一个接口,Adapter Pattern让原本接口不兼容的2个类可以合作无间。
通过加入适配器,在不修改原有类/接口和现有类/接口的情况下使原本不互通的2个类/接口兼容
适配器模式分为3个组成部分:
Target -- 目标类/接口
Adapter -- 适配器
Adaptee -- 被适配的类/接口(通过Adapter的适配,可以像使用Target一样使用Adaptee)
由于不需要修改Target和Adaptee本身,故使用该设计模式不会为程序带来很大的风险
public class Chick { public void crow(){ System.out.println("chick crow!"); } }
public class ChickLike extends Duck implements Chick { public void crow() { quack(); } }
public class Duck { public void quack(){ System.out.println("duck quack!"); } }
通过ChickLike类,可以像调用Chick类一样调用Duck类
public class Test { public static void main(String[] args) { Chick chick = new ChickLike(); chick.crow(); } }
由于ChickLike类与Duck类之间的关联关系为继承,而继承是一种强关联关系,故可扩展性不高
将ChickLike类与Duck类之间的关联关系修改为聚合(聚合是一种比继承弱的关联关系)以提高程序的可扩展性
public interface Chick { public void crow(); }
public class ChickLike implements Chick { public Duck duck; public ChickLike(Duck duck){ this.duck = duck; } public void crow() { duck.quack(); } }
public class Duck { public void quack(){ System.out.println("quack!"); } }
public class YellowDuck extends Duck { public void quack(){ System.out.println("Yellow Duck can not quack!"); } }
通过ChickLike类,我们可以像使用Chick接口一样使用YellowDuck类(子类也可以被适配)
public class Test { public static void main(String[] args) { Duck duck = new YellowDuck(); Chick chick = new ChickLike(duck); chick.crow(); } }
当然,如果目标类/接口(Chick)比较庞大,适配器(ChickLike)也会变得相当庞大,难于维护
来看一个JDK中使用适配器模式的例子:
通过InputStreamReader类(在其内部StreamDecoder类的帮助下),我们可以像使用Reader类一样使用InputStream类(读字符)