• 设计模式-适配器模式


    适配器的插头

    我们来看一下适配器的一个简单的代码案例

    package cn.javass.dp.adapter.example1;
    /**
     * 已经存在的接口,这个接口需要被适配
     */
    public class Adaptee {
        /**
         * 示意方法,原本已经存在,已经实现的方法
         */
        public void specificRequest() {
            //具体的功能处理
        }
    }
    package cn.javass.dp.adapter.example1;
    /**
     * 适配器
     */
    public class Adapter implements Target {
        /**
         * 持有需要被适配的接口对象
         */
        private Adaptee adaptee;
        /**
         * 构造方法,传入需要被适配的对象
         * @param adaptee 需要被适配的对象
         */
        public Adapter(Adaptee adaptee) {
            this.adaptee = adaptee;
        }
    
        public void request() {
            //可能转调已经实现了的方法,进行适配
            adaptee.specificRequest();
        }
    }
    package cn.javass.dp.adapter.example1;
    /**
     * 定义客户端使用的接口,与特定领域相关
     */
    public interface Target {
        /**
         * 示意方法,客户端请求处理的方法
         */
        public void request();
    }
    package cn.javass.dp.adapter.example1;
    /**
     * 使用适配器的客户端
     */
    public class Client {    
        public static void main(String[] args) {
            //创建需被适配的对象
            Adaptee adaptee = new Adaptee();
            //创建客户端需要调用的接口对象
            Target target = new Adapter(adaptee);
            //请求处理
            target.request();
        }
    }

    本质上就是对已经存在的功能进行封装,满足客户端心得需求

    我们现在使用一个下面的功能。将日志文件保存到文件中

    package cn.javass.dp.adapter.example2;
    
    import java.io.*;
    
    /**
     * 日志数据对象
     */
    public class LogModel implements Serializable{
        /**
         * 日志编号
         */
        private String logId;
        /**
         * 操作人员
         */
        private String operateUser;
        /**
         * 操作时间,以yyyy-MM-dd HH:mm:ss的格式记录
         */
        private String operateTime;    
        /**
         * 日志内容
         */
        private String logContent;
        
        public String getLogId() {
            return logId;
        }
        public void setLogId(String logId) {
            this.logId = logId;
        }
        public String getOperateUser() {
            return operateUser;
        }
        public void setOperateUser(String operateUser) {
            this.operateUser = operateUser;
        }
        public String getOperateTime() {
            return operateTime;
        }
        public void setOperateTime(String operateTime) {
            this.operateTime = operateTime;
        }
        public String getLogContent() {
            return logContent;
        }
        public void setLogContent(String logContent) {
            this.logContent = logContent;
        }
        
        public String toString(){
            return "logId="+logId+",operateUser="+operateUser+",operateTime="+operateTime+",logContent="+logContent;
        }
    }
    package cn.javass.dp.adapter.example2;
    
    import java.util.List;
    /**
     * 日志文件操作接口
     */
    public interface LogFileOperateApi {
        /**
         * 读取日志文件,从文件里面获取存储的日志列表对象
         * @return 存储的日志列表对象
         */
        public List<LogModel> readLogFile();
        /**
         * 写日志文件,把日志列表写出到日志文件中去
         * @param list 要写到日志文件的日志列表
         */
        public void writeLogFile(List<LogModel> list);
    }
    package cn.javass.dp.adapter.example2;
    
    import java.io.*;
    import java.util.*;
    
    /**
     * 实现对日志文件的操作
     */
    public class LogFileOperate implements LogFileOperateApi{
        /**
         * 日志文件的路径和文件名称,默认是当前classpath下的AdapterLog.log
         */
        private String logFilePathName = "AdapterLog.log";    
        /**
         * 构造方法,传入文件的路径和名称
         * @param logFilePathName 文件的路径和名称
         */
        public LogFileOperate(String logFilePathName) {
            //先判断是否传入了文件的路径和名称,如果是,
            //就重新设置操作的日志文件的路径和名称
            if(logFilePathName!=null && logFilePathName.trim().length()>0){
                this.logFilePathName = logFilePathName;
            }
        }
        public  List<LogModel> readLogFile() {
            List<LogModel> list = null;
            ObjectInputStream oin = null;
            try {
                File f = new File(logFilePathName);
                if(f.exists()){
                    oin = new ObjectInputStream(
                            new BufferedInputStream(new FileInputStream(f))
                    );
                    list = (List<LogModel>)oin.readObject();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }finally{
                try {
                    if(oin!=null){
                        oin.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return list;
        }
    
        public void writeLogFile(List<LogModel> list){
            File f = new File(logFilePathName);
            ObjectOutputStream oout = null;
            try {
                oout = new ObjectOutputStream(
                        new BufferedOutputStream(new FileOutputStream(f))
                );
                oout.writeObject(list);            
            } catch (IOException e) {
                e.printStackTrace();
            }finally{
                try {
                    oout.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    客户端的使用

    package cn.javass.dp.adapter.example2;
    import java.util.*;
    public class Client {
        public static void main(String[] args) {
            //准备日志内容,也就是测试的数据
            LogModel lm1 = new LogModel();
            lm1.setLogId("001");
            lm1.setOperateUser("admin");
            lm1.setOperateTime("2010-03-02 10:08:18");
            lm1.setLogContent("这是一个测试");
            
            List<LogModel> list = new ArrayList<LogModel>();
            list.add(lm1);
    
            //创建操作日志文件的对象
            LogFileOperateApi api = new LogFileOperate(""); 
            //保存日志文件
            api.writeLogFile(list);
            
            //读取日志文件的内容
            List<LogModel> readLog = api.readLogFile();
            System.out.println("readLog="+readLog);
        }
    }

    现在在后面的开发中,我们需要使用数据库的形式来保存日志,最新的保存的日志使用最新的数据库的增加

    删除 更新等四个接口,所以现在存在了两个版本的日志系统,第一个版本是日志文件系统,第二个版本是数据库系统,我们需要实现操作数据库的接口能够实现操作日志

    我们使用适配器的模式来解决下面的代码

    package cn.javass.dp.adapter.example3;
    import java.util.*;
    /**
     * 定义操作日志的应用接口,为了示例的简单,
     * 只是简单的定义了增删改查的方法
     */
    public interface LogDbOperateApi {
        /**
         * 新增日志
         * @param lm 需要新增的日志对象
         */
        public void createLog(LogModel lm);
        /**
         * 修改日志
         * @param lm 需要修改的日志对象
         */
        public void updateLog(LogModel lm);
        /**
         * 删除日志
         * @param lm 需要删除的日志对象
         */
        public void removeLog(LogModel lm);
        /**
         * 获取所有的日志
         * @return 所有的日志对象
         */
        public List<LogModel> getAllLog();
    }
    package cn.javass.dp.adapter.example4;
    
    import java.util.List;
    /**
     * DB存储日志的实现,为了简单,这里就不去真的实现和数据库交互了,示意一下
     */
    public class LogDbOperate implements LogDbOperateApi{
    
        public void createLog(LogModel lm) {
            System.out.println("now in LogDbOperate createLog,lm="+lm);
        }
    
        public List<LogModel> getAllLog() {
            System.out.println("now in LogDbOperate getAllLog");
            return null;
        }
    
        public void removeLog(LogModel lm) {
            System.out.println("now in LogDbOperate removeLog,lm="+lm);
        }
    
        public void updateLog(LogModel lm) {
            System.out.println("now in LogDbOperate updateLog,lm="+lm);
        }
    
    }
    package cn.javass.dp.adapter.example3;
    
    import java.util.List;
    
    /**
     * 适配器对象,把记录日志到文件的功能适配成第二版需要的增删改查的功能
     */
    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);
        }
    }

    客户端的调用

    package cn.javass.dp.adapter.example3;
    import java.util.*;
    public class Client {
        public static void main(String[] args) {
            //准备日志内容,也就是测试的数据
            LogModel lm1 = new LogModel();
            lm1.setLogId("001");
            lm1.setOperateUser("admin");
            lm1.setOperateTime("2010-03-02 10: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);
        }
    }

    这样就是实现采用数据库的方式来适配第一版的日志系统

    适配器的主要功能:

    是复用已经存在的功能,被适配的对象adaptee和需要适配成新的对象Target接口,二者是毫无关系的

  • 相关阅读:
    首页三级菜单显示
    mysql引擎(转)
    nginx配置虚拟主机
    macos10.9 配置nginx,php-fpm
    排序算法 java实现
    Struts清楚session方法
    No result defined for action and result input的错误
    java throw throws
    try catch finally中return语句与非return语句的执行顺序问题
    java操作Excel
  • 原文地址:https://www.cnblogs.com/kebibuluan/p/7259468.html
Copyright © 2020-2023  润新知