适配器模式是将将一个类的接口适配成用户所期待的。
生活中适配器也无处不在。常见的是电源适配器。一个15V笔记本通过电源适配器可以接在220V的电压下使用。
想象这么一个需求场景。在项目早期建立了很多类库,这个类库中方法众多,代码复杂,加入新的方法后或者修改旧有方法会使得原类库中方法大幅修改。(或者类库源码找不到了,也难以进行修改)。那么此时可以重新建立一个新接口,通过适配器而使用原有方法。
适配器模式就是将一个接口转化为客户希望的另一个接口。
适配器的常用分类:
现在主要介绍单向适配器和单接口适配器。
1 单向适配器。
Target是目标类,也就是客户端的类。Adaptee是客户端所需要的类,但是现在还不能直接为Target所使用。所以需要建立一个Adapter类,使得Adaptee转换为Target所需要的类。
现在看一个案例。
通过OperatorAdapter适配类使得两个类CommonOperator和Sort,Search可以一起使用。CommonOperator使用了自己所需要的方法needSort与needSearch.
下面是源代码:
package myjava.designpattern.adapter; public class Sort { public String needsort(){ return "排序"; } }
package myjava.designpattern.adapter; public class Search { public String needsearch(){ return "查找"; } }
package myjava.designpattern.adapter; public class OperatorAdapter implements CommonOperator { private Sort sort; private Search search; public OperatorAdapter() { sort = new Sort(); search = new Search(); } @Override public String sort() { // TODO Auto-generated method stub return sort.needsort(); } @Override public String search() { // TODO Auto-generated method stub return search.needsearch(); } }
package myjava.designpattern.adapter; public interface CommonOperator { public String sort(); public String search(); }
package myjava.designpattern.adapter; /** * * @author xiaozl * */ public class Client { public static void main(String[] args) { // TODO Auto-generated method stub //通过适配器类,可以使得两个接口相结合,因为原来客户端并不知 //道具体sort实现方法,现在只需要调用便可以实现不同接口一起工作 //而Sort与Search就是客户端需要适配的类。 CommonOperator co = new OperatorAdapter(); System.out.println(co.sort()); System.out.println(co.search()); } }
输出的结果是:
2 单接口适配器模式
如果一个接口中有太多方法,而实现该接口的类中并不需要这么多的方法,那么便可以使用单接口适配器模式。
下面是一个案例,模仿WindowAdaper。
interface Window{ // 定义Window接口,表示窗口操作 public void open() ; // 打开 public void close() ; // 关闭 public void activated() ; // 窗×××动 public void iconified() ; // 窗口最小化 public void deiconified();// 窗口恢复大小 } abstract class WindowAdapter implements Window{ public void open(){} ; // 打开 public void close(){} ; // 关闭 public void activated(){} ; // 窗×××动 public void iconified(){} ; // 窗口最小化 public void deiconified(){};// 窗口恢复大小 }; class WindowImpl extends WindowAdapter{ public void open(){ System.out.println("窗口打开。") ; } public void close(){ System.out.println("窗口关闭。") ; } }; public class AdapterDemo{ public static void main(String args[]){ Window win = new WindowImpl() ; win.open() ; win.close() ; } };
好无聊啊,看下WindowAdapter的源码吧。
public interface WindowListener extends EventListener { public void windowOpened(WindowEvent e); public void windowClosing(WindowEvent e); public void windowClosed(WindowEvent e); public void windowIconified(WindowEvent e); public void windowDeiconified(WindowEvent e); public void windowActivated(WindowEvent e); public void windowDeactivated(WindowEvent e); }
public abstract class WindowAdapter implements WindowListener, WindowStateListener, WindowFocusListener{ public void windowOpened(WindowEvent e) {} public void windowClosing(WindowEvent e) {} public void windowClosed(WindowEvent e) {} public void windowIconified(WindowEvent e) {} public void windowDeiconified(WindowEvent e) {} public void windowActivated(WindowEvent e) {} public void windowDeactivated(WindowEvent e) {} public void windowStateChanged(WindowEvent e) {} public void windowGainedFocus(WindowEvent e) {} public void windowLostFocus(WindowEvent e) {} }
JMenu中的内部类
WinListener实现了一个方法windowClosing()方法
protected class WinListener extends WindowAdapter implements Serializable { JPopupMenu popupMenu; public WinListener(JPopupMenu p) { this.popupMenu = p; } public void windowClosing(WindowEvent e) { setSelected(false); } }
这就是对于适配器设计模式的简单介绍。最后一点,适配器属于结构性模式。
Sleeping now!!!It is too late!!!