本文转载自:https://www.cnblogs.com/gdwkong/p/8413342.html,原文是将工厂方法模式和抽象工厂模式放在一起了好做比较,我这里拆分开
1.工厂模式介绍
1.1定义:定义一个创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到子类。
工厂方法的通用类图
在工厂模式中,抽象产品类Product负责定义产品的共性,实现对事物最抽象的定义,Creator为抽象类的创建类,也就是抽象工厂,具体如何创建类是由具体的实现工厂ConcreteCreator完成的。
1.2工厂方法模式的有点
- 良好的封装性,代码结构清晰
- 扩展性非常好,在增加产品类的情况下,只要适当的修改一个具体工厂类或者扩展一个工厂类,就可以“拥有变化”。
- 屏蔽产品类。产品类如何变化,调用者无需关心,它只需关心产品的接口,只要接口保持不变,系统的上层模块就不需要发生变化。
- 解耦框架。高层模块只需要关心产品的抽象类,其他实现类都不用关心。
1.3工厂方法模式的使用场景
2.工厂模式的实现
2.1简单工厂模式(静态工厂模式)
以实现一个计算器为例:
整个过程设计三个对象:人(Program4表示),计算器(以OperationFactory表示),计算方式(计算方式有多种,加减乘除等,都属于计算方法,以一个父类Operation,加减乘除继承覆写方法即
可)。整个示例类如下:
1 public class Program4 { 2 3 public static void main(String[] args) { 4 Scanner scanner = new Scanner(System.in); 5 System.out.println("请输入数字A"); 6 double numberA = Double.parseDouble(scanner.nextLine()); 7 System.out.println ("选择运算符(+、-、*、/):"); 8 String atrithmeticType = scanner.nextLine(); 9 System.out.println("请输入数字B"); 10 double numberB = Double.parseDouble(scanner.nextLine()); 11 Operation operate = OperationFactory.createOperate(atrithmeticType); 12 13 if (atrithmeticType.equals("/") && numberB == 0){ 14 System.out.println("除数不能为0"); 15 }else { 16 operate.setNumberA(numberA); 17 operate.setNumberB(numberB); 18 double result = operate.result(); 19 System.out.println("结果为:1" + result); 20 } 21 scanner.close(); 22 } 23 }
计算器(工程)用户需求,选择(生产)符合需要的计算方式创建对应的示例对象,创建过程需要用户参与。
1 public class OperationFactory { 2 3 public static Operation createOperate(String arithmeticType){ 4 Operation operation = null; 5 switch (arithmeticType){ 6 case "+": 7 operation = new OperationAdd(); 8 break; 9 case "-": 10 operation= new OperationSub(); 11 break; 12 case "*": 13 operation = new OperationMul(); 14 break; 15 case "/": 16 operation = new OperationDiv(); 17 break; 18 } 19 return operation; 20 } 21 }
1 public class Operation { 2 private double numberA; 3 private double numberB; 4 5 public double getNumberA() { 6 return numberA; 7 } 8 9 public void setNumberA(double numberA) { 10 this.numberA = numberA; 11 } 12 13 public double getNumberB() { 14 return numberB; 15 } 16 17 public void setNumberB(double numberB) { 18 this.numberB = numberB; 19 } 20 public double result(){ 21 double result = 0; 22 return 0; 23 } 24 } 25 26 public class OperationAdd extends Operation{ 27 @Override 28 public double result() { 29 return getNumberA() + getNumberB(); 30 } 31 } 32 33 public class OperationSub extends Operation { 34 @Override 35 public double result() { 36 return getNumberA() - getNumberB(); 37 } 38 } 39 40 public class OperationMul extends Operation { 41 @Override 42 public double result() { 43 return getNumberA() * getNumberB(); 44 } 45 } 46 47 public class OperationDiv extends Operation { 48 @Override 49 public double result() { 50 return getNumberA() / getNumberB(); 51 } 52 }
简单工厂的缺点是不符合“开闭原则”,要增加新的功能(计算方式)时,需要修改工厂类(增加分支)。
2.2多方法工厂模式
是对简单工厂模式的改进,在简单工厂方法模式中,如果传递的字符串出错,则不能创建对象,而多方法工厂模式是提供多个工厂方法,分别创建对象
1 public class OperationFactory03 { 2 public Operation add(){ 3 return new OperationAdd(); 4 } 5 public Operation sub(){ 6 return new OperationSub(); 7 } 8 public Operation mul(){ 9 return new OperationMul(); 10 } 11 public Operation div(){ 12 return new OperationDiv(); 13 } 14 } 15 16 17 // main方法中 18 OperationFactory03 operationFactory03 = new OperationFactory03(); 19 Operation add = operationFactory03.add(); 20 add.setNumberA(1); 21 add.setNumberB(2); 22 double result = add.result(); 23 System.out.println("结果是:" + result);
2.3静态工厂方法
多个工厂方法设置为静态,不需要创建工厂,直接创建对象
1 public class OperationFactory04 { 2 public static Operation add(){ 3 return new OperationAdd(); 4 } 5 public static Operation sub(){ 6 return new OperationSub(); 7 } 8 public static Operation mul(){ 9 return new OperationMul(); 10 } 11 public static Operation div(){ 12 return new OperationDiv(); 13 } 14 } 15 16 // main方法中 17 Operation add = OperationFactory04.add(); 18 add.setNumberA(1); 19 add.setNumberB(2); 20 double result = add.result(); 21 System.out.println("结果是:" + result);
总体来说:工厂模式,适合出现了大量产品需要创建,并且具有共同的接口时,可以通过工厂方法模式进行创建。
在以上三种工程方法模式中,第一种如果不能正确的传入字符,不能正确创建对象;第三种相对于第二种不需要实例化工厂,所以大多数情况下我们会选择第三种--------静态工厂方法模式。