适配器模式
定义
将一个类的接口转换成客户希望的另外一个接口,适配器模式使得原本由于接口不兼容而不能一起工作的哪些类可以一起工作。
结构与说明
Client:客户端,调用自己需要的领域接口Target。
Target:定义客户端需要的跟特点领域相关的接口
Adaptee:已经存在的接口,但与客户端要求的特点领域接口不一致,需要适配。
Adapter:适配器,把Adaptee适配成Client需要的Target。
.举例:转接线、插口槽
public interface Target {
public void request();
}
public class Adaptee {
public void specificRequest(){
System.out.println("适配成功");
}
}
public class Adapter implements Target{
private Adaptee adaptee;
public Adapter(Adaptee adaptee){
this.adaptee=adaptee;
}
@Override
public void request() {
adaptee.specificRequest();
}
}
public class Client {
public static void main(String[] args) {
Adaptee adaptee = new Adaptee();
Target target = new Adapter(adaptee);
target.request();
}
}
体会模式
同时支持数据库和文件的日志的管理
1、日志第一版
使用Io流读写
2、日志第二版
使用数据库读写
代码
public class LogModel implements Serializable {
private String logId;
private String operateUser;
private String operateTime;
private String logContent;
public LogModel() {
}
public LogModel(String logId, String operateUser, String operateTime, String logContent) {
this.logId = logId;
this.operateUser = operateUser;
this.operateTime = operateTime;
this.logContent = 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;
}
@Override
public String toString() {
return "LogModel{" +
"logId='" + logId + '\'' +
", operateUser='" + operateUser + '\'' +
", operateTime='" + operateTime + '\'' +
", logContent='" + logContent + '\'' +
'}';
}
}
public interface LogOperateApi {
public List<LogModel> readLogFile();
public void writeLogFile(List<LogModel> list);
}
/**
* 模拟数据库接口
*/
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();
}
public class LogFileOperate implements LogOperateApi{
String LogFilePathName = "E:\\data\\log1.log";
public LogFileOperate(){
}
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 (IOException | ClassNotFoundException e) {
e.printStackTrace();
}finally {
try {
if(oin != null){
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 (IOException e) {
e.printStackTrace();
}finally {
try {
oout.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 适配器对象,把记录日志到文件的功能适配成第二版需要的增查删改功能
*/
public class Adapter {
/**
* 持有需要被适配的接口对象
*/
private LogFileOperate adaptee;
public Adapter(LogFileOperate adaptee){
this.adaptee=adaptee;
}
public void createLog(LogModel lm){
//读取文件内容
List<LogModel> list = adaptee.readLogFile();
//加入日志对象
list.add(lm);
//重新写入文件
adaptee.writeLogFile(list);
}
public List<LogModel> getAllLog(){
return adaptee.readLogFile();
}
public void removeLog(LogModel lm){
//读取文件内容
List<LogModel> list = adaptee.readLogFile();
//删除相应的日志对象
list.remove(lm);
//重新写入文件
adaptee.writeLogFile(list);
}
public void updateLog(LogModel lm){
//读取文件内容
List<LogModel> list = adaptee.readLogFile();
//修改相应的日志对象
for (int i=0;i<list.size();i++){
if(list.get(i).getLogId().equals(lm.getLogId())){
list.set(i,lm);
break;
}
}
adaptee.writeLogFile(list);
}
}
public class Client {
public static void main(String[] args) {
LogModel logModel =new LogModel();
logModel.setLogId("1");
logModel.setOperateUser("xxx");
logModel.setOperateTime("2020/5/8 6:45:20");
logModel.setLogContent("登录操作");
List<LogModel> list = new ArrayList<LogModel>();
list.add(logModel);
LogOperateApi logOperateApi = new LogFileOperate();
logOperateApi.writeLogFile(list);
List<LogModel> readLog = logOperateApi.readLogFile();
System.out.println("readLog"+readLog);
LogFileOperate logFileOperate = new LogFileOperate("");
LogDbOperateApi logDbOperateApi = (LogDbOperateApi) new Adapter(logFileOperate);
logDbOperateApi.createLog(logModel);
List<LogModel> allLog =logDbOperateApi.getAllLog();
System.out.println("allLog="+allLog);
}
}
功能
1、主要功能是进行转换匹配,目的是复用已有的功能,而不是实现新的接口。适配器里面也可以实现功能,称这种适配器为智能适配器。
2、Adaptee和Target没有关联关系
3、适配器的实现方式其实是依靠对象组合的方式
实现
1、适配器通常是一个类,一般会让适配器去实现Target接口,然后在适配器中调用Adaptee。
2、智能适配器:适配器实现里加入新功能的实现
3、适配多个Adaptee
4、适配器Adapter实现的复杂程度,取决于Target和Adaptee的相似程度
5、缺省适配:为一个接口提供缺省实现