23种设计模式之简单工厂

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

最容易想到的写法是:


 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段代码的第二段几乎是一样的,代码就足够通用了。

 

时间: 2024-10-29 03:24:49

23种设计模式之简单工厂的相关文章

23种设计模式(2)-简单工厂模式

这些设计模式都是在这么多年的软件开发中,先辈对软件重构的经验总结提炼的结果,这些设计模式要遵循软件设计的六原则.每一种设计模式都有相应的需求场景的.有了这些设计模式的思想和面向对象的思想,在软件设计特定的需求中会给你解决思路. 一,需求场景 在此,我也借用书上看到的一个例子.计算器工厂给我们留了一些任务,设计一个计算器做成成品卖给买家.但是这个任务是分两个阶段让我们实现的.如下: 阶段一:买家目前只需要计算器具有加减程序的功能即可.别的功能待市场需求再做设计.也就是阶段二的任务. 阶段二:阶段一

23种设计模式之简单工厂模式

模式是基于在面对对象的思想上实现的计算机编程模式思维面对对象的模式思维有四大好处:可维护,可复用,可拓展,灵活性好基于三个步骤,封装,继承,多态举个例子:计算机要完成两个数字之间的运算一.就要考虑到定义一个可被继承类1.需要两个数的字段并且将之属性化2. 一个virtual的虚方法在每一个运算方法中都可以实现调用 二.要将运算的方法类继承,完成运算方法 三.创建工厂类,将根据运算符号来判断使用哪种运算类 四.在客户端中使用多态调用工厂类,输出结果就OK了 具体代码如下: 原文地址:https:/

重头开始学23种设计模式:三大工厂(简单工厂,工厂方法,抽象工厂)

在开发当中我们经常会使用三个设计模式,来帮我们解决项目代码的可扩展性. 在简单工厂,工厂方法,抽象工厂这三个设计模式当中,代码其实都很简单,主要是要理解运用. 简单工厂: 简单工厂说白了,就是利用Switch根据传递的参数,进行实例化. 工厂方法: 工厂方法,为解决每次都去增加Swicth的简单工厂的升级.为每一个产品提供一个工厂类. 抽象工厂: 抽象工厂,我觉得也是对工厂方法的再次升级,工厂方法每次只能创作一个产品,而抽象工厂就是产品线的产品族. 总结下,从网上找到一个大牛的回复: 我认为不能

设计模式的学习(一)-软件设计模式的概念与意义以及23种设计模式的简单介绍

有关软件设计模式的定义有很多,有些是从模式的作用出发,也写是根据模式的特点,本文根据大多数教材定义,从以下两个方面来说明. 软件模式的概念.软件设计模式(Software Design Pattern),又称设计模式,是一套被反复使用,多数人知晓,经过分类编目.代码设计经验的总结.它描述了在软件设计过程中的一些不断重复发生的问题,以及对该问题的解决方案.也就是说,它是解决特定问题的一系列套路,是前辈们代码设计经验的总结,具有一定的普遍性,可以反复使用.目的是为了提高代码的可重用性,代码的可读性和

23种设计模式[2]:工厂方法模式

一.简单工厂模式(静态工厂方法,不属于23种GOF设计模式之一) 定义:定义一个用于创建产品对象的方法,由该工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例. 类型:创建类模式 public interface SmsService { void sendSms(); } public class MontnetsService implements SmsService { @Override public void sendSms() { Syste

两种设计模式(1)==&gt;&gt;“简单工厂”

我们以做一个计算器为例,给大家介绍简单工厂的应用: 效果: 这里我们使用 继承 ,虚方法, 简单工厂的设计模式来完成 首先,我们除了搭好窗体外,我们应该把我们的一些类准备好: 1.计算的父类Calculation using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 计算器_简单工厂_ { //父类(

23种设计模式之抽象工厂

抽象工厂 当想创建一组密不可分的对象时,工厂方法似乎就不够用了 抽象工厂是应对产品族概念的.应对产品族概念而生,增加新的产品线很容易,但是无法增加新的产品.比如,每个汽车公司可能要同时生产轿车.货车.客车,那么每一个工厂都要有创建轿车.货车和客车的方法 优点:向客户端提供一个接口,使得客户端在不必指定产品具体类型的情况下,创建多个产品族中的产品对象 缺点:增加新的产品等级结构很复杂,需要修改抽象工厂和所有的具体工厂类,对“开闭原则”的支持呈现倾斜性 1 public interface IRac

【Unity与23种设计模式】抽象工厂模式(Abstract Factory)

GoF中定义: "提供一个能够建立整个类群组或有关联的对象,而不必指明它们的具体类." 意思就是 根据不同的执行环境产生不同的抽象类子类 抽象工厂模式经常在面试中会涉及到 下面的例子为工厂1和工厂2 两个工厂都可以生成产品A和B 但是两个工厂工艺不同 所以工厂1只能生产产品A1和B1 工厂2只能生产产品A2和B2 //可生成各抽象成品对象的操作 public abstract class AbstractFactory{ public abstract AbstractProductA

23种设计模式之抽象工厂模式

抽象工厂模式(Abstract Factory):提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. package designMode.abstractFactory; class User { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() {