`

适配器模式2

阅读更多

4.2  解决方案

4.2.1  适配器模式来解决

用来解决上述问题的一个合理的解决方案就是适配器模式。那么什么是适配器模式呢?

(1)适配器模式定义

 

(2)应用适配器模式来解决的思路

       仔细分析上面的问题,问题的根源在于接口的不兼容,功能是基本实现了的,也就是说,只要想办法让两边的接口匹配起来,就可以复用第一版的功能了。

按照适配器模式的实现方式,可以定义一个类来实现第二版的接口,然后在内部实现的时候,转调第一版已经实现了的功能,这样就可以通过对象组合的方式,既复用了第一版已有的功能,同时又在接口上满足了第二版调用的要求。

完成上述工作的这个类就是适配器。

4.2.2  模式结构和说明

适配器模式的结构如图4.6所示:

 

图4.6  适配器模式结构图

Client

客户端,调用自己需要的领域接口Target。

Target

定义客户端需要的跟特定领域相关的接口。

Adaptee

已经存在的接口,通常能满足客户端的功能要求,但是接口与客户端要求的特定领域接口不一致,需要被适配。

Adapter

适配器,把Adaptee适配成为Client需要的Target。

4.2.3  适配器模式示例代码

(1)先看看Target接口的定义,示例代码如下:

/**

 * 定义客户端使用的接口,与特定领域相关

 */

public interface Target {

    /**

     * 示意方法,客户端请求处理的方法

     */

    public void request();

}

(2)再看看需要被适配的对象定义,示例代码如下:

/**

 * 已经存在的接口,这个接口需要被适配

 */

public class Adaptee {

    /**

     * 示意方法,原本已经存在,已经实现的方法

     */

    public void specificRequest() {

       //具体的功能处理

    }

}

(3)再看看适配器对象的基本实现,示例代码如下:

/**

 * 适配器

 */

public class Adapter implements Target {

    /**

     * 持有需要被适配的接口对象

     */

    private Adaptee adaptee;

    /**

     * 构造方法,传入需要被适配的对象

     * @param adaptee 需要被适配的对象

     */

    public Adapter(Adaptee adaptee) {

       this.adaptee = adaptee;

    }

 

    public void request() {

       //可能转调已经实现了的方法,进行适配

       adaptee.specificRequest();

    }

}

(4)再来看看使用适配器的客户端,示例代码如下:

/**

 * 使用适配器的客户端

 */

public class Client {   

    public static void main(String[] args) {

       //创建需被适配的对象

       Adaptee adaptee = new Adaptee();

       //创建客户端需要调用的接口对象

       Target target = new Adapter(adaptee);

       //请求处理

       target.request();

    }

}

4.2.4  使用适配器模式来实现示例

       要使用适配器模式来实现示例,关键就是要实现这个适配器对象,它需要实现第二版的接口,但是在内部实现的时候,需要调用第一版已经实现的功能。也就是说,第二版的接口就相当于适配器模式中的Target接口,而第一版已有的实现就相当于适配器模式中的Adaptee对象。

(1)把这个适配器简单的实现出来,示意一下,示例代码如下:

/**

 * 适配器对象,把记录日志到文件的功能适配成第二版需要的增删改查的功能

 */

public class Adapter implements LogDbOperateApi{

    /**

     * 持有需要被适配的接口对象

     */

    private LogFileOperateApi adaptee;

    /**

     * 构造方法,传入需要被适配的对象

     * @param adaptee 需要被适配的对象

     */

    public Adapter(LogFileOperateApi adaptee) {

       this.adaptee = adaptee;

    }

   

    public void createLog(LogModel lm) {

       //1:先读取文件的内容

       List<LogModel> list = adaptee.readLogFile();

       //2:加入新的日志对象

       list.add(lm);

       //3:重新写入文件

       adaptee.writeLogFile(list);

    }

    public List<LogModel> getAllLog() {

       return adaptee.readLogFile();

    }

    public void removeLog(LogModel lm) {

       //1:先读取文件的内容

       List<LogModel> list = adaptee.readLogFile();

       //2:删除相应的日志对象

       list.remove(lm);

       //3:重新写入文件

       adaptee.writeLogFile(list);

    }

    public void updateLog(LogModel lm) {

       //1:先读取文件的内容

       List<LogModel> list = adaptee.readLogFile();

       //2:修改相应的日志对象

       for(int i=0;i<list.size();i++){

           if(list.get(i).getLogId().equals(lm.getLogId())){

              list.set(i, lm);

              break;

           }

       }

       //3:重新写入文件

       adaptee.writeLogFile(list);

    }

}

(2)此时的客户端也需要一些改变,示例代码如下:

public class Client {

    public static void main(String[] args) {

       //准备日志内容,也就是测试的数据

       LogModel lm1 = new LogModel();

       lm1.setLogId("001");

       lm1.setOperateUser("admin");

       lm1.setOperateTime("2010-03-0210:08:18");

       lm1.setLogContent("这是一个测试");

       List<LogModel> list = new ArrayList<LogModel>();

       list.add(lm1);

       //创建操作日志文件的对象

       LogFileOperateApi logFileApi = new LogFileOperate("");

      

       //创建新版的操作日志的接口对象

       LogDbOperateApi api = new Adapter(logFileApi);

      

       //保存日志文件

       api.createLog(lm1);     

       //读取日志文件的内容

       List<LogModel> allLog = api.getAllLog();

       System.out.println("allLog="+allLog);

    }

}

       去运行一下,测试看看是否能满足要求。

(3)小结一下思路

在看完前面的思路和范例代码后,来对这个思路小小总结一下。

①原有文件存取日志的方式,运行得很好,如图4.7所示:

 

图4.7  原有文件存取日志的方式

②现在有了新的基于数据库的实现,新的实现有自己的接口,如图4.8所示:

 

图4.8  新的基于数据库的实现

③现在想要在第二版的实现里面,能够同时兼容第一版的功能,那么就应有一个类来实现第二版的接口,然后在这个类里面去调用已有的功能实现,这个类就是适配器,如下图4.9所示:

 

图4.9  加入适配器的实现结构示意图

上面是分步的思路,现在来看一下前面示例的整体结构,如图4.10所示:

 

图4.10  适配器实现的示例的结构示意图

如同上面的例子,原本新的日志操作接口不能和旧的文件实现一起工作,但是经过适配器适配后,新的日志操作接口就能和旧的文件实现日志存储一起工作了。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics