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

需求:制作一个日志管理系统,分为2个版本,第一版制作一个将日志存在本地文件的管理系统,第二版制作一个存储在数据库的管理系统,同时,第二版兼容第一版。

优点:可以复用现有功能,无需重新开发。

一、第一版日志系统存储本地

日志domain类

@Data
@Builder
public class LogModel implements Serializable{
    private String logId;
    private String operUser;
    private String operTime;

    @Override
    public String toString() {
        return "LogModel{" +
                "logId='" + logId + '\'' +
                ", operUser='" + operUser + '\'' +
                ", operTime='" + operTime + '\'' +
                ", content='" + content + '\'' +
                '}';
    }
    private String content;
}

日志管理接口

public interface LogFileOperateApi {
    void writeLogFile(List<LogModel> list);
    List<LogModel> readLogFile();
}

日志管理实现类

public class LogFileOperateImpl implements LogFileOperateApi {

    private String logFilePathName = "";

    LogFileOperateImpl(String logFilePathName){
        File file = new File(logFilePathName);
        if(!file.exists()){
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        this.logFilePathName = logFilePathName;
    }

    @Override
    public void writeLogFile(List<LogModel> list) {
        try {
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(new File(logFilePathName)));
            objectOutputStream.writeObject(list);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public List<LogModel> readLogFile() {
        List<LogModel> list = null;
        ObjectInputStream  objectInputStream = null;
        try {
            objectInputStream = new ObjectInputStream(new FileInputStream(new File(logFilePathName)));
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            list = (List<LogModel>) objectInputStream.readObject()  ;
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return list;
    }
}

客户端

public class Client {
    public static void main(String[] args) {
        LogFileOperateApi logFileOperateImpl = new LogFileOperateImpl("d:/1.log");
        List<LogModel> list = new LinkedList<>();
        list.add(LogModel.builder().logId("1").operTime("2900-10-14").operUser("lby").content("hallo").build());
        list.add(LogModel.builder().logId("2").operTime("2900-10-15").operUser("lby").content("hello").build());
        logFileOperateImpl.writeLogFile(list);
        List<LogModel> logModels = logFileOperateImpl.readLogFile();
        System.out.println(logModels);
    }

}

到此,第一版日志系统已经完成。

二、第二版日志系统存储数据库

日志管理接口

public interface LogDbOperateApi {
    void createLog(List<LogModel> list);
    void removeLog(LogModel logModel);
    void updateLog(LogModel logModel);
    List<LogModel> getAllLogs();
}

日志管理实现类(简化了实现过程)

public class LogDbOperateImpl implements  LogDbOperateApi{
    @Override
    public void createLog(List<LogModel> list) {
        System.out.println("DB createLog"+list);
    }

    @Override
    public void removeLog(LogModel logModel) {
        System.out.println("DB removeLog"+logModel);
    }

    @Override
    public void updateLog(LogModel logModel) {
        System.out.println("DB updateLog"+logModel);
    }

    @Override
    public List<LogModel> getAllLogs() {
        System.out.println("DB getAllLogs");
        return null;
    }
}

客户端测试

public class Client {
    public static void main(String[] args) {
        LogDbOperateApi logDbOperateApi = new LogDbOperateImpl();
        List <LogModel> list = new ArrayList<>();
        list.add(LogModel.builder().content("test").build());
        logDbOperateApi.createLog(list);
        logDbOperateApi.removeLog(LogModel.builder().content("test").build());
        logDbOperateApi.updateLog(LogModel.builder().content("test").build());
        logDbOperateApi.getAllLogs();
    }
}

三、第二版日志管理系统也开发好了,这个时候客户需要第二版的管理系统兼容第一版。

改造:无需重新开发支持第一版,引入adapter利用现有的LogFileOperateApi接口,转化为LogDbOperateApi接口。

public class Adapter implements LogDbOperateApi {

    LogFileOperateApi logFileOperateApi;

    Adapter(LogFileOperateApi logFileOperateApi){
        this.logFileOperateApi = logFileOperateApi;
    }
@Override
public void createLog(List<LogModel> list) { logFileOperateApi.writeLogFile(list); }
@Override
public void removeLog(LogModel logModel) { List<LogModel> list = logFileOperateApi.readLogFile(); list.forEach(item->{ logModel.getLogId().equals(item.getLogId()); list.remove(item); }); logFileOperateApi.writeLogFile(list); }
@Override
public void updateLog(LogModel logModel) { List<LogModel> list = logFileOperateApi.readLogFile(); list.forEach(item->{ logModel.getLogId().equals(item.getLogId()); list.remove(item); }); list.add(logModel); logFileOperateApi.writeLogFile(list); }
@Override
public List<LogModel> getAllLogs() { return logFileOperateApi.readLogFile(); } }

客户端测试 

public class Client {
    public static void main(String[] args) {
        LogFileOperateApi logFileOperateImpl = new LogFileOperateImpl("d:/1.log");
        LogDbOperateApi logDbOperateApi = new Adapter(logFileOperateImpl);
        System.out.println(logDbOperateApi.getAllLogs());
        logDbOperateApi.updateLog(LogModel.builder().logId("1").operTime("6666-10-14").operUser("lby").content("hallo").build());
        System.out.println(logDbOperateApi.getAllLogs());
    }
}

四、双向兼容

已经完成了第二版日志管理系统兼容第一版,继续改造,利用双向适配器将系统改造成,两个版本相互兼容。

public class TwoDeriectApater implements LogDbOperateApi,LogFileOperateApi {

    private LogDbOperateApi logDbOperateApi;

    private LogFileOperateApi logFileOperateApi;

    public TwoDeriectApater(LogDbOperateApi logDbOperateApi,LogFileOperateApi logFileOperateApi){
        this.logDbOperateApi = logDbOperateApi;
        this.logFileOperateApi = logFileOperateApi;
    }

    /**
     *
     * --------------以下为第二版兼容第一版部分----------
     */

    @Override
    public void createLog(List<LogModel> list) {
        logFileOperateApi.writeLogFile(list);
    }

    @Override
    public void removeLog(LogModel logModel) {
        List<LogModel> list = logFileOperateApi.readLogFile();
        list.forEach(item->{
            logModel.getLogId().equals(item.getLogId());
            list.remove(item);
        });
        logFileOperateApi.writeLogFile(list);
    }

    @Override
    public void updateLog(LogModel logModel) {
        List<LogModel> list = logFileOperateApi.readLogFile();
        list.forEach(item->{
            logModel.getLogId().equals(item.getLogId());
            list.remove(item);
        });
        list.add(logModel);
        logFileOperateApi.writeLogFile(list);
    }

    @Override
    public List<LogModel> getAllLogs() {
        return logFileOperateApi.readLogFile();
    }

    /**
     * 
     * --------------以下为第一版兼容第二版部分----------
     */

    @Override
    public void writeLogFile(List<LogModel> list) {
        logDbOperateApi.createLog(list);
    }

    @Override
    public List<LogModel> readLogFile() {
        return logDbOperateApi.getAllLogs();
    }
}

客户端测试  

public class Client {
    public static void main(String[] args) {
        LogFileOperateApi logFileOperateImpl = new LogFileOperateImpl("d:/1.log");
        LogDbOperateApi logDbOperateImpl = new LogDbOperateImpl();
        LogFileOperateApi fileApi = new TwoDeriectApater(logDbOperateImpl,logFileOperateImpl);
        LogDbOperateApi dbApi = new TwoDeriectApater(logDbOperateImpl,logFileOperateImpl);

        List<LogModel> list = new LinkedList<>();
        list.add(LogModel.builder().logId("1").operTime("8888-10-14").operUser("lby").content("hallo").build());
        list.add(LogModel.builder().logId("2").operTime("2222-10-15").operUser("lby").content("hello").build());
        dbApi.createLog(list);
        System.out.println(dbApi.getAllLogs());

        System.out.println(fileApi.readLogFile());
    }

}

猜你喜欢

转载自www.cnblogs.com/liuboyuan/p/9611045.html