缺省适配器模式为一个接口提供缺省实现,这样子类型可以从这个缺省实现进行扩展,而不必从原有接口进行扩展。作为适配器模式的一个特例,缺省适配器模式在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的应用
缺省模式在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();
}
}