重学 Java 设计模式:实战抽象工厂模式

338 阅读4分钟

重学 Java 设计模式:实战抽象工厂模式

今天我们来谈一下 Java 设计模式中的抽象工厂模式,以实战方式来介绍。我们将以升级 Redis 双集群,代理类抽象场景为例,通过抽象工厂模式的实现,来解决代理类升级问题,提高程序的可维护性、可扩展性和可读性。

什么是抽象工厂模式

抽象工厂模式是一种创建型设计模式,它允许创建一系列相关的对象,而无需指定其具体类别。抽象工厂模式通过抽象化工厂类和具体工厂类的方式,实现了客户端和具体实现类的分离。客户端只需要知道抽象工厂和抽象产品接口,就可以使用一组产品,无需知道具体的实现。

抽象工厂模式优点

  • 增强程序的可维护性和可扩展性,提高程序的可读性
  • 通过工厂方法封装了对象的创建过程,避免了客户端直接依赖具体实现类
  • 可以轻松地替换不同的具体实现类,无需修改客户端代码

升级 Redis 双集群场景

假设我们现在有一个 Redis 双集群场景,其中一个集群存放请求较少的数据,另一个集群存放请求较多的数据。我们希望通过代理类实现在请求量超过阈值的时候,自动切换到请求量较大的集群中。

下面我们通过抽象工厂模式实现此场景。

实现思路

我们可以通过抽象工厂模式,为请求量较大的集群中的代理类进行替换。具体实现步骤如下:

  1. 定义抽象工厂接口,包含创建一系列代理类的方法。
  2. 定义抽象产品接口,包含获取请求量、代理转发等方法。
  3. 创建具体产品类,分别实现抽象产品接口,即代理类功能实现。
  4. 创建具体工厂类,实现抽象工厂接口,用于创建与请求量对应的具体代理类。
  5. 在客户端中,使用抽象工厂和抽象产品接口,通过配置文件或者其他方式,选择对应的工厂类,来创建具体代理类。

通过这样的实现方式,我们可以轻松地替换掉具体的代理类,而无需对客户端进行任何修改。

实现代码

抽象工厂接口

public interface ProxyFactory {
    /**
     * 获取代理类
     *
     * @return 抽象产品
     */
    Proxy getProxy();
}

抽象产品接口

public interface Proxy {
    /**
     * 获取请求量
     *
     * @return 请求量
     */
    int getRequestCount();
​
    /**
     * 代理转发
     *
     * @param request 请求
     * @return 响应
     */
    String proxy(String request);
}

具体产品类

请求量较小的代理类

public class SmallProxy implements Proxy {
​
    @Override
    public int getRequestCount() {
        return 1000;
    }
​
    @Override
    public String proxy(String request) {
        // 实现请求转发逻辑
        return "SmallProxy: " + request;
    }
}

请求量较大的代理类

public class BigProxy implements Proxy {
​
    @Override
    public int getRequestCount() {
        return 10000;
    }
​
    @Override
    public String proxy(String request) {
        // 实现请求转发逻辑
        return "BigProxy: " + request;
    }
}

具体工厂类

public class ProxyFactoryImpl implements ProxyFactory {
​
    private static final String CLUSTER_CONFIG = "cluster.properties";
​
    private static final String SMALL_PROXY_CLASS = "small_proxy_class";
​
    private static final String BIG_PROXY_CLASS = "big_proxy_class";
​
    /**
     * 根据请求量创建具体代理类
     *
     * @return 抽象产品
     */
    @Override
    public Proxy getProxy() {
        Properties properties = new Properties();
        try {
            properties.load(new FileInputStream(new File(CLUSTER_CONFIG)));
        } catch (IOException e) {
            throw new RuntimeException("无法读取配置文件", e);
        }
​
        int requestCount = 0; // 获取请求量
​
        if (requestCount < 5000) { // 根据请求量选择具体代理类
            String smallProxyClass = properties.getProperty(SMALL_PROXY_CLASS);
            try {
                return (Proxy) Class.forName(smallProxyClass).newInstance();
            } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
                throw new RuntimeException("无法实例化小型代理类", e);
            }
        } else {
            String bigProxyClass = properties.getProperty(BIG_PROXY_CLASS);
            try {
                return (Proxy) Class.forName(bigProxyClass).newInstance();
            } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
                throw new RuntimeException("无法实例化大型代理类", e);
            }
        }
    }
}

客户端代码

public class App {
​
    public static void main(String[] args) {
        ProxyFactory proxyFactory = new ProxyFactoryImpl();
        Proxy proxy = proxyFactory.getProxy();
        // 使用代理类实现请求转发
        System.out.println(proxy.proxy("hello world!"));
    }
}

配置文件

small_proxy_class=cn.example.SmallProxy
big_proxy_class=cn.example.BigProxy

结语

本文通过实战的方式介绍了 Java 设计模式中的抽象工厂模式,并以升级 Redis 双集群,代理类抽象场景为例,演示了抽象工厂模式的实现思路和具体代码实现。在实际开发中,设计模式可以提高程序的可读性、可重用性和可维护性,希望本文对您有所帮助。