二十三种设计模式(二)--工厂方法模式

简单工厂模式

简单工厂模式并不属于二十三种设计模式之一, 但是也能够适用于日常使用中扩展性不那么强的情景.

简单工厂主要解决的问题就是使用端不再通过大量的if-else去创建结构相似的类, 而是把这种创建类的操作封装在工厂类中, 使用端通过不同的参数就可以得到对应的类实例.

简单工厂示例:

使用端和工厂类端都依赖这个枚举类, 用来匹配参数

java 复制代码
public enum WorkerTypes {
    WORKER_TYPE_A,
    WORKER_TYPE_B,
    WORKER_TYPE_C,
    WORKER_TYPE_D;
}

工厂端:

类的生成逻辑及后续的扩展修改都在工厂端进行修改, 符合开闭原则

java 复制代码
// 这个类可扩展, 生成结构相同的子类
public class FactoryCreator {
    public static Worker getWorker(WorkerTypes param) {
        switch (param) {
            case WORKER_TYPE_A:
                return new WorkerA();
            case WORKER_TYPE_B:
                return new WorkerB();
            case WORKER_TYPE_C:
                return new WorkerC();
            case WORKER_TYPE_D:
                return new WorkerD();
            // ... 新增扩展类时修改这里进行扩展
            default:
                return null;
        }
    }
}

// 可供扩展的接口, 所有扩展类都基于这个接口
interface Worker {
    void doJob();
}

class WorkerA implements Worker {
    public void doJob(){
        System.out.println("Work A job done.");
    }
}

class WorkerB implements Worker {
    public void doJob(){
        System.out.println("Work B job done.");
    }
}

class WorkerC implements Worker {
    public void doJob(){
        System.out.println("Work C job done.");
    }
}

class WorkerD implements Worker {
    public void doJob(){
        System.out.println("Work D job done.");
    }
}

使用端:

使用简单工厂模式, 最大的好处是解耦, 根据不同参数生成不同的类的操作转移到了工厂中, 工厂类可自由扩展

java 复制代码
public class SimpleFactory {
    public static void main(String[] args) {
        // 使用端, 根据业务逻辑, 从工厂获取需要的类对象, 直接调用
        Worker workerA = FactoryCreator.getWorker(WorkerTypes.WORKER_TYPE_A);
        workerA.doJob();

        Worker workerB = FactoryCreator.getWorker(WorkerTypes.WORKER_TYPE_B);
        workerB.doJob();

        Worker workerC = FactoryCreator.getWorker(WorkerTypes.WORKER_TYPE_C);
        workerC.doJob();

        Worker workerD = FactoryCreator.getWorker(WorkerTypes.WORKER_TYPE_D);
        workerD.doJob();
    }
}

运行结果:

复制代码
Work A job done.
Work B job done.
Work C job done.
Work D job done.

工厂方法模式

基于简单工厂模式, 工厂模式多加了一个扩展层, 工厂类本身也可以自由扩展

工厂方法模式是为了将核心业务逻辑与具体实现类解耦, 从工厂类中实现一定程度的扩展

当每一个工厂都有包含大量独有的业务逻辑时, 简单工厂模式会变得非常臃肿, 此时就要将工厂本身抽象出来单独扩展, 此时就要采用工厂方法模式增加扩展性

示例如下:

可扩展的工厂类部分:

java 复制代码
// 可扩展的工厂类接口
public interface Factory {
    Worker getWorker();
}

class FactoryA implements Factory {
    public Worker getWorker() {
        return new WorkerAFactoryA();
    }
}

class FactoryB implements Factory {
    public Worker getWorker() {
        return new WorkerBFactoryB();
    }
}

class FactoryC implements Factory {
    public Worker getWorker() {
        return new WorkerCFactoryC();
    }
}

可扩展的具体实现类部分:

java 复制代码
// 可扩展的具体实现类接口
public interface Worker {
    void doWork();
}

class WorkerAFactoryA implements Worker {
    public void doWork() {
        System.out.println("Worker A in Factory A job done.");
    }
}

class WorkerBFactoryB implements Worker {
    public void doWork() {
        System.out.println("Worker B in Factory B job done.");
    }
}

class WorkerCFactoryC implements Worker {
    public void doWork() {
        System.out.println("Worker C in Factory C job done.");
    }
}

业务调用端, 根据具体情况使用工厂类生成对应的实现类:

java 复制代码
public class FactoryMethod {
    public static void main(String[] args) {
        FactoryA factoryA = new FactoryA();
        Worker workerA = factoryA.getWorker();
        workerA.doWork();

        FactoryB factoryB = new FactoryB();
        Worker workerB = factoryB.getWorker();
        workerB.doWork();

        FactoryC factoryC = new FactoryC();
        Worker workerC = factoryC.getWorker();
        workerC.doWork();
    }
}

运行结果:

复制代码
Worker A in Factory A job done.
Worker B in Factory B job done.
Worker C in Factory C job done.

这里有个需要注意的地方, 就是工厂类与具体的实现类一般是一对一的关系, 这样是标准的工厂方法模式.

工厂方法模式与简单工厂模式混合, 适用某些特殊场景

但是有时候, 当一个工厂对应两个或以上的实现类时, 就需要灵活一些, 工厂方法类与简单工厂类混合, 以处理更多特殊的业务逻辑, 示例如下:

定义工厂类和应用层共用的枚举类:

java 复制代码
public enum WorkerTypes {
    WORKER_A_FACTORY_A,
    WORKER_B_FACTORY_A,
    WORKER_C_FACTORY_B,
    WORKER_D_FACTORY_B;
}

工厂方法模式与简单工厂模式混写以处理某些特殊的业务情形

这种混写的方式违背了单一职责原则, 开闭原则, 写这个例子只是为了展示设计模式

的灵活运用示例.

java 复制代码
// 可扩展接口
public interface Factory {
    Worker getWorker(WorkerTypes type);
}

class FactoryA implements Factory {
    public Worker getWorker(WorkerTypes type) {
        switch (type) {
            case WORKER_A_FACTORY_A:
                return new WorkerAFactoryA();
            case WORKER_B_FACTORY_A:
                return new WorkerAFactoryB();
            default:
                return null;
        }
    }
}

class FactoryB implements Factory {
    public Worker getWorker(WorkerTypes type) {
        switch (type) {
            case WORKER_C_FACTORY_B:
                return new WorkerCFactoryB();
            case WORKER_D_FACTORY_B:
                return new WorkerDFactoryB();
            default:
                return null;
        }
    }
}

具体的实现类:

java 复制代码
// 可扩展接口
public interface Worker {
    void doWork();
}

class WorkerAFactoryA implements Worker {
    public void doWork() {
        System.out.println("Worker A in Factory A job done.");
    }
}

class WorkerAFactoryB implements Worker {
    public void doWork() {
        System.out.println("Worker B in Factory A job done.");
    }
}

class WorkerCFactoryB implements Worker {
    public void doWork() {
        System.out.println("Worker C in Factory B job done.");
    }
}

class WorkerDFactoryB implements Worker {
    public void doWork() {
        System.out.println("Worker D in Factory B job done.");
    }
}
相关推荐
一嘴一个橘子12 小时前
spring-aop 的 基础使用 - 4 - 环绕通知 @Around
java
小毅&Nora13 小时前
【Java线程安全实战】⑨ CompletableFuture的高级用法:从基础到高阶,结合虚拟线程
java·线程安全·虚拟线程
冰冰菜的扣jio13 小时前
Redis缓存中三大问题——穿透、击穿、雪崩
java·redis·缓存
小璐猪头13 小时前
专为 Spring Boot 设计的 Elasticsearch 日志收集 Starter
java
ps酷教程13 小时前
HttpPostRequestDecoder源码浅析
java·http·netty
闲人编程13 小时前
消息通知系统实现:构建高可用、可扩展的企业级通知服务
java·服务器·网络·python·消息队列·异步处理·分发器
栈与堆13 小时前
LeetCode-1-两数之和
java·数据结构·后端·python·算法·leetcode·rust
OC溥哥99914 小时前
Paper MinecraftV3.0重大更新(下界更新)我的世界C++2D版本隆重推出,拷贝即玩!
java·c++·算法
星火开发设计14 小时前
C++ map 全面解析与实战指南
java·数据结构·c++·学习·算法·map·知识
*才华有限公司*14 小时前
RTSP视频流播放系统
java·git·websocket·网络协议·信息与通信