简单工厂模式

源起

最近在看程杰著作的《大话设计模式》,全书以小菜和大鸟对话的形势,由浅入深的讲解程序的设计思想,影射出一个个设计模式。我之前虽然也使用过一些设计模式,但没有系统的学习、整理、总结,现从该书入手,拟补自己技术领域的一块空白。该书虽以C#语言为基础,但对Java程序猿来说,却不影响阅读。本专栏记录自己学习设计模式的过程及自己的认识,争取从小菜蜕变成大鸟。

定义

从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式。

需求

使用Java来编写一个计算器控制台程序,要求输入两个数和运算符号,得到结果。

实现

 

级别1

 

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
 
  1. import java.util.Scanner;  
  2.    
  3. public class Operateion{  
  4.    
  5.          public static void main(String[] args) {  
  6.                    Scanner scanner = new Scanner(System.in);  
  7.                    try{  
  8.                             do{  
  9.                                      System.out.println("输入数字A:");  
  10.                                      double numA = scanner.nextDouble();  
  11.                                      System.out.println("输入运算符(+、-、*、/):");  
  12.                                      Stringoperate = scanner.next();  
  13.                                      System.out.println("输入数字B:");  
  14.                                      double numB = scanner.nextDouble();  
  15.                                      double result = 0;  
  16.                                      if(operate.equals("+"))  
  17.                                                result = numA + numB;  
  18.                                      else if (operate.equals("-"))  
  19.                                                result = numA - numB;  
  20.                                      else if (operate.equals("*"))  
  21.                                                result = numA * numB;  
  22.                                      else if (operate.equals("/") && numB != 0)  
  23.                                                result = numA / numB;  
  24.                                      else if (numB == 0)  
  25.                                                System.err.println("除数不能为0!");  
  26.                                      else  
  27.                                                System.err.println("运算符输入有误!");  
  28.                                      System.out.println("运算结果为:"+ result);  
  29.                                      System.out.println("是否继续操作(Y/N):");  
  30.                             }while(!scanner.next().equalsIgnoreCase("n"));  
  31.                    }catch (RuntimeException e) {  
  32.                             System.err.println("程序发生异常退出!");  
  33.                    }  
  34.          }  
  35. }  

 

上面的程序实现了最基本的四则运算,并对基本的异常进行了处理,还可以循环运算。假如说我别处也需要一个运算的程序,还需要再写一份,难复用。我们需要一份可以复用的代码!

级别2

 

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
 
  1. import java.util.Scanner;  
  2.    
  3. public class Operation {  
  4.    
  5.          /*客户端代码 */  
  6.          public static void main(String[] args) {  
  7.                    Scanner scanner = new Scanner(System.in);  
  8.                    try{  
  9.                             do{  
  10.                                      System.out.println("输入数字A:");  
  11.                                      double numA = scanner.nextDouble();  
  12.                                      System.out.println("输入运算符(+、-、*、/):");  
  13.                                      String operate = scanner.next();  
  14.                                      System.out.println("输入数字B:");  
  15.                                      double numB = scanner.nextDouble();  
  16.                                      double result = getResult(numA, numB, operate);  
  17.                                      System.out.println("运算结果为:"+ result);  
  18.                                      System.out.println("是否继续操作(Y/N):");  
  19.                             }while(!scanner.next().equalsIgnoreCase("n"));  
  20.                    }catch (RuntimeException e) {  
  21.                             System.err.println("程序发生异常退出!");  
  22.                    }  
  23.          }  
  24.           
  25.          /*计算器代码 */  
  26.          public static double getResult(double numA, double numB, String operate) {  
  27.                    doubleresult = 0;  
  28.                    if(operate.equals("+"))  
  29.                             result = numA + numB;  
  30.                    else if (operate.equals("-"))  
  31.                             result = numA - numB;  
  32.                    else if (operate.equals("*"))  
  33.                             result = numA * numB;  
  34.                    else if (operate.equals("/") && numB != 0)  
  35.                             result = numA / numB;  
  36.                    else if (numB == 0)  
  37.                             System.err.println("除数不能为0!");  
  38.                    else  
  39.                             System.err.println("运算符输入有误!");  
  40.                    returnresult;  
  41.          }  
  42. }  

 

上面的程序将计算器的代码封装到一个方法中,供客户端调用,这样如果存在多个客户端,只需要调用这个方法即可,实现了代码的可复用。那么现在我们把这个工具类编译后,其他人就可以使用了,假如说现在需要添加一个新算法,求A的B次方,我们就需要修改这个类的源代码,在getResult中加入新的分支,然后重新编译,供客户端使用,难扩展。

级别3

 

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
 
  1. public abstract class Operation {  
  2.   
  3.     protected double numA;  
  4.       
  5.     protected double numB;  
  6.       
  7.     public double getNumA() {  
  8.         return numA;  
  9.     }  
  10.   
  11.     public void setNumA(double numA) {  
  12.         this.numA = numA;  
  13.     }  
  14.   
  15.     public double getNumB() {  
  16.         return numB;  
  17.     }  
  18.   
  19.     public void setNumB(double numB) {  
  20.         this.numB = numB;  
  21.     }  
  22.   
  23.     public abstract double getResult();  
  24. }  

 

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
 
  1. /* 加法 */  
  2. public class AddOperation extends Operation {  
  3.   
  4.     @Override  
  5.     public double getResult() {  
  6.         return numA + numB;  
  7.     }  
  8.   
  9. }  

 

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
 
  1. /* 减法 */  
  2. public class SubOperation extends Operation {  
  3.   
  4.     @Override  
  5.     public double getResult() {  
  6.         return numA - numB;  
  7.     }  
  8.   
  9. }  

 

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
 
  1. /* 乘法 */  
  2. public class MulOperation extends Operation {  
  3.   
  4.     @Override  
  5.     public double getResult() {  
  6.         return numA * numB;  
  7.     }  
  8.   
  9. }  

 

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
 
  1. /* 除法 */  
  2. public class DivOperation extends Operation {  
  3.   
  4.     @Override  
  5.     public double getResult() {  
  6.         if(numB == 0)  
  7.             throw new RuntimeException("除数不能为0!");  
  8.         return numA / numB;  
  9.     }  
  10.   
  11. }  

 

上面的代码先创建了一个抽象类Operation,然后创建了加减乘除四个子类,分别实现其运算方法,如果以后需要修改某种运算,只需要去修改相应的类即可,如果需要增加某种运算,只需要去实现Operation的getResult方法即可,那么,我们还需要一个创建运算类的工厂。

 

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
 
  1. public class OperationFactory {  
  2.   
  3.     public static Operation createOperation(String operate) {  
  4.         Operation op = null;  
  5.         if(operate == null)  
  6.             throw new RuntimeException("运算符不能为空!");  
  7.         else if(operate.equals("+"))  
  8.             op = new AddOperation();  
  9.         else if(operate.equals("-"))  
  10.             op = new SubOperation();  
  11.         else if(operate.equals("*"))  
  12.             op = new MulOperation();  
  13.         else if(operate.equals("/"))  
  14.             op = new DivOperation();  
  15.         else  
  16.             throw new RuntimeException("运算符错误!");  
  17.         return op;  
  18.     }  
  19.       
  20. }  

 

客户端代码

 

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
 
  1. public class OperationTest {  
  2.   
  3.     public static void main(String[] args) {  
  4.         Operation op = null;  
  5.         Scanner scanner = new Scanner(System.in);  
  6.         try {  
  7.             do {  
  8.                 System.out.println("输入数字A:");  
  9.                 double numA = scanner.nextDouble();  
  10.                 System.out.println("输入运算符(+、-、*、/):");  
  11.                 String operate = scanner.next();  
  12.                 System.out.println("输入数字B:");  
  13.                 double numB = scanner.nextDouble();  
  14.   
  15.                 op = OperationFactory.createOperation(operate);  
  16.                 op.setNumA(numA);  
  17.                 op.setNumB(numB);  
  18.                   
  19.                 double result = op.getResult();  
  20.                 System.out.println("运算结果为:" + result);  
  21.                 System.out.println("是否继续操作(Y/N):");  
  22.             } while(!scanner.next().equalsIgnoreCase("n"));  
  23.         } catch (RuntimeException e) {  
  24.             System.err.println("程序发生异常退出!");  
  25.             e.printStackTrace();  
  26.         }  
  27.     }  
  28.   
  29. }  

 

将创建对象的工作交给工厂负责,使客户端调用和运算类解耦,当我们更改运算类时,客户端代码不会受到影响,也不需要修改。同时将计算器程序中的多个分支判断拆成了各个类,当分支判断中逻辑过于复杂时,这样做是非常好的。使用面向对象语言的特性(封装、继承、多态),以优雅的方式解决了可复用、可维护、可扩展等问题。

UML

总结

一个小小的计算器程序竟然可以写的这么perfect,编程是一门技术,更是一门艺术。在编写代码的过程中,要牢记可复用、易维护、好扩展,这样,自己才能有所提高,才是真正的软件工程师。

基于STM32的简易电压、频率、占空比测量仪 任务详解:我们需要实现三个功能: 第一个是测频率的功能,输入信号为频率为1kHz~10kHz的三种波形(方波、三角波、正弦波),这也是我们最常见的三种波形。幅度是不需要测量的,所以先不关心幅度。 第二个是电压报警功能,当输入信号的幅度超过15V时,我们需要报警(这里我用了一个红色LED当报警器,有条件的还可以加个蜂鸣器)并且把此时的信号幅度显示在OLED屏幕上。 第三个是通信方式的要求,需要有串口通信功能。 第四个是计算占空比的任务,这个任务的输入是幅度为1V~10V、频率为20Hz ~1kHz的方波,需要 阅读详情

相关推荐

MBIST --- PATR1.Memorybist测试原理

mem bist作为现在design设计中不可或缺的DFT设计内容,越发重要。本章节主要介绍mem bist组成部分,测试的原理以及注意事项。

sinat_27691203的博客 1万+

程杰“大话设计模式”中的设计原则

依赖倒置其实可以说是面向对象设计的标志,用哪种语言来编写程序不重要,如果编写时考虑的都是如何针对抽象编程而不是针对细节编程,即程序中所有的依赖关系都是 终止于抽象类或者接口,那就是面向对象的设计,反之那就是过程化的设计了。软件设计真正要做的许多内容,就是发现职责并把那些职责相互分离,如果你能够想到多余一个的动机去改变一个类,那么这类就具有多于一个的职责,这时就应该考虑类的职责分离。类之间的耦合越弱,越有利于复用,一个处在弱耦合的类被修改,不会对有关系的类造成波及。迪米特法则的根本思想是强调类之间的松耦合。

qfturauyls的博客 1992

VFH避障/局部路径规划算法

VFH避障/局部路径规划算法 本文章是我看《The Vector Field Histogram-Fast Obstacle Avoidance for Mobile Robots》论文时候的笔记,感兴趣的欢迎去看原论文。 VFH中有一些概念是从其他算法中借鉴过来的,并且VFH算法本身就是对VFF(Virtural Force Field)的一种改进,其中有很多的相似之处。所以按照原论文的思路,先介绍由CMU提出的Certainty Grid算法中的一些概念,再介绍一下势场法中的一些概念,接着介绍一下VFF

qq_41845878的博客 8120

设计模式 总结 根据《大话设计模式》程杰 整理

1.简单工厂模式 用一个单独的类来创造实例。 2. 策略模式(Strategy) 定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。  主要用于:需要在不同时间应用不同的业务规则,就可以考虑用策略模式处理这种变化的可能性。 3.单一职责原则(SRP):就一个类而言,应该仅有一个引起它变化的原因。    若一个类承担的职责过多,就等于

ChallenChenZhiPeng的专栏 2660

腾讯云运维工程师认证TCA--真题(最新2022.11)

解析:云原生应用的12要素,1.基准代码:一份基准代码,多份部署;解析:腾讯云主账号具备对其名下资源(包括存储桶)的最大权限,您虽然可以在存储桶策略中限制几乎所有操作,但主账号始终具备 PUT Bucket Policy 操作的权限,主账号调用该操作不检查存储桶策略。解析:瀑布模型将软件生命周期划分为制定计划、需求分析、软件设计、程序编写、软件测试和运行维护等六个基本活动,并且规定了它们自上而下、相互衔接的固定次序,如同瀑布流水,逐级下落。解答:云原生五大关键技术:微服务、容器化、DevOps、持续交付。

e1210101的博客 9915

手把手教你用分立元件搭建自举电路:解决高端MOS驱动难题

本文详细介绍了如何用分立元件搭建自举电路,解决高端MOS驱动中的栅源极电压不足问题。通过面包板实验,逐步讲解二极管、电容等关键元件的选型与电路搭建,提供波形调试和常见问题排查方法,帮助工程师提升开关电源和电机驱动等应用的效率与可靠性。

weixin_30555125的博客 153

【学习笔记】UML类图(程杰-大话设计模式)

《大话设计模式》1.9节,UML类图学习笔记。

野生C++程序员 574

【Google Play 上架】内部 / 封闭 / 开放 测试全解 — “只跑一个就能上架”?不行!

Google Play新规要求个人开发者账号在2023年11月13日后必须通过封闭测试(Closed testing)才能上架应用。封闭测试需要至少12名测试者连续14天保持参与状态,而内部测试和开放测试不能替代这一要求。三类测试轨道各有特点:内部测试用于快速内部验证,封闭测试是上架必经环节,开放测试面向更广泛用户但非必需。上架流程建议先内部测试修复问题,再启动封闭测试满足14天要求,最后申请生产发布。组织账号和早期个人账号可能不受此限制。开发者应提前规划测试人群,确保持续测试周期,并关注Play Cons

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 2801

设计模式之工厂模式

工厂模式 1、简单工厂模式 1.1、定义 简单工厂模式(Simple Factory Pattern)是指有一个工厂对象决定创建出哪一种产品类的实例,不属于23种设计模式。 简单工厂是产品的工厂 1.2、应用场景 简单工厂模式适用于工厂类创建的对象较少的场景,且客户端只需要传入工厂参数,对如何创建对象的逻辑不需要关心。 1.3、缺点 工厂类的职责相对过重,增加新的产品时需要修改工厂类的判断逻辑,违背了开闭原则。 不易于扩展过于复杂的产品结构。 1.4、实例 支付接口规范: public interface

aaa31203的博客 16万+

药物代谢仿真软件:PKSim_(6).案例研究与实践应用

通过本章的案例研究和实践应用,我们展示了如何利用PKSim软件构建药物动力学模型、进行参数估计、仿真预测和结果分析。这些方法不仅有助于优化药物代谢研究过程,还可以在药物研发中提供重要的数据支持。通过模型的构建和验证,我们可以更好地理解药物在体内的动态变化过程,为临床试验和药物治疗提供科学依据。

kkchenjj的博客 655

4.6 知识库使用指南:如何让AI Agent拥有专业知识

本文介绍了如何为AI Agent构建和使用知识库。知识库的作用是为Agent提供专业知识,包含文档、数据和规则,可用于专业问答和知识检索。使用方法包括创建知识库(上传文档)、向量化处理、知识检索以及在Agent中的应用。核心要点是理解知识库的价值和使用流程。文章还提出了构建方法、检索优化和应用实践等思考题,建议准备高质量数据、优化检索效果并持续更新知识库。下节将介绍用LangGraph构建复杂AI应用。

yonggeit的博客 3013

简单工厂模式(静态工厂方法模式)

目录 定义 为什么要使用工厂模式 模式结构 模式分析 实例 简单工厂模式的优点 简单工厂模式的缺点 适用环境 总结 定义 简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是...

心猿意碼 9489

华为OD机试双机位C卷-魔法收积木 (C/C++/Py/Java/Js/Go)

华为OD机试(机考)双机位C卷 【魔法收积木】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为od - 魔法收积木。

qq_45776114的博客 1941

深入理解设计模式-简单工厂模式(静态工厂方法模式)

文章目录一、定义二、使用场景三、代码样例1.需求2.类图3.运算操作类4.操作工厂类5.客户端类四、优缺点结尾 一、定义 简单工厂模式是属于创建型模式,在简单工厂模式中用于被创建实例的方法通常为静态(static)方法,因此又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。 二、使用场景 工厂类负责创建的对

少说,多做 1万+

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

创建型模式-简单工厂模式(静态工厂方法模式)

目录 1. 简单工厂模式概述 1.1 概念 1.2角色 1.3 类图 2. 简单工厂模式创建原理 3. 简单工厂模式的优缺点 3.1 优点 3.2 缺点 3.3 使用场景 1. 简单工厂模式概述 1.1 概念 简单工厂模式又称为静态工厂方法模式。将一个具体类的实例化交给一个静态工厂方法来执行定义一个类,根据参数的不同返回不同的类的实例。这些类具有公共的...

云上道人的博客 569

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

简单工厂模式(C++描述)

一.简单工厂模式又称静态工厂方法模式(Static Factory Method),它不是Gof 所讲的23种设计模式之一,但是它却是我们在编码过程中经常使用的方法之一。 1.静态工厂方法统一管理对象的创建。静态工厂方法通过传入的参数判断决定创建哪一个产品的实例,封装了对象的创建,客户端只管消费,实现了对责任(模块)的分割。2.静态工厂方法推迟了产品的实例化。通过XML配置文件就能改变

一步一步 1万+

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

java静态工厂方法与工厂模式

静态工厂方法和工厂模式很像,但是在java中还是有很大区别的。(一)静态工厂方法vs工厂模式对于一个类来说,为了让客户端获得一个自身的实例,最常用的方法就是提供一个公有的构造器。除了这种使用构造器的方法之外,对于单个类来说,我们可以定义静态工厂方法来获取自身的类的一个实例。静态工厂方法和工厂模式的不同也体现在此,静态工厂方法是获取这个类自身的一个实例,他的存在是为了更好的描述和处理这个类。而工厂模式

往事散云烟,十寸光阴换一钱 9103

简单工厂模式(静态工厂方法(Static Factory Method)模式)

简单工厂模式 所谓的简单工厂模式-----------这里百度百科里面的解释:简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工引用百度厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。 简单点说就是一个工厂类根据传入

sundaysunshine的博客 1733

android 静态工厂方法,Android 源码中的静态工厂方法

我们知道工厂模式有三兄弟,通常我们说的工厂模式指的是工厂方法模式,它的应用频率最高。本篇博客分享的简单工厂模式是工厂方法模式的“小弟”,确切的来讲它不属于设计模式,而是一种方法。此外,工厂方法模式还有一位“大哥”——抽象工厂模式。今天我们来分享一下简单工厂模式的一些情况,以及它在Android源码中的应用。定义简单工厂模式是类的创建模式,又叫做静态工厂方法(Static Factory Metho...

weixin_39616547的博客 138

Java 设计模式之静态工厂方法模式

静态工厂方法模式,又称为简单工厂模式,是最简单最易理解的工厂模式,本文通过一个 “月饼” 例子,一起来学习下这种设计模式吧!

牛角尖 2442

设计模式-简单工厂模式/静态工厂方法(Static Factory Method)

定义 简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。 优点 工厂类是整个模式的关键.包含了必要的逻辑判断,根据外界给定的信息,决定究竟应该创建哪个具体类的对象.通过使用工

Robert学习分享 2395
上一篇: 策略模式
下一篇: 代理模式
weixir123
博客等级 码龄16年 1粉丝 207原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值