水边
一只青蛙在笑

      ——石头和水

工厂方法模式(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方法。

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

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

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

Java学习笔记——设计模式之五.工厂方法的更多相关文章

  1. C#设计模式学习笔记:(2)工厂方法模式

    本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7567880.html,记录一下学习过程以备后续查用. 一.引言 接上一篇C#设计模式学习笔记:简单工厂模式( ...

  2. java 23 - 1 设计模式之工厂方法模式

    转载: JAVA设计模式之工厂模式(简单工厂模式+工厂方法模式)

  3. Spring4.0学习笔记(6) —— 通过工厂方法配置Bean

    1.静态工厂方法: bean package com.spring.factory; public class Car { public Car(String brand) { this.brand ...

  4. Java学习笔记——设计模式之一.简单工厂

    蜀道之难.难于上青天,侧身西望长咨嗟 --蜀道难 设计模式第一篇,简单工厂. 定义Operation类 package cn.no1.simplefactory; public abstract cl ...

  5. 0040 Java学习笔记-多线程-线程run()方法中的异常

    run()与异常 不管是Threade还是Runnable的run()方法都没有定义抛出异常,也就是说一条线程内部发生的checked异常,必须也只能在内部用try-catch处理掉,不能往外抛,因为 ...

  6. Java学习笔记——设计模式之二.策略模式

    明确是王道 --Clean Code 先定义策略类 package cn.no2.strategy; public abstract class Strategy { //省略属性 //算法方法 pu ...

  7. 1.8(java学习笔记)继承与方法的重写

    继承 在java中可以通过继承提高代码的复用率. 例如A继承了B,就可以是 例如,首先有一个类似Person,这个类中有有一些属性和方法,我们再新建一个Student类,其中有一部分属性和方法与Per ...

  8. Java学习笔记(六)——方法

    一.方法定义 1.语法: 其中: (1) 访问修饰符:方法允许被访问的权限范围, 可以是 public.protected.private 甚至可以省略 ,其中 public 表示该方法可以被其他任何 ...

  9. 疯狂java学习笔记之面向对象(三) - 方法所属性和值传递

    方法的所属性: 从语法的角度来看:方法必须定义在类中 方法要么属于类本身(static修饰),要么属于实例 -- 到底是属于类还是属于对象? 有无static修饰 调用方法时:必须有主调对象(主语,调 ...

随机推荐

  1. NTP时间服务器

    1. NTP简介 NTP(Network Time Protocol,网络时间协议)是用来使网络中的各个计算机时间同步的一种协议.它的用途是把计算机的时钟同步到世界协调时UTC,其精度在局域网内可达0 ...

  2. 快速找到Office应用程序安装路径

    p{ font-size: 15px; } .alexrootdiv>div{ background: #eeeeee; border: 1px solid #aaa; width: 99%; ...

  3. thinkphp3.2.x多图上传并且生成多张缩略图

    html部分 <!DOCTYPE html><html><head><meta http-equiv="Content-Type" con ...

  4. git clone时出现 error:inflate:data stream error(incorrect data check)

    git clone时出现 error:inflate:data stream error(incorrect data check) fatal:serrious inflate inconsiste ...

  5. 1102: 零起点学算法09——继续练习简单的输入和计算(a-b)

    1102: 零起点学算法09--继续练习简单的输入和计算(a-b) Time Limit: 1 Sec  Memory Limit: 520 MB   64bit IO Format: %lldSub ...

  6. 用 Python 编写剪刀、石头、布的小游戏(快速学习python语句)

    import random#定义手势类型allList = ['石头','剪刀','布']#定义获胜的情况winList = [['石头','剪刀'],['剪刀','布'],['步','石头']]pr ...

  7. css常用技巧集合

    1 不想让按钮touch时有蓝色的边框或半透明灰色遮罩(根据系统而定) /*解决方式一*/ -webkit-tap-highlight-color:rgba(0,0,0,0); -webkit-use ...

  8. dubbo+zipkin调用链监控

    分布式环境下,对于线上出现问题往往比单体应用要复杂的多,原因是前端的一个请求可能对应后端多个系统的多个请求,错综复杂. 对于快速问题定位,我们一般希望是这样的: 从下到下关键节点的日志,入参,出差,异 ...

  9. B/S 和 C/S两种架构

    一: 什么是B/S(Browser/Server)架构? 应用系统完全放在应用服务器上, 并通过应用服务器同数据库服务器进行通信,系统界面 是通过浏览器来展现的. T是浏览器模式. 优点: 1)客户端 ...

  10. 数据库Schema两种含义~~

    1.数据库Schema有两种含义,一种是概念上的Schema,指的是一组DDL语句集,该语句集完整地描述了数据库的结构.还有一种是物理上的 Schema,指的是数据库中的一个名字空间,它包含一组表.视 ...