设计模式.简单工厂模式(SimpleFactory).pptx
设计模式(Design Pattern),张凯 副教授计算机学院 软件工程系,问题(Problem),实现控制台计算器利用任意一种面向对象的语言要求输入2个数和运算符,得到结果,问题(Problem),static void Main(string args)Console.Write(请输入数字A:);string strNumberA=Console.ReadLine();Console.Write(请选择运算符号(+、-、*、/):);string strOperate=Console.ReadLine();Console.Write(请输入数字B:);string strNumberB=Console.ReadLine();string strResult=;switch(strOperate)case+:strResult=(double.Parse(strNumberA)+double.Parse(strNumberB).ToString();break;case-:strResult=(double.Parse(strNumberA)-double.Parse(strNumberB).ToString();break;case*:strResult=(double.Parse(strNumberA)*double.Parse(strNumberB).ToString();break;case/:if(strNumberB!=0)strResult=(double.Parse(strNumberA)/double.Parse(strNumberB).ToString();else strResult=除数不能为0;break;Console.WriteLine(结果是:+strResult);Console.ReadLine();,问题(Problem),原来的代码可复用吗?,问题(Problem),实现计算器Ctrl+C 和 Ctrl+V维护的时候,带来灾难尽可能的办法去避免重复通过面向对象设计,让数据计算和用户交互方式分开,问题(Problem),class Operation public static double GetResult(double numberA,double numberB,string operate)double result=0;switch(operate)case+:result=numberA+numberB;break;case-:result=numberA-numberB;break;case*:result=numberA*numberB;break;case/:result=numberA/numberB;break;return result;,问题(Problem),问题(Problem),static void Main(string args)try Console.Write(请输入数字A:);string strNumberA=Console.ReadLine();Console.Write(请选择运算符号(+、-、*、/):);string strOperate=Console.ReadLine();Console.Write(请输入数字B:);string strNumberB=Console.ReadLine();string strResult=;strResult=Operation.GetResult(double.Parse(strNumberA),double.Parse(strNumberB),strOperate).ToString();Console.WriteLine(结果是:+strResult);Console.ReadLine();catch(Exception ex)Console.WriteLine(您的输入有错:+ex.Message);,问题(Problem),private void button8_Click(object sender,EventArgs e)if(bOperate)textBox1.Text=;bOperate=false;textBox1.Text=textBox1.Text+(Button)sender).Text;private void button14_Click(object sender,EventArgs e)if(textBox1.Text!=)operate=(Button)sender).Text;numberA=double.Parse(textBox1.Text);bOperate=true;private void button17_Click(object sender,EventArgs e)if(textBox1.Text!=)numberB=double.Parse(textBox1.Text);textBox1.Text=Operation.GetResult(numberA,numberB,operate).ToString();bOperate=true;,bool bOperate=false;double numberA=0;double numberB=0;string operate=;,问题(Problem),这种改变很有效,体现了面向对象的重要原则之一,单一职责原则,问题(Problem),添加平方根运算,问题(Problem),class Operation public static double GetResult(double numberA,double numberB,string operate)double result=0;switch(operate)case+:result=numberA+numberB;break;case-:result=numberA-numberB;break;case*:result=numberA*numberB;break;case/:result=numberA/numberB;break;return result;,问题(Problem),紧耦合 vs 松耦合Switch中添加一个分支,搞定!思考:运算+-*/的代码GetResult是正确的,却需要在修改的时候暴露?如何修改或添加新运算,不影响其它的运算代码?,违背面向对象设计原则:开放封闭原则,问题(Problem),class Operation public static double GetResult(double numberA,double numberB,string operate)double result=0;switch(operate)case+:result=numberA+numberB;break;case-:result=numberA-numberB;break;case*:result=numberA*numberB;break;case/:result=numberA/numberB;break;return result;,面向对象三大特性:继承、封装、多态,问题(Problem),class Operation private double _numberA=0;private double _numberB=0;public double NumberA get return _numberA;set _numberA=value;public double NumberB get return _numberB;set _numberB=value;public virtual double GetResult()return 0;,问题(Problem),/加法类 class OperationAdd:Operation public override double GetResult()double result=0;result=NumberA+NumberB;return result;/减法类 class OperationSub:Operation public override double GetResult()double result=0;result=NumberA-NumberB;return result;,/乘法类 class OperationMul:Operation public override double GetResult()double result=0;result=NumberA*NumberB;return result;/除法类 class OperationDiv:Operation public override double GetResult()double result=0;if(NumberB=0)throw new Exception(除数不能为0。);result=NumberA/NumberB;return result;,问题(Problem),添加新的运算,满足开放封闭原则!,问题(Problem),static void Main(string args)try Console.Write(请输入数字A:);string strNumberA=Console.ReadLine();Console.Write(请选择运算符号(+、-、*、/):);string strOperate=Console.ReadLine();Console.Write(请输入数字B:);string strNumberB=Console.ReadLine();string strResult=;/strResult=Operation.GetResult(double.Parse(strNumberA),double.Parse(strNumberB),strOperate).ToString();if(strOperate=+)OperationAdd add=new OperationAdd();add.NumberA=double.Parse(strNumberA);add.NumberB=double.Parse(strNumberB);strResult=add.GetResult().ToString();Console.WriteLine(结果是:+strResult);Console.ReadLine();catch(Exception ex)Console.WriteLine(您的输入有错:+ex.Message);,问题(Problem),设计带来的新问题:虽然满足了开放封闭原则,单一职责原则,但是对于众多类,客户端使用起来非常不方便,问题(Problem),问题(Problem),class OperationFactory public static Operation createOperate(string operate)Operation oper=null;switch(operate)case+:oper=new OperationAdd();break;case-:oper=new OperationSub();break;return oper;,负责对象创建,问题(Problem),static void Main(string args)try Console.Write(请输入数字A:);string strNumberA=Console.ReadLine();Console.Write(请选择运算符号(+、-、*、/):);string strOperate=Console.ReadLine();Console.Write(请输入数字B:);string strNumberB=Console.ReadLine();string strResult=;Operation oper;oper=OperationFactory.createOperate(strOperate);oper.NumberA=Convert.ToDouble(strNumberA);oper.NumberB=Convert.ToDouble(strNumberB);strResult=oper.GetResult().ToString();Console.WriteLine(结果是:+strResult);Console.ReadLine();catch(Exception ex)Console.WriteLine(您的输入有错:+ex.Message);,只需简单参数即可获得所需对象,实现对象的创建和使用的分离,负责对象使用,主要内容,简单工厂模式(Simple Factory),模式动机模式名称:简单工厂模式(Simple Factory)模式动机:考虑一个简单场景,一个软件系统可以提供多个外观不同的按钮,这些按钮都源自同一个基类,不过在继承基类后不同的子类修改了部分属性从而使得它们可以呈现不同的外观,如果我们希望不需要知道这些具体按钮类的名字,只需要知道按钮类的一个参数,并提供一个调用方便的方法,把该参数传入方法即可返回一个相应的按钮对象。,简单工厂模式(Simple Factory),模式定义 简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,属于类的创建型模式,通过它根据自变量的不同返回不同的类的实例。简单工厂模式专门定义一个类来负责创建其它类的实例,被创建的实例通常都具有共同的父类。,简单工厂模式(Simple Factory),模式结构,简单工厂模式(Simple Factory),模式结构,简单工厂模式(Simple Factory),参与者 Factory:工厂角色,工厂类在客户端的直接控制下(Create方法)创建产品对象。Product:抽象产品角色,定义简单工厂创建的对象的父类或它们共同拥有的接口。可以是一个类、抽象类或接口。ConcreteProduct:具体产品角色,定义工厂具体加工出的对象。,简单工厂模式(Simple Factory),public class OperationFactory public static Operation createOperate(string operate)Operation oper=null;switch(operate)case+:oper=new OperationAdd();break;case-:oper=new OperationSub();break;return oper;,工厂角色,抽象产品角色,具体产品角色,具体产品角色,简单工厂模式(Simple Factory),模式结构,为什么是依赖关系,简单工厂模式(Simple Factory),模式结构,CreateOperate(string operate),return new ConcreteProduct,简单工厂模式(Simple Factory),简单工厂模式的优点如下工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅“消费”产品。简单工厂模式通过这种做法实现了对象创建和使用的分离。客户端代码简洁,无需知道所创建具体产品的类名,只需知道对应的参数,可以减少使用者的记忆量。,简单工厂模式(Simple Factory),简单工厂模式的缺点如下工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。增加了系统中类的数量,增加了系统的复杂度和理解难度。系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,有可能造成工厂逻辑过于复杂,不利于扩展。简单工厂模式通常使用静态工厂方法,造成工厂角色无法形成基于继承的等级结构。,简单工厂模式(Simple Factory),模式应用根据各类算法的密码生成器。根据各类数据进行图表绘制。,Thank You!,