设计方式之略见一斑(适配器模式Adapter)

设计模式之略见一斑(适配器模式Adapter)

适配器模式就是基于客户提供的接口和功能,再此基础上实现具体业务功能。

它大体分为两类:类适配器与对象适配器

1.类适配器

   类适配器就是本着在客户提供功能接口与业务BO的基础上实现业务功能。

  该类需要继承第三方类并实现定义的接口,再在这个接口的方法实现中调用父类(即第三方类)中需要用到的方法。

先举个例子,我们每次登录QQ时,都会获取当天的新闻信息,假如我们定义一个通用的Customer,它包含有qnumber,loginDate,friends三个属性

public class Customer {   
    private String qnumber;// Q号   
    private Date loginDate;// 登录日期   
    private List friends;// 获得好友信息   
    public Customer(String qnumber, Date loginDate, List friends) {   
        super();   
        this.qnumber = qnumber;   
        this.loginDate = loginDate;   
        this.friends = friends;   
    }   
  
    public List getFriends() {   
        return friends;   
    }   
  
    public void setFriends(List friends) {   
        this.friends = friends;   
    }   
  
    public Date getLoginDate() {   
        return loginDate;   
    }   
  
    public void setLoginDate(Date loginDate) {   
        this.loginDate = loginDate;   
    }   
  
    public String getQnumber() {   
        return qnumber;   
    }   
  
    public void setQnumber(String qnumber) {   
        this.qnumber = qnumber;   
    }   
  
}  


再有就是一个业务功能接口
public interface LoginEvent {   
    //登录时获取新闻信息   
    public void getNews();   
}  


这个事件就是当客户端登录时自动获得新闻信息,那么这时假哪QQ客户端有多种可能性,如Linux下的客户或者Windows下的客户端.

我们分别定义这两个类为

.LinuxCustomer

.WindowsCustomer
为了能够让这两个对象都能够实现当它们登录时都能够获得登录信息,我们就可以通过继续Cutomer并实现接口LoginEvent.

public class LinuxCostomer extends Customer implements LoginEvent{   
    public LinuxCostomer(String qnumber, Date loginDate, List friends) {   
        super(qnumber, loginDate, friends);   
    }   
    public void getNews() {   
        doGetNews();   
    }   
    //处理获得信息   
    private void doGetNews(){   
           
    }   
    <SPAN style="COLOR: #0000ff">public static void main(String[] args) {   
        LinuxCostomer lc = new LinuxCostomer("272401534",new Date(0),new ArrayList());   
        lc.getNews();   
    }</SPAN>   
}  


这就是类适配器,它就是继承业务对象(Customer)并实现业务功能接口(LoginEvent).



2.对象适配器

如果开发者提供的只是抽象类,而不提供接口(很多时候抽象类都会预先实现了一些比较烦琐的业务功能,使我们不用再去一一实现它,那样会带给我们很多方便)。这个时候我们就只能通过继续抽象类,并把业务对象当做参数传递进去进行调用,这便就是对象适配器

例子代码如下:

  开发者只提供的抽象类的LoginEvent

public abstract class LoginEvent {   
    //网络连接   
    public void connectInternet(){   
//      init();   
//      ....and so on...   
    }   
    //登录时获取新闻信息   
    public abstract void getNews();   
}  


而LinuxCustomer(Linux客户登录端)为了能够获取新闻信息并且包含有登录端相应的属性,我们可以通过建立如下适配器LinuxCostomer实现:

public class LinuxCostomer extends LoginEvent{   
    private Customer customer;   
    public LinuxCostomer(Customer customer) {   
         this.customer= customer;   
    }   
    public void getNews() {   
        doGetNews();   
    }   
    //处理获得信息   
    private void doGetNews(){   
           
    }   
    public static void main(String[] args) {   
        LinuxCostomer lc = new LinuxCostomer(new Customer("272401534",new Date(0),new ArrayList()));   
        lc.getNews();   
    }   
}  


通过把Customer当做参数传递给LinuxCustomer同时继承抽象类LoginEvent,重载该类的获得新闻方法getNews



这种方式就是对象适配器模式。

同理linux下系统可能分为各种各样的系统如red hat,solaris等

我们就可以通过继承LinuxCustomer这个适配器,然后再去实现相应的业务功能。





总结:

其实这种开发形式在我们日常开发中很常见,只是有时候我们还不清楚而已。

    类适配器是通过继承类适配者类实现的,另外类适配器实现客户类所需要的接口。当客户对象调用适配器类方法的时候,适配器内部调用它所继承的适配者的方法。

    对象适配器包含一个适配器者的引用与类适配器相同,对象适配器也实现了客户类需要的接口。当客户对象调用对象适配器的方法的时候,对象适配器调它所包含的适配器者实例的适当方法。

它们的区别就下图:
设计方式之略见一斑(适配器模式Adapter)


原文:http://lgh3292.iteye.com/blog/586322