适配器模式是一种结构型模式,所谓结构性模式(Structural Pattern):
描述如何将类或者对象结合在一起,以此来形成更大的结构。
结构型模式可以分为类结构型和对象结构型,其中,类结构型模式关心类层次的组合,一般只存在继承关系和实现关系;而对象结构型关心类与对象的组合,通过关联关系使得在一个类中定义另外一个类的实例对象。根据尽量用组合而不用继承的原则,大部分结构型模式都是对象结构型。
适配器模式:
将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。
由此可见,适配器模式的主要功能在于“兼容”,在适配器模式中定义一个包装类(也就是适配器,Adapter),用来包装不被客户端兼容的对象,这个对象就是适配者(Adaptee),但这个过程对客户端是透明的,客户端并不知道Adapter内部调用了Adaptee的方法。
类适配器
对象适配器
以下是类结构型适配器的简单代码:
package adapter; public class TestClassAdapter { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub testRequeset(); } public static void testRequeset() { System.out.println("TestClassAdapter.request"); Target target = new Adapter(); target.request(); } } interface Target { void request(); } class Adaptee { public void SpecificRequest() { System.out.println("Adaptee.SpecificRequest"); } } class Adapter extends Adaptee implements Target { @Override public void request() { // TODO Auto-generated method stub System.out.println("Adapter.request"); SpecificRequest(); } }
在jdk中,有很多代码都是用到各个类型的设计模式,比如InputStreamReader和OutputStreamWrite就用到了适配器模式。拿InputStreamReader举例,使用的是对象适配器,它继承自Reader(就是Target),并在这个对象中持有StreamDecoder(Adaptee)对象:
public class InputStreamReader extends Reader
private final StreamDecoder sd;
构造InputStreamReader时会初始化这个空白final对象,拿其中之一构造函数来看:
public InputStreamReader(InputStream in) { super(in); try { sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object } catch (UnsupportedEncodingException e) { // The default encoding should always be available throw new Error(e); } }
当Client调用read()方法时,适配器InputStreamReader会将请求适配给适配者,既调用StreamDecoder对象的read方法:
public int read() throws IOException { return sd.read(); } public int read(char cbuf[], int offset, int length) throws IOException { return sd.read(cbuf, offset, length); }
这样,在Client不知情的情况下,达到了接口兼容的效果。
1)将目标类和适配者类解耦,无需修改原来的代码;
2)灵活性和扩展性好,符合“开闭原则”;
3)对于Java这种不支持多重继承的语言,一次最多只能适配一个适配者类,而且目标抽象类只能为抽象类,不能为具体类,其使用有一定的局限性,不能将一个适配者类和它的子类都适配到目标接口。
1)系统需要使用现有的类,而这些类的接口不符合系统的需要;
2)想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。
ps
不知道大家平时用什么工具画UML,刚刚网上找了一个JUDE-Community,基本功能都有,也比较Q,符合我的审美,但是各个图、组建对齐好像没有快捷键,线也没有像PowerDesigner一样可以指定角度,每次都得自己移动鼠标调整,有点麻烦。