缺省适配器模式为一个接口提供缺省实现,这样子类型可以从这个缺省实现进行扩展,而不必从原有接口进行扩展。作为适配器模式的一个特例,缺省适配器模式在Java语言中有着特殊的应用。
在阅读本文章之前,请先阅读"适配器模式"文章。
缺省适配器是一种"平庸"化的适配器模式,这个模式的静态结构可以通过下面UML类图看清楚,如下:
该类图涉及的对象如下:
IAdapter:缺省适配器的抽象目标角色,该接口定义类缺省适配器的行为;
DefaultAdapter:默认适配器实现类,该类中的所有方法都只是空实现,即不做任何操作;
Java代码如下:
// 监听接口 public interface IAdapter { public void mouseDown(); public void mouseUp(); public void keyUp(); public void keyDown(); public void click(); } // 默认适配器类 public class DefaultAdapter implements IAdapter { @Override public void mouseDown() {} @Override public void mouseUp() {} @Override public void keyUp() {} @Override public void keyDown() {} @Override public void click() {} } // 我们需要的业务类 public class Business { private IAdapter iAdapter; public Business() {} public void setAdapter(IAdapter iAdapter) { this.iAdapter = iAdapter; } public void run() { if ( null == iAdapter ) { throw new NullPointerException("Please set IAdapter."); } // 调用事件 iAdapter.mouseDown(); iAdapter.mouseUp(); iAdapter.keyUp(); iAdapter.keyDown(); iAdapter.click(); } } // 客户端,我们只需要实现click点击事件,实现方式分为两种 public class Client { /** * 直接实现IAdapter接口,实现所有方法 */ public void test01() { Business business = new Business(); business.setAdapter(new IAdapter() { @Override public void mouseUp() {} @Override public void mouseDown() {} @Override public void keyUp() {} @Override public void keyDown() {} @Override public void click() { System.out.println("test01() -> click"); } }); business.run(); } /** * 继承DefaultAdapter类,选择性的实现某个方法 */ public void test02() { Business business = new Business(); business.setAdapter(new DefaultAdapter() { @Override public void click() { System.out.println("test02() -> click"); } }); business.run(); } public static void main(String[] args) { Client client = new Client(); client.test01(); client.test02(); } }
上述代码中,我们分别展示了直接实现IAdapter接口和继承缺省模式DefaultAdapter类。明显在实现IAdapter中方法较少的时候,选择DefaultAdapter更合适;如果你需要将IAdapter接口的所有方法都实现,则两者选择哪一个都一样。
缺省模式在Java中得到了很好的应用,比如在Swing编程中,我们需要对某些组件的鼠标、键盘等事件进行监听时,如果直接实现某个接口,则需要实现一大堆我们不需要的接口方法,因此引入了缺省适配器,我们可以选择性的实现我们需要关注的方法。
下面我们以MouseListener为例,下面是MouseListener接口的代码。如下图:
上图中,该接口定义了很多关于鼠标的事件方法。如果每次只需要监听某一个动作,需要将上面的方法都实现。因此,我们创建了缺省适配器。如下图:
上图中,这些代码都是对MouseListener接口方法的空实现,什么也不做,如果我们要监听mouseClicked事件,代码如下:
import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.JFrame; import javax.swing.WindowConstants; public class MyFrame extends JFrame { private static final long serialVersionUID = 1L; public MyFrame() { this.setTitle("测试MouseListener事件"); this.setSize(500, 350); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); this.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { System.out.println(e.getX() + "-" + e.getY()); } }); this.setVisible(true); } public static void main(String[] args) { new MyFrame(); } }