在现实生活中分工越来越细,各种各样的工厂进行生产产品,告别过去刀耕火种的小农生活,想要什么东西就购买直接使用就好了。而在代码中同样可以通过工厂模式做到想要什么类就直接获取使用就好,无需关注对象创建过程。
一、简单工厂模式(Simple Factory Pattern)
是指定一个工厂对象决定创建哪一种产品的实例,适用于工程类负责创建的对象较少的场景,且客户端只需要传入工厂类的参数,对如何场景对象并不关心。
下面是一个简单的加减法计算工厂类
- 计算接口
public interface Calculate {
int result(int num1, int num2);
}
- 加法实现类
public class AddCalculate implements Calculate {
@Override
public int result(int num1, int num2) {
return num1 + num2;
}
}
- 减法实现类
public class SubCalculate implements Calculate {
@Override
public int result(int num1, int num2) {
return num1 - num2;
}
}
- 计算工厂
public class AlgorithmFactory {
Calculate creat(String type) {
switch (type) {
//加法
case "add":
return new AddCalculate();
//减法
case "sub":
return new SubCalculate();
default:
return null;
}
}
}
- 运行
public class Run {
public static void main(String[] args) {
AlgorithmFactory factory = new AlgorithmFactory();
System.out.println(factory.creat("add").result(1, 2));
System.out.println(factory.creat("sub").result(1,2));
}
}
- 结果
3
-1
缺点:工厂类职责过重,不易扩展复杂的业务
二、工厂方法
定义一个创建对象的接口,让实现这个接口的类来决定实例化哪个类,工厂方法模式让类的实例化推迟到子类中进行,在工厂方法中用户只需要关注所需产品对应的工厂,无需关注创建细节。工厂方法主要解决产品无法扩展的问题。新增的产品也符合开闭原则。
- 工厂方法适用于以下场景:
- 创建对象需要大量代码
- 应用层不依赖产品类实例如何被创建、如何被实现的问题
- 一个类通过其子类指定创建哪个对象
- 缺点
- 类的个数容易过多,增加代码复杂度
- 增加系统的抽象和理解难度
- 计算接口
public interface Calculate {
int result(int num1, int num2);
}
- 计算工厂接口
public interface CalculateFactory {
Calculate creat();
}
- 加法实现接口
public class AddCalculate implements Calculate {
@Override
public int result(int num1, int num2) {
return num1+num2;
}
}
- 加法实现工厂
public class AddCalculateFactory implements CalculateFactory {
@Override
public Calculate creat() {
return new AddCalculate();
}
}
- 运行
public class Run {
public static void main(String[] args) {
CalculateFactory factory = new AddCalculateFactory();
Calculate creat = factory.creat();
System.out.println(creat.result(1, 2));
}
}
- 结果
3
三、抽象工厂(Abstract Factory Pattern)
是指提供一个创建一系列相关或相互依赖的对象接口,无须指定他们的具体类。应用层不依赖产品类实例如何被创建、如何被实现的细节。
-
缺点
- 规定了所有可能被创建的产品集合,产品族(CalculateFactory)中需要扩展新的产品困难(AddCalculate、SubCalculate),需修改抽象工厂的接口
- 增加系统的抽象和理解难度
-
类结构
- 抽象工厂(CalculateFactory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法 newProduct() 来创建产品。
- 具体工厂(CalculateFactoryImpl):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
- 抽象产品(AddCalculate、SubCalculate):定义了产品的规范,描述了产品的主要特性和功能。
- 具体产品(AddCalculateImpl、SubCalculateImpl):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。
-
basice
-
clazz
-
顶层抽象接口
/**
* 加法接口
*/
public interface AddCalculate {
int result(int num1, int num2);
}
/**
* 减法接口
*/
public interface SubCalculate {
int result(int num1, int num2);
}
/**
* 算法抽象工厂
*/
public interface CalculateFactory {
AddCalculate creatAdd();
SubCalculate creatSub();
}
- 基础实现
public class AddCalculateImpl implements AddCalculate {
@Override
public int result(int num1, int num2) {
System.out.println("基础加法");
return num1+num2;
}
}
public class SubCalculateImpl implements SubCalculate {
@Override
public int result(int num1, int num2) {
System.out.println("基础减法");
return num1-num2;
}
}
public class CalculateFactoryImpl implements CalculateFactory {
@Override
public AddCalculate creatAdd() {
return new AddCalculateImpl();
}
@Override
public SubCalculate creatSub() {
return new SubCalculateImpl();
}
}
- 类实现
public class ClazzAddCalculateImpl implements AddCalculate {
@Override
public int result(int num1, int num2) {
System.out.println("类加法");
return new Integer(num1)+new Integer(num2);
}
}
public class ClazzSubCalculateImpl implements SubCalculate {
@Override
public int result(int num1, int num2) {
System.out.println("类减法");
return new Integer(num1) - new Integer(num2);
}
}
public class ClazzCalculateFactoryImpl implements CalculateFactory {
@Override
public AddCalculate creatAdd() {
return new ClazzAddCalculateImpl();
}
@Override
public SubCalculate creatSub() {
return new ClazzSubCalculateImpl();
}
}
- 运行
public class Run {
public static void main(String[] args) {
CalculateFactory factory = new CalculateFactoryImpl();
factory.creatAdd().result(1,2);
factory.creatSub().result(1,2);
factory = new ClazzCalculateFactoryImpl();
factory.creatAdd().result(1,2);
factory.creatSub().result(1,2);
}
}
- 结果
基础加法
基础减法
类加法
类减法
四、总结
工厂模式来来回回通过看书或看视频也有许多次了,每次看完过一段时间也忘记差不多只有一点印象。书看完也需要整理和归纳,最重要的是在实际工作中使用到,虽然可能用的不好,但慢慢用起来,慢慢改正是会越用越熟的。就像代码一次次的迭代越来越好。
资料参考
《spring 5 核心原理》书籍