简单工厂模式
简单工厂模式并不属于二十三种设计模式之一, 但是也能够适用于日常使用中扩展性不那么强的情景.
简单工厂主要解决的问题就是使用端不再通过大量的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.");
}
}