Java学习笔记——设计模式之五.工厂方法

水边
一只青蛙在笑

      ——石头和水

 

工厂方法模式(Factory Method),定义了一个用于创建对象的接口,让实现类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

这里在简单和工厂的基础上写工厂:

先定义一个接口

1 package cn.no5.factorymethod;
2 
3 import cn.no1.simplefactory.Operation;
4 
5 public interface IFactory {
6 
7     Operation CreateOperation();
8 }

再定义其子类:

 1 package cn.no5.factorymethod;
 2 
 3 import cn.no1.simplefactory.Operation;
 4 import cn.no1.simplefactory.OperationAdd;
 5 import cn.no1.simplefactory.OperationSub;
 6 import cn.no1.simplefactory.OperationMultiply;
 7 import cn.no1.simplefactory.OperationDivide;
 8 
 9 public class AddFactory implements IFactory {
10 
11     @Override
12     public Operation CreateOperation() {
13         return new OperationAdd();
14     }
15 
16 }
17 public class SubFactory implements IFactory {
18 
19     @Override
20     public Operation CreateOperation() {
21         return new OperationSub();
22     }
23 
24 }
25 public class MultiplyFactory implements IFactory {
26 
27     @Override
28     public Operation CreateOperation() {
29         return new OperationMultiply();
30     }
31 
32 }
33 public class DivideFactory implements IFactory {
34 
35     @Override
36     public Operation CreateOperation() {
37         return new OperationDivide();
38     }
39 
40 }

测试类:

 1 package cn.no5.factorymethod;
 2 
 3 import java.util.Scanner;
 4 
 5 import cn.no1.simplefactory.Operation;
 6 
 7 public class _Test {
 8 
 9     public static void main(String[] args) {
10         Scanner sc = new Scanner(System.in);
11         System.out.println("输入数字1:");
12         double numA = sc.nextDouble();
13         System.out.println("输入数字2:");
14         double numB = sc.nextDouble();
15         System.out.println("输入操作符:");
16         String operator = sc.next();
17         sc.close();
18         IFactory operFactory = null;
19         switch (operator) {
20         case "+":
21             operFactory = new AddFactory();
22             break;
23         case "-":
24             operFactory = new SubFactory();
25             break;
26         case "*":
27             operFactory = new MultiplyFactory();
28             break;
29         case "/":
30             operFactory = new DivideFactory();
31             break;
32 
33         }
34         Operation oper = operFactory.CreateOperation();
35         oper.setNumA(numA);
36         oper.setNumB(numB);
37         double result = oper.calculate();
38         System.out.println("计算结果是:"+result);
39     }
40 }

现在应该可以发现简单工厂和工厂方法的区别了:

工厂方法比简单工厂麻烦多了?这种感性的回答可不能算数,得从流程上分析它们的区别。

简单工厂:客户端无需判断创建哪个实例对象,但是需要把符号数据传入简单工厂,简单工厂根据传入的符号返回实例对象。

工厂方法:客户端需要根据符号判断创建哪个工厂对象,所以无需再传入什么符号,工厂对象直接调用方法返回实例对象。

考虑两个场景:

1、需要创建10个加法实例:

如果你使用简单工厂,你需要传10次符号(比如10次“+”)给简单工厂,既然知道都是加法,干嘛还要重复传10次”+“?!不好意思,客户端不考虑这些,他只负责给工厂传参数就能得到实例;

如果你使用工厂方法,直接创建加法工厂,调用其生产方法10次即可。

这下简单工厂的使用范围也就清楚了。就是在比较简单的情况下使用简单工厂。比如计算器。客户端只操作一次,得到一个运算实例,但谁也不知道用户要输入什么操作符号,索性把符号丢给简单工厂。

2、需要添加numA的numB次方业务逻辑

使用简单工厂,需要扩展运算类,并且修改简单工厂类的createOperation方法。

使用工厂方法,需要扩展运算类和工厂类。

简单工厂在业务逻辑改变时对自身方法进行了修改,违背了开放-封闭原则

工厂方法克服了简单工厂违背开放-封闭原则的缺陷

原文地址:https://www.cnblogs.com/tomasman/p/6851755.html