简单工厂模式描述的是,通过类的继承关系,父类(工厂类)与子类(产品类),调用父类中的方法,实际干活儿的是子类中的方法;封装需求的不确定性,做出通用的编程,下面以常用的计算器为例:

最容易想到的写法是:

 1            Console.WriteLine("请输入操作数1:");
 2             double a = double.Parse(Console.ReadLine());
 3             Console.WriteLine("请输入操作符:");
 4             string opt = Console.ReadLine();
 5             Console.WriteLine("请输入操作数2:");
 6             double b = double.Parse(Console.ReadLine());
 7
 8             double result = 0;
 9
10             switch (opt)
11             {
12                 case "+":
13                     result = a + b;
14                     break;
15                 case "-":
16                     result = a - b;
17                     break;
18                 case "*":
19                     result = a * b;
20                     break;
21                 case "/":
22                     if (b == 0)
23                     {
24                         throw new Exception("被除数不能为0");
25                     }
26                     result = a / b;
27                     break;
28             }
29             Console.WriteLine("计算结果是:"+result);

这么写,对于控制台来说基本够用了,但是它有很多的弊病:

1.计算结果是直接输出到控制台,如果要做一个WinForm版呢?(目前只有重新写一遍,不能够重用)

2.这里的case只考虑了基本的四则运算,业务变更后,如果有求平方、求立方、开方等运算呢?(那么只能去改写好的方法,一个项目中只有一处还好说,如果有多处要修改,那就麻烦了,可扩展性太差)
3.这段代码也没有体现面向对象的3大特性:封装、继承、多态。

基于以上的种种弊端,需要修改代码:

首先定义一个父类Operat,在类中不考虑未来是否有四则运算及怎样运算

Operat类
 1 /// <summary>
 2     /// 父类计算方法
 3     /// </summary>
 4     public class Operat
 5     {
 6         public double NumberA { get; set; }
 7         public double NumberB { get; set; }
 8         /// <summary>
 9         /// 构造函数
10         /// </summary>
11         /// <param name="a"></param>
12         /// <param name="b"></param>
13         public Operat(double a,double b)
14         {
15             this.NumberA = a;
16             this.NumberB = b;
17         }
18
19         public virtual double Oper()
20         {
21             double result = 0;
22             return result;
23         }
24     }

只定义了2个操作数和一个计算方法(虚方法,因为这里不知道未来有几个运算)

再定义一个加法类(OperatAdd)来继承它,并实现父类中的计算方法:

OperatAdd类(加法)
 1  class OperatAdd : Operat
 2     {
 3         //构造函数
 4         public OperatAdd(double a,double b):base(a,b)
 5         {
 6
 7         }
 8         /// <summary>
 9         /// 子类重写父类的Oper方法(实现)
10         /// </summary>
11         /// <returns></returns>
12         public override double Oper()
13         {
14             double result = 0;
15             result = NumberA + NumberB;
16             return result;
17         }
18     }

依次定义后面的3个类(减、乘、除)

OperatSub类(减法)
 1 class OperatSub : Operat
 2     {
 3         public OperatSub(double a,double b):base(a,b)
 4         {
 5
 6         }
 7         public override double Oper()
 8         {
 9             double result = 0;
10             result= NumberA - NumberB;
11             return result;
12         }
13     }

OperatMult类(乘法)
 1 class OperatMult:Operat
 2     {
 3         public OperatMult(double a,double b):base(a,b)
 4         {
 5
 6         }
 7         public override double Oper()
 8         {
 9             double result = 0;
10             result= NumberA * NumberB;
11             return result;
12         }
13     }

OperatVision类(除法)

 1 class OperatVision:Operat
 2     {
 3         public OperatVision(double a,double b):base(a,b)
 4         {
 5
 6         }
 7         public override double Oper()
 8         {
 9             double result = 0;
10             if (NumberB==0)
11             {
12                 throw new Exception("被除数不能为0");
13             }
14             result = NumberA / NumberB;
15             return result;
16         }
17     }

这时候,应该考虑的问题是,在业务中,怎样调用这4个子类中的运算方法(简单工厂)

定义一个工厂类,由工厂类根据具体业务去调用具体的子类(产品类)

 1 /// <summary>
 2     /// 工厂类
 3     /// </summary>
 4    public class OperatFactory
 5     {
 6         public Operat JiSuan(double a, string opt, double b)
 7         {
 8             Operat opt1 = null;
 9             //封装了异同业务需求的差异
10             switch (opt)
11             {
12                 case "+":
13                     opt1 = new OperatAdd(a, b);     //产品1(加法)
14                     break;
15                 case "-":
16                     opt1 = new OperatSub(a, b);    //产品2(减法)
17                     break;
18                 case "*":
19                     opt1 = new OperatMult(a, b);   //产品3(乘法)
20                     break;
21                 case "/":
22                     opt1 = new OperatVision(a, b);  //产品4(除法)
23                     break;
24             }
25             return opt1;        //返回父类对象
26         }
27     }

给opt赋不同的运算,工厂类就会去调用相应的子类,执行计算方法,new出相应的产品类,因为子类中都只是 return result;没有考虑这个结果具体显示在那个地方(控制台还是winform中的label),就变得相当灵活了,并返回父类对象。

控制台去使用时,调用工厂类中JiSuan()方法返回父类对象,即可:

 1          Console.WriteLine("请输入操作数1:");
 2             double a = double.Parse(Console.ReadLine());
 3             Console.WriteLine("请输入操作符:");
 4             string opt = Console.ReadLine();
 5             Console.WriteLine("请输入操作数2:");
 6             double b = double.Parse(Console.ReadLine());
 7
 8             OperatFactory factory = new OperatFactory();
 9             Operat opt1 = factory.JiSuan(a, opt, b);
10             Console.WriteLine("计算结果是:{0}", opt1.Oper());
11             Console.ReadKey();

而winform的代码也很类似:

 1             lbResult.Text = "";
 2
 3             lbResult.ForeColor = Color.Red;
 4             lbResult.Font = new Font("宋体", 12);
 5             double a = double.Parse(txtNumber1.Text.Trim());
 6             string opt = cmbOperat.SelectedItem.ToString();
 7             double b = double.Parse(txtNumber2.Text.Trim());
 8
 9             OperatFactory factory = new OperatFactory();
10             Operat oper = factory.JiSuan(a, opt, b);
11             lbResult.Text = oper.Oper().ToString();

可以看出上面2段代码的第二段几乎是一样的,代码就足够通用了。

 

转载于:https://www.cnblogs.com/chens2865/p/3732071.html

23种设计模式之简单工厂相关推荐

  1. 23种设计模式之简单工厂模式,工厂方法模式,抽象工厂模式详解

    工厂模式详解 1. 简单工厂模式 1.1 需求分析 1.2 使用传统方式实现 1.2.1 类图 1.2.2 代码实现 1.2.2.1 新建pizza抽象类 1.2.2.2 希腊披萨实现类 1.2.2. ...

  2. 23种设计模式之-----简单工厂(静态工厂)模式(SimpleFactory Pattern)

    这里引用 https://www.kailing.pub/PdfReader/web/viewer.html?file=24DesignPattern 讲解设计模式一文中的例子. 这个例子很形象而且通 ...

  3. 23种设计模式的简单介绍

    文章目录 23种设计模式 概要 0.简单工厂设计模式 多方法简单工厂 静态方法简单工厂 创造型 单例模式(**Singleton**) 懒汉模式:(以时间换空间) 饿汉模式 (以空间换时间) 工厂方法 ...

  4. 23种设计模式之抽象工厂模式(Abstract Factory Pattern)

    前言:大家好,我是小威,24届毕业生,在一家满意的公司实习.本篇文章将23种设计模式中的抽象工厂模式,此篇文章为一天学习一个设计模式系列文章,后面会分享其他模式知识. 如果文章有什么需要改进的地方还请 ...

  5. 23种设计模式及简单代码

    1. 概述 随着做项目增多不可避免地接触到了设计模式,现在各大文档中呈现的设计模式总共有23种,实际上使用中的肯定比23种多,为了让自己深刻理解设计模式,本博决定自己手写这些设计模式,便于在项目中灵活 ...

  6. java七大设计原则,23种设计模式

    点击查看七大设计原则,23种设计模式 其中 简单工厂.工厂方法.抽象工厂 三种工厂模式中的工厂类的作用基本都是:根据传入的参数创建对应的对象,如果创建的种类太多,那么 简单工厂要写很多 if - el ...

  7. 2.5万字详解23种设计模式—创建型模式(简单工厂、工厂方法、抽象工厂、单例-多线程安全详解、建造者、原型)的详细解读、UML类图

    本文简述了各大设计模式,并通过UML和代码详细说明.本文大约共 2.5W 字,建议收藏.下方是本文的目录: 一.设计模式的认识 二.设计模式的分类 根据其目的 根据范围 三.设计模式的优点 四.设计模 ...

  8. 神了!有人用一个项目把23种设计模式与六大原则融会贯通了

    前言 设计模式分为三类,创建型,结构型和行为型.创建型比较好理解,它抽象了实例化过程,将系统与实例的创建解耦.实例由专门的工厂来创建,从而使系统针对实例的抽象接口编程,不依赖任何具体的实现.结构型和行 ...

  9. 2.5 万字详解:23 种设计模式,阿里京东面试必过

    本文简述了各大设计模式,并通过UML和代码详细说明.本文大约共 2.5W 字,建议收藏.下方是本文的目录: 一.设计模式的认识 二.设计模式的分类 根据其目的 根据范围 三.设计模式的优点 四.设计模 ...

最新文章

  1. 自监督学习(Self-Supervised Learning)多篇论文解读(下)
  2. Keil 二进制数输入宏
  3. svn如何隐藏代码路径_程序员课堂—如何通过改善代码风格来消灭隐藏bug
  4. 如何用python驱动器调用neo4j算法包
  5. iframe 中 js 的 cookie 读写不到的解决办法
  6. Google 出品的 Java 编码规范和编程指南!
  7. jQuery图片自动轮转动画特效
  8. 腾讯视频云黄斌:打造toB的产品与运营体系
  9. centos 开机执行的命令
  10. 连续不等_第九讲 函数的连续性与函数的间断点
  11. python虚拟环境管理工具_Python虚拟环境和包管理工具Pipenv的使用详解--看完这一篇就够了...
  12. MQ的连接是否是线程安全的
  13. Linux下实现多线程异步管道
  14. 重启计算机可以使用什么组合键,死机重启电脑快捷键有哪些
  15. 批量替换 Word 文档前几页
  16. 一年级课程表(4月18日-4月22日)
  17. 最易懂得 鸿蒙 实战 - 真机调试 原子服务
  18. 科技是国之利器,人工智能与机器人发展势不可当
  19. 华厦眼科上市:募资31亿市值393亿 挂靠厦门大学
  20. PTA --- 1032.挖掘机技术哪家强 (20 分)

热门文章

  1. Dcloud HTML5 监听蓝牙设备 调用 原生安卓实现 - aspirant - 博客园
  2. HierarchicalBeanFactory
  3. docker --- 镜像、容器
  4. 2springboot:快速创建springboot项目
  5. Effective_STL 学习笔记(十九) 了解相等和等价的区别
  6. eclipse环境配置、快捷键及基本操作
  7. 《交互式程序设计 第2版》一3.6 关系比较
  8. Java 中参数传递是传值还是引用?
  9. PHP自动测试框架Top 10
  10. 《CLR via C#》读书笔记 之 参数