引出:组装电脑例子,向电脑加入新硬盘,但电源和新的硬盘的电源接口不同,该如何?采用一个转换线,将电源的接口适配成为新的硬盘所需要的接口,那么这个转换线就是-----适配器(adapter)。还比如各种管道的转接头、不同制式的插座等。
notusingMode包里是日志的第一版,将日志保存在文件里,notusingMode2是日志的第二版,将日志保存在数据库中
package notusingMode;
import java.io.Serializable;
/*
* 日志对象模型,描述日志的,这个对象需要被写入文件,需要序列化
*/
public class LogModel implements Serializable {
private String logId; // 日志编号
private String operateUser; // 操作人员
private String operateTime; // 操作时间,以yyyy-MM-dd HH:mm:ss格式记录
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 notusingMode;
import java.util.List;
/*
* 操作日志文件的接口
*/
public interface LogFileOperateApi {
//读取日志文件,从文件里面获取存储的日志列表对象
public List<LogModel> readLogFile();
//写日志,将日志列表写出到日志文件中去。
public void writeLogFile(List<LogModel> list);
}
package notusingMode;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.List;
/*
* 将日志保存到文件中去,并能从文件中把日志内容读取出来
*/
public class LogFileOperate implements LogFileOperateApi {
private String logFilePathName = "AdapterLog.log"; //日志文件路径和名称,默认在当前根目录下的
public LogFileOperate(String logFilePathName) { //构造方法,传入文件的路径和名称
if(logFilePathName!=null&&logFilePathName.trim().length()>0)
this.logFilePathName = logFilePathName;
}
@Override
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 (SecurityException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
finally{
if(oin!=null)
try {
oin.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return list;
}
@Override
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 (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
finally{
if(oout!=null)
try {
oout.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
package notusingMode;
import java.util.ArrayList;
import java.util.List;
//日志第一版,将日志写入文件
public class Client {
public static void main(String[] args) {
// 准备日志内容,即测试数据
LogModel lm1 = new LogModel();
lm1.setLogId("001");
lm1.setLogContent("这是一个测试");
lm1.setOperateTime("2011-03-23 14:32:40");
lm1.setOperateUser("Sunflower");
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 notusingMode1;
import java.util.List;
import notusingMode.LogModel;
public interface LogDbOperateApi {
public void createLog(LogModel lm);
public void updateLog(LogModel lm);
public void deleteLog(LogModel lm); //删除日志
public List<LogModel> getAllLog(); //获取所有日志
}
package notusingMode1;
import java.util.List;
import notusingMode.LogModel;
//日志的第二种保存方法
public class LogDbOperate implements LogDbOperateApi {
@Override
public void createLog(LogModel lm) {
}
@Override
public void deleteLog(LogModel lm) {
}
@Override
public List<LogModel> getAllLog() {
return null;
}
@Override
public void updateLog(LogModel lm) {
}
}
现在需要让日志管理第二版同时支持数据库和文件存储两种方式,怎么办??第二版的接口和第一版的接口不同,直接修改第一版,可能导致
其他依赖于第一版的应用不能运行。。。-------》适配器模式解决
定义:将一个类的接口转换成客户希望的另外一个接口。
上述问题只要将两边的接口匹配起来,就可以复用第一版的功能了。
按照适配器模式的实现方式,可以定义一个类来实现第二版的接口,然后在其内部实现的时候,转调第一版已经实现了的功能,完成上述工作的类就是适配器。
适配器结构中有:
Client:客户端,调用自己需要的领域接口Target。
Target:定义客户端需要的跟特定领域相关的接口。
Adaptee:已经存在的接口,通常能满足客户需要(其实现类),但是接口和要求的特定领域的接口不一致,需要被适配
Adapter:适配器,将Adaptee适配成Client需要的Target。它是一个类,实现了Target接口,并在其内部转调Adaptee的功能.
package adapter;
public class Adaptee {
public void specificRequest(){
//具体的功能处理
};
}
package adapter;
public class Adapter implements Target {
private Adaptee adaptee; //持有需要被适配的接口对象
@Override
public void request() {
//可能转调已经实现的方法,进行适配
adaptee.specificRequest();
}
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
}
package adapter;
public class Client {
public static void main(String[] args) {
//创建需要被适配的对象
Adaptee adaptee = new Adaptee();
// 利用适配器创建客户需要的接口对象
Target target = new Adapter(adaptee);
//请求处理
target.request();
}
}
package adapter;
public interface Target {
public void request();
}
适配器模式主要功能进行转换匹配,以复用已有的功能,而不是实现新的接口。
适配器模式的实现:
1,常见实现,适配器是一个类,一般让适配器类去实现Target接口,然后在其具体实现里面调用adaptee。
2,可以适配多个adaptee,双向适配器,前面是把Adaptee适配成为Target,其实也可以将Target适配成Adaptee。它同时实现了Target和Adapteee接口
适配器分类:类适配器和对象适配器
对象适配器就是前面的实现示例,采用对象组合的方式。
类适配器的实现,采用多重继承对一个接口与另一个接口进行匹配。由于java不支持多继承,所以到目前为止还没有涉及。但可以通过实现Target接口,然后继承Adaptee的实现,来实现类似类适配器。
适配器优缺点
更好的复用性,如果功能已经有了,只是接口不兼容,可以使用适配器让这些功能更好的复用
但过多的使用适配器,会让系统非常凌乱,不容易整体进行把握。例如明明看到调用的是A接口,其实内部被适配成了B接口来实现。
本质:转换匹配,复用功能
分享到:
相关推荐
设计模式之 适配器 Adapter C++ 源码 vs2019 工具,设计模式之 适配器 Adapter C++ 源码 vs2019 工具,设计模式之 适配器 Adapter C++ 源码 vs2019 工具,设计模式之 适配器 Adapter C++ 源码 vs2019 工具,设计模式...
在这个“适配器模式demo源码”中,我们可以深入理解这一模式的实现方式及其应用场景。 适配器模式的核心思想是将一个类的接口转换成客户期望的另一个接口,使得原本由于接口不兼容而不能一起工作的类可以协同工作。...
适配器模式是一种软件设计模式,它允许两个不兼容的接口之间进行通信。在软件工程中,当系统中存在两种不兼容的接口或者类需要协同工作时,适配器模式可以发挥关键作用。通过适配器,我们可以复用现有的类,而无需...
适配器模式(Adapter Pattern)是软件设计模式中的一种,其主要目的是解决系统中的接口不兼容问题,使得原本由于接口不匹配而无法一起工作的类能够协同工作。在本文中,我们将深入探讨适配器模式的概念、结构、作用...
在`DesignMode_Adapter`这个压缩包文件中,可能包含了相关的C++源码示例,演示了如何创建和使用适配器模式。这些源码可能包括了目标接口、原始接口、适配器类的定义以及客户端如何通过适配器进行调用的示例。通过...
在提供的博客链接中,作者详细分析了适配器模式的源码,包括类适配器和对象适配器的实现,以及如何在实际项目中应用这些模式。 适配器模式有助于提高代码的灵活性和可扩展性,降低了系统之间的耦合度,使得系统的...
适配器模式的核心概念包括三部分:目标(Target)、适配者(Adaptee)和适配器(Adapter)。目标是客户端期望调用的接口,适配者是需要被适配的对象,而适配器则是连接目标和适配者的桥梁,它实现了目标接口,并通过...
适配器模式(Adapter Pattern)是软件设计模式中的一种,其主要目的是使两个不兼容的接口之间能够协同工作。在IT行业中,我们经常遇到不同系统、库或组件之间的接口不一致,导致它们无法直接交互。适配器模式就提供...
标题“设计模式之适配器Adapter”暗示我们将深入探讨适配器模式的核心概念和应用场景。适配器模式通常应用于以下场景: 1. 当系统中存在一个已经存在的类,其接口不符合新需求时,可以使用适配器模式来调整接口,使...
在软件设计模式中,Adapter(适配器)模式是一种常用的设计模式,它的主要作用是将两个不兼容的接口之间进行适配,使得原本无法协同工作的类可以一起工作。适配器模式可以分为类适配器模式和对象适配器模式。在这里...
在Android开发中,ListView和RecyclerView的Adapter也是适配器模式的典型应用,它们使得各种数据源可以被视图组件正确地显示。 文件"适配器模式-概念图.pdf"可能包含了适配器模式的可视化表示,帮助理解各个角色...
通过阅读和理解这些源码,我们可以学习到如何在实际项目中实现适配器模式,包括如何定义适配接口、如何创建适配器类、如何处理适配者类的接口,以及如何在客户端代码中正确地使用适配器。 适配器模式不仅提高了代码...
适配器模式是一种软件设计模式,它允许两个不兼容的接口之间进行通信。在软件工程中,当系统中存在一个已经存在的组件,但其接口不符合当前项目的需求时,适配器模式就能发挥作用。通过适配器,我们可以复用现有的...
总结来说,"adapter_C++_adapter_源码"项目提供了C++实现的适配器模式示例,通过适配器类将不兼容的接口转换为客户期望的接口,从而实现系统的集成和扩展。深入研究这个源码可以帮助我们更好地理解和应用适配器模式...
适配器模式(Adapter Pattern)是其中的一种,它允许两个不兼容的接口之间进行通信,通过创建一个适配器类来将原有接口转换成目标接口,使得原本不能一起工作的类可以协同工作。 适配器模式分为类适配器和对象...
在 Java 开发中,适配器模式(Adapter Pattern)是一种非常有用的结构型设计模式,它可以帮助我们解决接口不兼容的问题,实现不同类之间的无缝集成。本文将详细介绍适配器模式的意图、解释、编程示例、适用场景、...
3. 适配器(Adapter):适配器实现了目标接口,同时持有原始类的一个引用,它将原始类的接口转换成目标接口,从而使客户端可以调用。 适配器模式的优点包括: 1. 提高代码的复用性:适配器模式使得我们可以继续使用...