zoukankan      html  css  js  c++  java
  • 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方法。

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

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

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

  • 相关阅读:
    Codeforces1101G (Zero XOR Subset)-less 【线性基】【贪心】
    Codeforces1101F Trucks and Cities 【滑动窗口】【区间DP】
    HDU4651 Partition 【多项式求逆】
    BZOJ2554 color 【概率DP】【期望DP】
    codeforces1101D GCD Counting 【树形DP】
    codechef EBAIT Election Bait【欧几里得算法】
    BZOJ2434 [NOI2011] 阿狸的打字机 【树链剖分】【线段树】【fail树】【AC自动机】
    codeforces1093G Multidimensional Queries 【线段树】
    BZOJ3277 串 【后缀数组】【二分答案】【主席树】
    AHOI2013 差异 【后缀数组】
  • 原文地址:https://www.cnblogs.com/tomasman/p/6851755.html
Copyright © 2011-2022 走看看