博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式培训之二:简单工厂、工厂方法
阅读量:4667 次
发布时间:2019-06-09

本文共 3873 字,大约阅读时间需要 12 分钟。

查看本人文章索引请通过

一、简单工厂和工厂方法定义:

简单工厂模式是由一个工厂类根据参数来决定创立出哪一种产品类的实例。

工厂方法模式通过调用不同的方法返回需要的类,而不是去实例化具体的类。 对实例创建进行了包装。 工厂方法是一组方法, 他们针对不同条件返回不同的类实例,这些类一般有共同的父类。

工厂方法模式实施一种按需分配的策略, 即传入参数进行选择, 工厂方法根据参数进行选择,返回具体的实例。

 

二、实例讲解:实现加减乘除

程序需求:

处理两个数的+,-,*,/等运算

 

1. 是面向过程的实现方法:

string strResult = "";            switch (Operate)            {                case "+":                    strResult = Convert.toString(Convert.ToDouble(NumA) + Convert.ToDouble(NumB));                    break;                case "-":                    strResult = Convert.toString(Convert.ToDouble(NumA) - Convert.ToDouble(NumB));                    break;                case "*":                    strResult = Convert.toString(Convert.ToDouble(NumA) * Convert.ToDouble(NumB));                    break;                case "/":                    if (NumB != 0)                    {                        strResult = Convert.toString(Convert.ToDouble(NumA) + Convert.ToDouble(NumB));                    }                    else                    {                        strResult = "除数不能为0";                    }                    break;            }

当增加需求时,例如:增加开方运算,这时我们需要更改上面switch的代码。如果再增加需求,还要更改switch代码。这样的代码很难维护。

健壮的设计应该是易扩展,不修改原有代码(或尽量减少修改原有代码)。

应对变化的运算方式,简单工厂就是一个很简单,好用的模式,下面是简单工厂的实现

 

2. 用简单工厂实现:

ULM图:

s

public abstract class Operation{    public double NumA { get; set; }    public double NumB { get; set; }    public abstract double GetResult();}public class OperationAdd : Operation{    public override double GetResult()    {        return NumA + NumB;    }}public class OperationSub : Operation{    public override double GetResult()    {        return NumA - NumB;    }}

工厂类:

public class Factory{    public Operation Create(string ope)    {        Operation operation=null;        switch(ope)        {        case "+":        operation=new OperationAdd();        break;        case "-":        operation=new OperationSub();        break;        }        return operation;    }}

 

客户端调用:

Operation oper;oper=new Factory().Create("+");oper.NumA=1;oper.NumB=2;double result=oper.GetResult();

这时在客户端代码就没有switch代码,现在的switch代码也没有运算逻辑。运算逻辑在GetResult()方法中。

当再有新需求时,我就可以增加子类(继承自Operation),在子类的GetResult方法中设置运算规则。现在只需在switch中增加一个case返回增加子类实例的代码。

简单工厂是一个不完美的模式,因为它还是修改了switch代码。

 

3 用工厂方法实现:

应对上面的需求也可以使用工厂方法模式,工厂方法使一个类的实例化延迟到其子类。

UML图:

public interface IFactory    {        Operation Create();    }    public class AddOperation : IFactory    {        public Operation Create()        {            return new OperationAdd();        }    }    public class SubOperation : IFactory    {        public Operation Create()        {            return new OperationSub();        }    }    public abstract class Operation    {        public double NumA { get; set; }        public double NumB { get; set; }        public abstract double GetResult();    }    public class OperationAdd : Operation    {        public override double GetResult()        {            return NumA + NumB;        }    }    public class OperationSub : Operation    {        public override double GetResult()        {            return NumA - NumB;        }    }

 

客户端:

IFactory factory = new AddOperation();Operation oper = factory.Create();oper.NumA = 3;oper.NumB = 2;double result = oper.GetResult();

 

在客户程序中,我们有效地避免了具体产品对象和应用程序之间的耦合,可是我们也看到,增加了具体工厂对象和应用程序之间的耦合。

当我们由加号操作变成减号操作时,只需要改动一处就可以了,其他地方都不用改。

IFactory factory = new SubOperation();Operation oper = factory.Create();oper.NumA = 3;oper.NumB = 2;double result = oper.GetResult();

 

当然这样的话,我们还是改动代码,这时候可以利用.NET反射机制来消除它,这样改动时,只需要改动配置文件就可以了

客户端代码:

string factoryName = ConfigurationSettings.AppSettings["factoryName"]; IFactory factory = (IFactory)Assembly.Load("BLL").CreateInstance("BLL." + factoryName);Operation oper = factory.Create();oper.NumA = 3;oper.NumB = 2;double result = oper.GetResult();

 

转载于:https://www.cnblogs.com/seesea125/archive/2012/05/02/2478981.html

你可能感兴趣的文章
C++常量的引用 const
查看>>
51nod 1101 换零钱 【完全背包变形/无限件可取】
查看>>
python单例设计模式(待补充)
查看>>
Binary Tree Inorder Traversal
查看>>
HDU 1394 Minimum Inversion Number (数据结构-线段树)
查看>>
ansible-playbook && Roles && include
查看>>
String s String s=null和String s="a"区别
查看>>
[Alpha阶段]第二次Scrum Meeting
查看>>
关于Java 8 forEach
查看>>
.NET设计模式(1):1.1 单例模式(Singleton Pattern)
查看>>
创建模态对话框和非模态对话框
查看>>
08-图8 How Long Does It Take
查看>>
二维数组中最大连通子数组
查看>>
java 正则表达式-忽略大小写与多行匹配
查看>>
mac 上亚马逊密钥登录
查看>>
css选择器中:first-child与:first-of-type的区别
查看>>
nopcommerce 二次开发
查看>>
NHibernate入门实例
查看>>
IBM_DS5020磁盘阵列做raid、热备并把盘阵挂在服务器上的步骤
查看>>
svg制作风车旋转
查看>>