码迷,mamicode.com
首页 > 其他好文 > 详细

设计模式学习笔记------适配器模式

时间:2018-01-02 18:43:48      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:param   结构   路径   output   buffere   情况下   不同   方式   adl   

              适配器模式

一、适配器模式

1.适配器模式结构图

技术分享图片

                    技术分享图片

技术分享图片

 

 2.适配器模式示例代码

 1 (1)先看看Target接口定义的示例代码如下
 2 /** 
 3  * 定义客户端使用的接口,与特定领域相关
 4  */
 5 public interface Target {
 6     /**
 7      * 示意方法,客户端请求处理方法
 8      */
 9     public void request();
10 }
11 (2)再看看需要被适配的对象定义。示例代码如下:
12 /**
13  * 已经存在的接口,这个接口需要配适配
14  */
15 public class Adaptee{
16     /**
17      * 示意方法,原本已经存在,已经实现的方法
18      */
19     public void specificRequest() {
20         //具体的功能处理
21     }
22 }
23 
24 (3)下面是适配器对象的基本实现。示例代码如下:
25 /**
26  * 适配器
27  */
28 public class Adapter implements Target {
29     /**
30      * 持有需要被适配的接口对象
31      */
32     private Adaptee adaptee;
33     
34     /**
35      * 构造方法,传入需要被适配的对象
36      * @param adaptee
37      */
38     public Adapter(Adaptee adaptee) {
39         this.adaptee = adaptee;
40     }
41     
42     @Override
43     public void request() {
44         //可能转调已经实现了的方法,进行适配
45         adaptee.specificRequest();
46     }
47     
48 }
49 
50 (4)再来看看使用适配器客户端的示例代码如下:
51 /**
52  * 使用适配器的客户端
53  */
54 public class Client {
55     public static void main(String[] args) {
56         //创建需要被适配的对象
57         Adaptee adaptee = new Adaptee();
58         //创建客户端需要调用的接口对象
59         Target target = new Adapter(adaptee);
60         //请求处理
61         target.request();
62     }
63 }

二、具体实现代码---日志管理

  需求一:用户要求日志以文件的形式记录。

  1 /**
  2  * 日志数据对象
  3  * @author abc
  4  *
  5  */
  6 public class LogModel implements Serializable {
  7     private static final long serialVersionUID = 1L;
  8     
  9     /**
 10      * 日志编号
 11      */
 12     private String logId;
 13     /**
 14      * 操作人员
 15      */
 16     private String operateUser;
 17     /**
 18      * 操作时间,以yyyy-MM-dd HH:mm:ss的格式记录
 19      */
 20     private String operateTime;
 21     /**
 22      * 日志内容
 23      */
 24     private String logContent;
 25     public String getLogId() {
 26         return logId;
 27     }
 28     public void setLogId(String logId) {
 29         this.logId = logId;
 30     }
 31     public String getOperateUser() {
 32         return operateUser;
 33     }
 34     public void setOperateUser(String operateUser) {
 35         this.operateUser = operateUser;
 36     }
 37     public String getOperateTime() {
 38         return operateTime;
 39     }
 40     public void setOperateTime(String operateTime) {
 41         this.operateTime = operateTime;
 42     }
 43     public String getLogContent() {
 44         return logContent;
 45     }
 46     public void setLogContent(String logContent) {
 47         this.logContent = logContent;
 48     }
 49     @Override
 50     public String toString() {
 51         return "logId=" + logId + ", operateUser=" + operateUser + ", operateTime=" + operateTime
 52                 + ", logContent=" + logContent;
 53     }
 54     
 55     
 56 }
 57 
 58 /**
 59  * 日志文件操作接口
 60  * @author abc
 61  *
 62  */
 63 public interface LogFileOperate {
 64     
 65     /**
 66      * 读取日志文件,从文件里面获取存储的日志列表对象
 67      * @return 存储的日志列表对象
 68      */
 69     public List<LogModel> readLogFile();
 70     
 71     /**
 72      * 写日子文件,把日志列表写出到日志文件中
 73      * @param list 要写到日志文件的日志列表
 74      */
 75     public void writeLogFile(List<LogModel> list);
 76     
 77 }
 78 
 79 /**
 80  * 日志文件操作接口实现
 81  * @author abc
 82  *
 83  */
 84 public class LogFileOperateImpl implements LogFileOperate {
 85     
 86     /**
 87      * 日志文件的路径和文件名称,默认是当前项目根路劲下的AdapterLog.log
 88      */
 89     private String logFilePathName = "AdapterLog.log";
 90     
 91     /**
 92      * 构造方法,传入文件的路径和名称
 93      * @param logFilePathName 文件路径和名称
 94      */
 95     public LogFileOperateImpl(String logFilePathName) {
 96         if (logFilePathName != null && logFilePathName.trim().length() > 0) {
 97             //判断是否传入了文件的路径和名称,传入就重置路径和名称
 98             this.logFilePathName = logFilePathName;
 99         }
100     }
101 
102     @Override
103     public List<LogModel> readLogFile() {
104         List<LogModel> list = null;
105         ObjectInputStream oin = null;
106         try {
107             File f = new File(logFilePathName);
108             if (f.exists()) {
109                 oin = new ObjectInputStream(new BufferedInputStream(new FileInputStream(f)));
110                 list = (List<LogModel>)oin.readObject();
111             }
112         } catch (Exception e) {
113             // TODO Auto-generated catch block
114             e.printStackTrace();
115         } finally {
116             try{
117                 if (oin != null) {
118                     oin.close();
119                     oin = null;
120                 }
121             } catch (IOException e) {
122                 e.printStackTrace();
123             }
124         }
125         return list;
126     }
127 
128     @Override
129     public void writeLogFile(List<LogModel> list) {
130         File f = new File(logFilePathName);
131         ObjectOutputStream oos = null;
132         try {
133             oos = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(f)));
134             oos.writeObject(list);
135         }  catch (IOException e) {
136             // TODO Auto-generated catch block
137             e.printStackTrace();
138         } finally {
139             try {
140                 if (oos != null) {
141                     oos.close();
142                     oos = null;
143                 }
144             } catch (IOException e) {
145                 // TODO Auto-generated catch block
146                 e.printStackTrace();
147             }
148         }
149 
150     }
151 
152 }
153 
154 /**
155  * 客户端测试
156  * @author abc
157  *
158  */
159 public class Client {
160     public static void main(String[] args) {
161         //准备日志内容,测试的数据
162         LogModel model = new LogModel();
163         model.setLogId("002");
164         model.setOperateUser("admin1");
165         model.setOperateTime("2018-01-02 16:16:00");
166         model.setLogContent("这是一个测试");
167         
168         List<LogModel> list = new ArrayList<LogModel>();
169         list.add(model);
170         //创建操作日志文件的对象
171         LogFileOperate logFileOperate = new LogFileOperateImpl("");
172         //保存日志文件
173         logFileOperate.writeLogFile(list);
174         
175         //读取日子文件的内容
176         List<LogModel> readLog = logFileOperate.readLogFile();
177         System.out.println("readLog=" + readLog);
178         
179     }
180 }

  需求二:用户要求日志以数据库的形式管理日志。

/**
 * 定义操作的应用接口
 * @author abc
 *
 */
public interface LogDbOperate {
    
    /**
     * 新增日志
     * @param model 需要新增的日志对象
     */
    public void createLog(LogModel model);
    /**
     * 修改日志
     * @param model 需要修改的日志对象
     */
    public void updateLog(LogModel model);
    /**
     * 删除日志
     * @param model 需要删除的日志对象
     */
    public void removeLog(LogModel model);
    /**
     * 获取所有的日志
     * @return 所有日志对象集合
     */
    public List<LogModel> getAllLog();
}

/**
 * 定义操作的应用接口实现类
 * @author abc
 */
public interface LogDbOperateImpl {
        //具体实现内容      
}

/**
 * 客户端测试
 * @author abc
 *
 */
public class Client {
    public static void main(String[] args) {
        //准备日志内容,测试的数据
        LogModel model = new LogModel();
        model.setLogId("002");
        model.setOperateUser("admin1");
        model.setOperateTime("2018-01-02 16:16:00");
        model.setLogContent("这是一个测试");
        
        List<LogModel> list = new ArrayList<LogModel>();
        list.add(model);
        //创建操作日志文件的对象
        LogFileOperate logFileOperate = new LogFileOperateImpl("");
        
        LogDbOperate logDbOperate  = new Adapter(logFileOperate);
        //保存日志文件
        logDbOperate.createLog(model);
        //读取日志文件的内容
        List<LogModel> allLog = logDbOperate.getAllLog();
        System.out.println("allLog=" + allLog);
    }
}

思路总结:

1.原有存取日志的方式

技术分享图片

 

2.现在有了新的基于数据库的实现,新的实现由自己的接口

技术分享图片

 

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

技术分享图片

 

 

整体结构

 技术分享图片

三、认识适配器模式

  1.模式的功能

    适配器模式的主要功能是进行转换匹配,目的是复用已有的功能,而不是来实现新的接口。也就是说,客户端需要的功能应该是已经实现好了的,不需要适配器模式来实现,适配器模式主要负责把不兼容的接口转换成客户端期望的样子就可以了。

    但这并不是说,在适配器里面就不能实现功能。适配器里面可以实现功能,称这种适配器为智能适配器。再说了,在接口匹配和转换的过程中,也有可能需要额外实现一定的功能,才能转换过来,比如需要调整参数以进行匹配等。

  2.Adaptee 和 Target 的关系

    适配器模式中被适配的接口Adaptee和适配成为的接口Target是没有关联的,也就是说,Adaptee和Target中的方法既可以相同,也可以不同。极端情况下两个接口里面方法可能完全不同的,当然这种情况下也可以完全相同。

    这里所说的相同和不同,是指方法定义的名称、参数列表、返回值,以及方法本省的功能都可以相同或不同。    

  3.对象组合

    根据前面的实现,你会发现,适配器的实现方式其实是依靠对象组合的方式。通过给适配器对象组合被适配的对象,然后当客户端调用Targer的时候,适配器会吧相应的功能委托给适配的对象去完成。

  4.适配器模式的调用顺序示意图

   技术分享图片

 

设计模式学习笔记------适配器模式

标签:param   结构   路径   output   buffere   情况下   不同   方式   adl   

原文地址:https://www.cnblogs.com/chensheng0617/p/8178359.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!