笑说设计模式-小白逃课被点名

工厂模式(Factory Pattern)是最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,而是通过使用一个共同的接口来指向新创建的对象。

分类

工厂模式可以分为三种,其中简单工厂一般不被认为是一种设计模式,可以将其看成是工厂方法的一种特殊。

简单工厂

工厂方法

抽象工厂

场景分析

平凡枯燥的文字总是让人看得想睡觉,接下来我们用几个情景案例来进行分析

简单工厂

直接通过一个Factory【工厂类】类创建多个实体类的构造方式。

时间:2021年2月19日 地点:教室 人物:学生小白、老师、大佬黑皮

小白是一名大二的计算机系学生,懒惰不爱学习。今天早晨第一节课就因为睡懒觉迟到被老师逮个正着,这节课还正好是小白最头疼的上机课"C#设计模式”。这不,课堂上到一半老师就开始提问,小白“光荣”的成为了老师的点名对象。

老师笑着说道:“小白,请你解答一下屏幕上的问题。”

题目:请使用c#、java、python、php或其他任一面向对象编程语言实现输入俩个合法数字和一个合法符号,输出对应结果的功能。

小白一看,这算什么题目,这么简单,看我不手到擒来,伴随着双手噼里啪啦一顿敲击声音,屏幕上出现一串编码。

**Calculator操作类 **

public class Calculator { public double GetResult(double A, double B, string operate) { double result = 0d; switch (operate) { case "+": result = A + B; break; case "-": result = A - B; break; case "*": result = A * B; break; case "http://www.likecs.com/": result = A / B; break; default: break; } return result; } }

客户端代码

class Program { static void Main(string[] args) { Console.WriteLine("请输入数字A"); string a = Console.ReadLine(); Console.WriteLine("请输入数字B"); string b = Console.ReadLine(); Console.WriteLine("请选择操作符号(+、-、*、/)"); string operate = Console.ReadLine(); Calculator box = new Calculator(); double result = box.GetResult(Convert.ToDouble(a), Convert.ToDouble(b), operate); Console.WriteLine(result); Console.ReadKey(); } }

小白:”老师,我写好了“

老师:"不错,写的很好。使用到了面向对象三大特性中的封装,将计算方法封装成了一个计算类,多个客户端可以复用这个类。但是这其中也有不少的问题,哪位同学来回答一下。"

黑皮:”小白同学写的代码有俩处问题。

1、如果输入A=10,B=0,程序就会报错,没有做输入的有效性验证

2、如果操作符号不按照规定的输入 ,也会导致报错“

老师:”黑皮同学回答的非常好,但是这都只是针对代码业务逻辑错误的描述。有没有谁可以看出更加深层次的内容。“

黑皮:”老师,你给点提示吧。“

老师:”这个可以会有点隐蔽,老师就给出一点提示。如果我们增加一个新的运算怎么办?“

小白立即回答到:”在switch中增加一个新的分支就可以了“。

老师:”这样当然是没有错误的,但是问题在于,我只是增加了一个新的运算符号,却需要让加减乘除所有的运算都参加编译,如果在修改的过程中不小心修改了其他的代码,例如把+号改成了-号,那不是很糟糕,这就违背了开闭原则【对扩展开放,对修改关闭】“

小白挠一挠头问道:”开闭原则,这是什么?“

老师:”这就是你不认真听课落下的内容,回去好好补习。黑皮同学,不知道你Get到了老师的点没有?“

黑皮:”我知道应该如何修改了。小白实现了面向对象三大特性之一的封装,其实就是将其他俩个特性一起使用就可以完成老师要的功能“

小白:”多态和继承?“

黑皮:”是的,等我改完你再看程序就应该有感觉了“

public class Operate { public double NumberA { get; set; } public double NumberB { get; set; } public virtual double GetResult() { return 0; } } public class OperateAdd : Operate { public override double GetResult() { return this.NumberA +this.NumberB; } } public class OperateSub : Operate { public override double GetResult() { return this.NumberA - this.NumberB; } }

简单工厂

public class OperateFactory { public static Operate GetOperateFactory(string operate) { Operate fac = null; switch (operate) { case "+": fac = new OperateAdd(); break; case "-": fac = new OperateSub(); break; case "*": fac = new OperateMul(); break; case "http://www.likecs.com/": fac = new OperateDiv(); break; default: break; } return fac; } }

黑皮:”首先是一个运算类,里面有俩个Number属性和一个虚方法GetResult()。加减乘除四个方法作为运算类的子类继承,继承后重写GetResult()方法,调用基类的A和B公有属性进行不同的数学运算。“

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wppgpj.html