MyBatis source depth understanding of Java Design Patterns adapter mode

What is the adapter mode

Definition: The interface converter of a system into another form, so that the interface can not directly call the original call becomes possible.

Adapter mode of roles

适配器模式涉及3个角色:
1.源(Adaptee):需要被适配的对象或类型,相当于插头。
2.适配器(Adapter):连接目标和源的中间对象,相当于插头转换器。
3.目标(Target):期待得到的目标,相当于插座。
适配器模式包括3种形式:类适配器模式、对象适配器模式、接口适配器模式(或又称作缺省适配器模式)。

Adapter mode scenario

1、新老版本接口的兼容
2、Mybatis多种日志框架的整合

Way adapter created 

1.对象适配器(组合模式)
2.类适配器(继承模式)

Adapter Quick Start example

For example, an early version of the order when V1 interface to the Senate for the Map type, with business updates and iterations of the order interface to the Senate need to support the type of List in V2 version of the time? In the case of the interface code Does not change, how to support the List type.

1. Source (Adaptee): the type of object or needs to be adapted, corresponding to the plug.

public void froOrderMap(Map map) { for (int i = 0; i < map.size(); i++) { // 使用I作为MapKey获取数据 String value = (String) map.get(i); System.out.println("value:" + value); } } 

2. Objectives (Target): looking forward to get the goal, the equivalent of the socket.

public interface List<E> extends Collection<E> { ...... int size(); E get(int index); E set(int index, E element); } 

3. Adapter (Adapter): and an intermediate connection target object sources, corresponding to plug adapter

public class ListAdapter extends HashMap { private List list; public ListAdapter(List list) { this.list = list; } @Override public int size() { return list.size(); } @Override public Object get(Object key) { return list.get(Integer.valueOf(key.toString()).intValue()); } }

Test run results

public class Test {
    public static void main(String[] args) { // 1.获取集合类型用户 List member = new MemberService().getMember(); //new OrderService().froOrderMap(member); ListAdapter listAdapter = new ListAdapter(member); new OrderService().froOrderMap(listAdapter); } } 

Use adapter model to achieve log collection

 For example, designing a log collection system, you may consider written documents may also consider written MQ, may also be considered for inclusion in databases.

Object Adapter manner

Defines the basic entity class

@Data
public class LogBean {
    /** * 日志ID */ private String logId; /** * 日志内容 */ private String logText; }

1. Source Destination Interface

public interface LogWriteFileService {

    /**
     * 将日志写入到文件中
     */
    void logWriteFile(); /** * 从本地文件中读取日志 * * @return */ List<LogBean> readLogFile(); } 

1. Source Destination interface class

public class LogWriteFileServiceImpl implements LogWriteFileService { @Override public void logWriteFile(www.yuntianyuL.cn) { System.out.println(">>>将日志写入文件中..."); } @Override public List<LogBean> readLogFile(www.shengdaptd.cn) { LogBean log1 = new LogBean(); log1.setLogId("0001"); log1.setLogText("Tomcat启动成功.."); LogBean log2 = new LogBean(); log2.setLogId("0002"); log2.setLogText("Jetty启动成功..www.xinhezaixia.cn"); List<LogBean> listArrayList = new ArrayList<LogBean>(); listArrayList.add(log1); listArrayList.add(log2); return listArrayList; } } 

2. Target Interface

public interface LogWriteDbService {

    /**
     * 将日志写入到数据库中
     */
   public void writeDbFile(LogBean logBean); } 

2. Adapter

//LogAdapter :适配器
//LogWriteDbService:目标
public class LogAdapter implements LogWriteDbService { //源接口 private LogWriteFileService logWriteFileService; public LogAdapter(LogWriteFileService logWriteFileService) { this.logWriteFileService www.oushengyule.com= logWriteFileService; } @Override public void writeDbFile(LogBean logBean) { // 1.从文件中读取日志文件 List<LogBean> logBeans = logWriteFileService.readLogFile(); //目标 // 2.写入到数据库中 logBeans.add(logBean); System.out.println(">>>将数据写入到数据库中.."); // 3.写入到本地文件中 logWriteFileService.logWriteFile(); } } 

Adapter mode advantages and disadvantages

适配器模式的优点
  更好的复用性 
系统需要使用现有的类,而此类的接口不符合系统的需要。那么通过适配器模式就可以让这些功能得到更好的复用。 
更好的扩展性 
在实现适配器功能的时候,可以调用自己开发的功能,从而自然地扩展系统的功能。 

适配器模式的缺点
  过多的使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是A接口,其实内部被适配成了B接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。

Mbatis log collection and analysis

Java开发中经常用到的日志框架有很多,Log4j、Log4j2、slf4j等等,Mybatis定义了一套统一的日志接口供上层使用,并为上述常用的日志框架提供了相应的适配器 在Mybatis的日志模块中就是使用了适配器模式。Mybatis内部在使用日志模块时,使用了其内部接口 org.apache.ibatis.logging.Log,但是常用的日志框架的对外接口各不相同,Mybatis为了复用和集成这些第三方日志组件,在其日志模块中,提供了多种Adapter,将这些第三方日志组件对外接口适配成org.apache.ibatis.logging.Log,这样Myabtis 就可以通过Log接口调用第三方日志了 

Source code analysis chart

Source analysis

Mybatis Log Interface: corresponding to the source interface

package org.apache.ibatis.logging;

public interface Log { boolean isDebugEnabled(); boolean isTraceEnabled(); void error(String s,www.meiwanyule.cn Throwable e); void error(String s); void debug(String s); void trace(String s); void warn(String s); }

Source interface implementation class Mybatis

The first adapter

package org.apache.ibatis.logging.slf4j;

import org.apache.ibatis.www.chengmyuLegw.cn logging.Log;
import org.slf4j.Logger;

//Slf4jLoggerImpl :相当于适配器
//Log :相当于源接口 class Slf4jLoggerImpl implements Log { //Logger:相当于目标接口 private Logger log; public Slf4jLoggerImpl(Logger logger) { //源=目标 log = logger; }

The second adapter

package org.apache.ibatis.logging.log4j2;

import org.apache.ibatis.www.tdcqgw.cn logging.Log;
import org.apache.logging.www.yongshi123.cn log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.spi.AbstractLogger; //Log4j2Impl :相当于适配器 //Log :相当于源接口 public class Log4j2Impl implements Log { private Log log; //构造器 public Log4j2Impl(String clazz) { //目标接口 Logger logger = LogManager.getLogger(clazz); //判断类型去实现:相当于目标 if (logger instanceof AbstractLogger) { log = new Log4j2AbstractLoggerImpl((AbstractLogger) logger); } else { //源=目标 log = new Log4j2LoggerImpl(logger); } }

Destination Interface: Logger

 

Guess you like

Origin www.cnblogs.com/qwangxiao/p/10942996.html