一、简介

工厂模式主要是为创建对象提供了接口。工厂模式按照《Java与模式》中的提法分为三类:
1. 简单工厂模式(Simple Factory)
2. 工厂方法模式(Factory Method)
3. 抽象工厂模式(Abstract Factory)

二、简单工厂模式

使用工厂获取功能定义相同的实现工具

接口

  1. /**
  2. * @author jiangyj
  3. * @version 1.0
  4. * @create 2021-03-18 11:16
  5. **/
  6. public interface Wheel {
  7. int wheelNum();
  8. void setNum(int num1);
  9. void show();
  10. }

抽象类

  1. /**
  2. * @author jiangyj
  3. * @version 1.0
  4. * @create 2021-03-18 14:59
  5. **/
  6. public abstract class BaseWheel implements Wheel {
  7. protected int num = 4;
  8. @Override
  9. public int wheelNum() {
  10. return num;
  11. }
  12. @Override
  13. public void setNum(int num) {
  14. this.num = num;
  15. }
  16. }

实现类

  1. /**
  2. * @author jiangyj
  3. * @version 1.0
  4. * @create 2021-03-18 11:17
  5. **/
  6. public class CircleWheel extends BaseWheel {
  7. @Override
  8. public void show() {
  9. System.out.println(this.getClass() + " has " + this.wheelNum() + " wheelNum");
  10. }
  11. }
  1. /**
  2. * @author jiangyj
  3. * @version 1.0
  4. * @create 2021-03-18 11:16
  5. **/
  6. public class RectangleWheel extends BaseWheel {
  7. @Override
  8. public void show() {
  9. System.out.println(this.getClass() + " has " + this.wheelNum() + " wheelNum");
  10. }
  11. }
  1. /**
  2. * @author jiangyj
  3. * @version 1.0
  4. * @create 2021-03-18 11:17
  5. **/
  6. public class SquareWheel extends BaseWheel {
  7. @Override
  8. public void show() {
  9. System.out.println(this.getClass() + " has " + this.wheelNum() + " wheelNum");
  10. }
  11. }

工厂

  1. /**
  2. * @author jiangyj
  3. * @version 1.0
  4. * @create 2021-03-18 11:17
  5. **/
  6. public class SimpleFactory {
  7. public Wheel getWheel(String type) {
  8. if (type == null) {
  9. return null;
  10. }
  11. if (type.equalsIgnoreCase("CIRCLE")) {
  12. return new CircleWheel();
  13. } else if (type.equalsIgnoreCase("RECTANGLE")) {
  14. return new RectangleWheel();
  15. } else if (type.equalsIgnoreCase("SQUARE")) {
  16. return new SquareWheel();
  17. }
  18. return null;
  19. }
  20. }

测试类

  1. /**
  2. * 简单工厂demo
  3. * @author jiangyj
  4. * @version 1.0
  5. * @create 2021-03-18 11:20
  6. **/
  7. @Slf4j
  8. public class SimpleFactoryDemo {
  9. public static void main(String[] args) {
  10. SimpleFactory simpleFactory = new SimpleFactory();
  11. //获取 Circle 的对象
  12. Wheel wheel = simpleFactory.getWheel("CIRCLE");
  13. wheel.show();
  14. //获取 Rectangle 的对象
  15. wheel = simpleFactory.getWheel("RECTANGLE");
  16. wheel.show();
  17. //获取 Square 的对象
  18. wheel = simpleFactory.getWheel("SQUARE");
  19. wheel.show();
  20. wheel = simpleFactory.getWheel("AAAA");
  21. log.info("AAAA == null : {}", wheel == null);
  22. }
  23. }

输出

class top.lossingdawn.design.pattern.demo1.wheel.CircleWheel has 4 wheelNum class top.lossingdawn.design.pattern.demo1.wheel.RectangleWheel has 4 wheelNum class top.lossingdawn.design.pattern.demo1.wheel.SquareWheel has 4 wheelNum 15:49:41.276 [main] INFO top.lossingdawn.design.pattern.demo1.simplefactory.SimpleFactoryDemo - AAAA == null : true

特点

1 它是一个具体的类,非接口 抽象类。根据参数返回具体的实现对象。
2 get()方法通常是静态的,所以也称之为静态工厂。

缺点

1 扩展性差,当需要增加、减少
2 不同的产品需要不同额外参数的时候 不支持。

注:当然也有规避缺点的方法,就是动态加载实现类,利用反射或者spring bean工厂,动态的把参数和实现类关联起来

三、工厂方法模式

不同工厂定义不同的初始化

工厂接口

  1. /**
  2. * @author jiangyj
  3. * @version 1.0
  4. * @create 2021-03-18 14:44
  5. **/
  6. public interface WheelFactory {
  7. Wheel getWheel(String shapeType);
  8. }

工厂类

  1. /**
  2. * @author jiangyj
  3. * @version 1.0
  4. * @create 2021-03-18 14:50
  5. **/
  6. public class LowWheelFactory implements WheelFactory {
  7. @Override
  8. public Wheel getWheel(String shapeType) {
  9. Wheel wheel = null;
  10. if (shapeType == null) {
  11. return null;
  12. }
  13. if (shapeType.equalsIgnoreCase("CIRCLE")) {
  14. wheel = new CircleWheel();
  15. } else if (shapeType.equalsIgnoreCase("RECTANGLE")) {
  16. wheel = new RectangleWheel();
  17. } else if (shapeType.equalsIgnoreCase("SQUARE")) {
  18. wheel = new SquareWheel();
  19. }
  20. wheel.setNum(4);
  21. return wheel;
  22. }
  23. }
  1. /**
  2. * @author jiangyj
  3. * @version 1.0
  4. * @create 2021-03-18 14:44
  5. **/
  6. public class UpWheelFactory implements WheelFactory {
  7. @Override
  8. public Wheel getWheel(String shapeType) {
  9. Wheel wheel = null;
  10. if (shapeType == null) {
  11. return null;
  12. }
  13. if (shapeType.equalsIgnoreCase("CIRCLE")) {
  14. wheel = new CircleWheel();
  15. } else if (shapeType.equalsIgnoreCase("RECTANGLE")) {
  16. wheel = new RectangleWheel();
  17. } else if (shapeType.equalsIgnoreCase("SQUARE")) {
  18. wheel = new SquareWheel();
  19. }
  20. wheel.setNum(8);
  21. return wheel;
  22. }
  23. }

测试类

  1. /**
  2. * 工厂模式demo
  3. * @author jiangyj
  4. * @version 1.0
  5. * @create 2021-03-18 15:03
  6. **/
  7. @Slf4j
  8. public class WheelFactoryDemo {
  9. public static void main(String[] args) {
  10. // lowcar
  11. WheelFactory wheelFactory = new LowWheelFactory();
  12. Wheel wheel = wheelFactory.getWheel("CIRCLE");
  13. wheel.show();
  14. // upcar
  15. wheelFactory = new UpWheelFactory();
  16. wheel = wheelFactory.getWheel("CIRCLE");
  17. wheel.show();
  18. }
  19. }

输出

class top.lossingdawn.design.pattern.demo1.wheel.CircleWheel has 4 wheelNum class top.lossingdawn.design.pattern.demo1.wheel.CircleWheel has 8 wheelNum

特点

不同的工厂输出定制化的实现工具

缺点

同简单模式,拓展性较差,因增加定制化需求,较难通过一些手段规避问题

四、抽象工厂模式

把不同的接口通过层级组合起来

接口

  1. /**
  2. * @author jiangyj
  3. * @version 1.0
  4. * @create 2021-03-18 14:37
  5. **/
  6. public interface Airbags {
  7. void show();
  8. }

实现类

  1. /**
  2. * @author jiangyj
  3. * @version 1.0
  4. * @create 2021-03-18 14:37
  5. **/
  6. public class AAirbags implements Airbags{
  7. @Override
  8. public void show() {
  9. System.out.println(this.getClass());
  10. }
  11. }
  1. /**
  2. * @author jiangyj
  3. * @version 1.0
  4. * @create 2021-03-18 15:08
  5. **/
  6. public interface CarFactory {
  7. Airbags getAirBags();
  8. Wheel getWheel();
  9. }

工厂接口

  1. /**
  2. * @author jiangyj
  3. * @version 1.0
  4. * @create 2021-03-18 15:08
  5. **/
  6. public interface CarFactory {
  7. Airbags getAirBags();
  8. Wheel getWheel();
  9. }

工厂类

  1. /**
  2. * @author jiangyj
  3. * @version 1.0
  4. * @create 2021-03-18 15:11
  5. **/
  6. public class ACarFactory implements CarFactory {
  7. @Override
  8. public Airbags getAirBags() {
  9. return new AAirbags();
  10. }
  11. @Override
  12. public Wheel getWheel() {
  13. return new RectangleWheel();
  14. }
  15. }
  1. /**
  2. * @author jiangyj
  3. * @version 1.0
  4. * @create 2021-03-18 15:11
  5. **/
  6. public class BCarFactory implements CarFactory {
  7. @Override
  8. public Airbags getAirBags() {
  9. return new BAirbags();
  10. }
  11. @Override
  12. public Wheel getWheel() {
  13. Wheel wheel = new CircleWheel();
  14. wheel.setNum(8);
  15. return wheel;
  16. }
  17. }

测试类

  1. /**
  2. * 抽象工厂模式demo
  3. * @author jiangyj
  4. * @version 1.0
  5. * @create 2021-03-18 15:21
  6. **/
  7. public class CarFactoryDemo {
  8. public static void main(String[] args) {
  9. // ACar
  10. CarFactory carFactory = new ACarFactory();
  11. Wheel wheel = carFactory.getWheel();
  12. wheel.show();
  13. Airbags airbags = carFactory.getAirBags();
  14. airbags.show();
  15. // BCar
  16. carFactory = new BCarFactory();
  17. wheel = carFactory.getWheel();
  18. wheel.show();
  19. airbags = carFactory.getAirBags();
  20. airbags.show();
  21. }
  22. }

输出

class top.lossingdawn.design.pattern.demo1.wheel.RectangleWheel has 4 wheelNum class top.lossingdawn.design.pattern.demo1.aribags.AAirbags class top.lossingdawn.design.pattern.demo1.wheel.CircleWheel has 8 wheelNum class top.lossingdawn.design.pattern.demo1.aribags.BAirbags

特点

通过接口层级关系,紧密的连接起来,形成一个产品

缺点

接口之间有固定的层级依赖关系,跨层级调整是灾难性的

五、总结

简单工厂:

一个工厂生产多种轮子,圆轮子、方轮子、矩形轮子
同种商品的不同种类

工厂方法:

多个工厂生产轮子,圆轮子、方轮子、矩形轮子
A工厂轮子4个一组,B工厂轮子8个一组
同种商品不同的生产规格

抽象工厂:

一个工厂生产轮子、气囊等产品
一个产品由规格不同的其他产品组成

六、工厂模式的实际应用

1、spring bean工厂 【BeanFactory】
2、加密工厂【SecretKeyFactory】

项目地址:https://github.com/Ruffianjiang/DesignPatternDemo/tree/master/demo1