Mybatis学习笔记六之设计模式

一、设计模式

        在软件工程领域,设计模式是一套通用的可复用的解决方案,用来解决在软件设计过程中产生的通用问题。它不是一个可以直接转换成源代码的设计,只是一套在软件系统设计过程中程序员应该遵循的最佳实践准则。

Mybatis源码中使用了大量的设计模式,通过观察设计模式在源码中的应用,能够更深入的理解设计模式。

Mybatis学习笔记六之设计模式_第1张图片

结合前面源码的分析,我们这里只介绍Build构建者模式、工厂模式和代理模式。

1,Build构建者模式

        Builder构建者模式指:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。它属于创建类模式,一般来说,如果一个对象的构建比较复杂,超出了构造函数所能包含的范围,就可以使用工厂模式和Build构建模式。相对于工厂模式会产出一个完整的产品,Build应用于更加复杂的对象的构建,甚至只会构建产品的一个部分,直白来说,就是使用多个简单的对象一步一步构建成一个复杂的对象。

例子:使用构建者模式来生产Computer。主要步骤:

(1)将需要构建的目标类分成多个部件(电脑可以分成主机、显示器、键盘、音响等)。

(2)创建构建类

(3)依次创建部件

(4)将部件组装成目标对象

目标对象Computer(一般来说这里面包含的也是对象,我们就全部以String类型例子来讲)

public class Computer {
    // 显示器
    private String displayer;
    // 主机
    private String mainUnit;
    // 鼠标
    private String mouse;
    // 键盘
    private String keyboard;
	
	//省略set get方法
	}

构建者ComputerBuilder

public class ComputerBuilder {

    private Computer computer = new Computer();


    public void installDisplayer(String displayer){
        computer.setDisplayer(displayer);
    }

    public void installMainUnit(String mainUnit){
        computer.setMainUnit(mainUnit);
    }

    public void installmouse(String mouse){
        computer.setMouse(mouse);
    }

    public void installkeyboard(String keyboard){
        computer.setKeyboard(keyboard);
    }

    public Computer build(){
        return computer;
    }
}

测试类

public class ConsructorTest {

    public static void main(String[] args) {
        ComputerBuilder computerBuilder = new ComputerBuilder();
        computerBuilder.installDisplayer("显示器");
        computerBuilder.installMainUnit("主机");
        computerBuilder.installmouse("鼠标");
        computerBuilder.installkeyboard("键盘");
        Computer computer = computerBuilder.build();
        System.out.println(computer);
    }
}

Mybatis中的体现:在Mybatis环境的初始化过程中,SqlSessionFactoryBuilder会调用XMLConfigBuilder读取所有的sqlMapConfig.xml和所有的*Mapper.xml文件,构建Mybatis运行的核心对象Configuration对象,然后将Configuration对象作为参数构建一个DefaultSqlSessionFactory对象。

Mybatis学习笔记六之设计模式_第2张图片

parser.parse()方法中是解析配置文件中所有信息并封装到Configuration中,从而构建出复杂Configuration对象。

Mybatis学习笔记六之设计模式_第3张图片

2,工厂模式

在Mybatis中比如SqlSessionFactory使用的是工厂模式,该工厂没有那么复杂的逻辑,是一个简单工厂模式(静态工厂方法模式),属于创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

例子:生产电脑

假设有一个电脑的代工生产商,它目前已经可以代工生产联想电脑了,随着业务的扩展,这个代工生产上还要生产惠普的电脑,我们就需要一个单独的类来专门生产电脑,这就用到了简单工厂模式。

(1)创建抽象产品类

public abstract class Computer {

    public abstract void start();
}

(2)创建具体产品类(它们都继承了父类Computer,并实现了了start()方法)

public class LenovoComputer extends Computer {
    @Override
    public void start() {
        System.out.println("联想电脑启动");
    }
}
public class HpComputer extends Computer {
    @Override
    public void start() {
        System.out.println("惠普电脑启动");
    }
}

(3)创建工厂类

接下来创建一个工厂类,它提供一个静态方法createComputer用来生产电脑。你只需要传入你想生产电脑的品牌,它就会实例化相应品牌的电脑对象

public class ComputerFactory {
    public static Computer createComputer(String type){
        Computer computer =null;
        switch (type){
            case "lenovo":
                computer = new LenovoComputer();
            case "hp":
                computer = new HpComputer();
        }
        return  computer;
    }
}

Mybatis中的体现:Mybatis中执行sql语句、获取Mappers、管理事务的核心接口SqlSession的创建过程使用到了工厂模式。有一个SqlSessionFactory来负责创建SqlSession。

Mybatis学习笔记六之设计模式_第4张图片

我们可以看到,该Factory的openSession()方法重载了好多个,支持传入不同的参数来创建SqlSession对象。

3,代理模式

代理模式(Proxy Pattern):给某一个对象提供一个代理,并由代理对象控制对原对象的引用。代理模式的英文叫Proxy,它是一种对象结构型模式,代理模式分为静态代理和动态代理。我们这里介绍动态代理。

例子:创建一个Person接口,并创建一个doSomething()方法:

public interface Person {
    public void doSomething();
}

创建一个名为Bob的Person接口的实现类,并重写doSomething()方法:

public class Bob implements Person {
    @Override
    public void doSomething() {
        System.out.println("Bob doing Something");
    }
}

创建JDK动态代理类,并使其实现InvocationHandler接口,拥有属性目标对象

public class JDKDynamicProxy implements InvocationHandler {
    // 声明被代理的对象
    private Person person;

    //构造函数
    public JDKDynamicProxy(Person person) {
        this.person = person;
    }
    //获取代理对象
    public Object getTarget(){
        Object proxyInstance = Proxy.newProxyInstance(person.getClass().getClassLoader(), person.getClass().getInterfaces(), this);
        return proxyInstance;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("对原方法进行了前置增强");
        //原方法执行
        Object invoke = method.invoke(person, args);
        System.out.println("对原方法进行了后置增强");
        return invoke;
    }
}

接下来编写一个测试类测试:

public class proxyTest {
    public static void main(String[] args) {

        System.out.println("不使用代理类,调用doSomething");
        Person person = new Bob();
        person.doSomething();

        System.out.println("--------------------------");

        System.out.println("使用代理类,调用doSomething");
        Person proxy = (Person) new JDKDynamicProxy(new Bob()).getTarget();
        proxy.doSomething();
    }
}

我们可以看到打印结果:

Mybatis学习笔记六之设计模式_第5张图片

Mybatis中的体现:代理模式可以认为是Mybatis的核心使用的模式,正是由于这个模式,我们只需要编写Mapper接口,不需要实现,有Mybatis帮我们完成具体sql的执行。具体实现可以看我上篇文章的源码分析。

 

你可能感兴趣的:(拉钩教育之开源框架学习,java,mybatis,设计模式)