设计模式-策略模式

118 阅读3分钟

策略模式

在考试的时候,文档说jdbc的实现使用了策略模式,那就先搞个简单的示例 然后再去看看jdbc是如何实现的吧,

我自己的理解,不知道对不对:

我自己感觉策略模式和工厂模式很像,都是在需要多种选择中选择其中一个。但是工厂模式中,我想要一个实例需要我向工厂请求,然后我拿到实例 去调用它的方法。这是客户端调用

在策略模式中,调用方法这个动作交给了服务端,但是服务端要使用哪种实例调用方法呢,这个要调用哪种实例的策略交给了客户端去动态的调整。

示例

示例中有三种输出方式,服务端只管输出,但是它不知道自己要输出到哪里。输出到哪里的策略交给客户端

interface

public interface MySout {
    void sout();
}

implement

public class MyFirstSout implements MySout {

    @Override
    public void sout() {
        System.out.println("my first sout");
    }
}
public class MySecondSout implements MySout {
    @Override
    public void sout() {
        System.out.println("my second sout");
    }
}
public class MyThirdSout implements MySout{
    @Override
    public void sout() {
        System.out.println("my third sout");
    }
}

manager

public class SoutManager {
    MySout sout;

    public void setSout(String className) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        sout = (MySout) Class.forName(className).newInstance();
    }

    public void action(){
        sout.sout();
    }
}

TEST

public class Test {
    public static void main(String[] args) throws IllegalAccessException, InstantiationException, ClassNotFoundException, InterruptedException {
        SoutManager soutManager = new SoutManager();
        while (true){
            soutManager.setSout("designpatterns.strategy.MyFirstSout");
            soutManager.action();
            Thread.sleep(1000);
            soutManager.setSout("designpatterns.strategy.MySecondSout");
            soutManager.action();
            Thread.sleep(1000);
            soutManager.setSout("designpatterns.strategy.MyThirdSout");
            soutManager.action();
            Thread.sleep(1000);
        }
    }
}

print:

my first sout
my second sout
my third sout
my first sout
my second sout
my third sout
my first sout
my second sout
my third sout
my first sout
my second sout
my third sout
my first sout
my second sout
my third sout
my first sout
my second sout
    ...
    ...

回到使用jdbc中的场景,看下jdbc

JDBC中的策略模式-以mysql举例

不具体的讨论源码,只看下jdbc的思路

整个与数据库连接的管理都有一个类叫DriverManager, 这个类位于java的sql包中,类中有一个字段

    // List of registered JDBC drivers
    private final static CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<>();

这个字段保存了注册过的jdbc驱动

还有个类叫Driver, 这个类同样位于java的sql包中,是个接口类,但是在jdk中并无任何实现。很明显这个是一个**策略接口**

public interface Driver

在项目中引入了mysql的包后,可以发现一个实现了Driver接口的类,com.mysql.cj.jdbc.Driver, 当我们注册Driver时,用的就是这个类,就是把这个策略告诉了jdbc,这个是mysql的驱动方式。

结合jdbc的使用

  1. 首先在DriverManager中注册自己的driver,只要自定义的driver实现了 java的dirver接口。自定义的dirver就会存在DriverManagerregisteredDrivers属性中
  2. 当客户端从DriverManagergetConnection时,DriverManager从存储的策略中选择对应的driver去执行driverconnect方法,并返回给客户端。

同理客户端也许需要多种数据库,但是只要此数据库实现了java提供的Driver类,客户端就可以使用上述方法去连接自己想要的数据库,至于jdbc是如何确认使用哪种驱动的。那就有时间再说吧