设计模式--简单工厂模式

来源:互联网 发布:炒外汇软件哪个好 编辑:程序博客网 时间:2024/05/20 20:48

软件工程的课程已经进行很久了,软件设计模式这门课看起来蛮重要的。好好记一下笔记!

这次介绍的是简单工厂模式。

基本解释:

简单工厂模式属于类的创新型模式,又叫作静态工厂方法模式,是通过专门定义一个类来负责创建其他类的实力,被创建的实例通常都具有共同的父类。


深入分析:

简单工厂模式解决的问题是如何去实例化一个合适的对象。

具体来说,把产品看成是一系列类的集合,这些类是由某个抽象类或者接口派生出来的一个对象树。而工厂类用来产生一个合适的对象来满足客户的要求。

如果简单工厂模式所涉及到的具体产品之间没有共同的逻辑,那么我们就可以用接口来扮演抽象产品的角色;如果具体产品之间有功能的逻辑,我们就必须把这些共同的东西提取出来,放在一个抽象类中,然后昂具体产品继承抽象类。为了实现更好复用的目的,共同的东西总是应该抽象出来的。


以下内容摘自《大话设计模式》程杰著,感谢作者的付出:

小菜:计算器这样的小程序还可以用到面向对象三大特性?继承和多态怎么可能用得上?我实在不能理解。

大鸟:小菜很有钻研精神嘛,好,今天我让你功力加深一级。你先考虑一下。你的代码已经可以做到封装,但是能否做到很灵活地修改和扩展呢?

小菜:我已经把业务和界面分离了呀,这不是很灵活了吗?

大鸟:那我问你,现在我如果我希望建立一个开根号运算,你怎么改?

小菜:那只需要改Operation类就行了,在switch中加一个分支就行了。

大鸟:问题是你要加一个平方根运算,却需要让加减乘除的运算都得来参与编译,如果你一不小心,把加法运算改成了减法,这岂不是大大的糟糕。打个比方,如果现在公司要求你为公司的薪资管理系统做维护,原来只有技术人员(月薪),市场销售人员(底薪+提成),经理(年薪+股份)三种运算算法,现在要增加兼职工作人员(时薪)的算法,但你按照昨天的程序写法,公司就必须要把包含原来三种算法的运算类给你,让你修改,如果你心中小算盘一打,TMD,公司给我的工资这么低,我真是郁闷,这下有机会了,于是你除了增加了兼职算法以外,在技术人员(月薪)算法中写了一句

<span style="font-size:12px;">if(员工是小菜){    salary = salary * 1.1;}</span>

那就意味着,你的月薪每月都会增加10%(小心被抓去坐牢),本来是让你增加一个功能,却使得所有运行良好的功能代码产生了变化,这样的风险太大了,你明白了吗?

小菜:噢,你的意思是,我应该把加减乘除等运算分离,修改其中一个不影响另外的几个,增加运算算法也不影响其他的代码,是这样吗?

大鸟:自己想去吧,如何使用继承和多态,你应该有感觉了。


设计类图如下:



Operation运算类:

<span style="font-size:12px;">    public 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()        {            double result = 0;            return result;        }    }</span>


加减乘除类,实例化
<span style="font-size:12px;">    public class OperationAdd : Operation    {        public override double GetResult()        {            double result = 0;            result = NumberA + NumberB;            return result;        }    }    public class OperationSub : Operation    {        public override double GetResult()        {            double result = 0;            result = NumberA - NumberB;            return result;        }    }    public class OperationMul : Operation    {        public override double GetResult()        {            double result = 0;            result = NumberA * NumberB;            return result;        }    }    public class OperationDiv : Operation    {        public override double GetResult()        {            double result = 0;            if (NumberB == 0)                throw new Exception("除数不能为0。");            return NumberA / NumberB;        }    }</span>



从左到右依次为textbox1,textbox2,textbox3,textbox4,button1,button2。

<span style="font-size:12px;">        private void button1_Click(object sender, EventArgs e)        {            Operation oper;            oper = OperationFactory.createOperate(textBox2.Text);            oper.NumberA = Convert.ToDouble(textBox1.Text);            oper.NumberB = Convert.ToDouble(textBox3.Text);            double result = oper.GetResult();            textBox4.Text = Convert.ToString(result);        }        private void button2_Click(object sender, EventArgs e)        {            textBox1.Text = "";            textBox2.Text = "";            textBox3.Text = "";            textBox4.Text = "";        }</span>

简单工厂模式的优缺点分析:

优点:工厂类是整个模式的关键所在。它包含必要的判断逻辑,能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。用户在使用时可以直接根据工厂类去创建所需的实例,而无需了解这些对象究竟是如何创建以及如何组织的,有利于整个软件体系结构的优化。

缺点:由于工厂类几种了所有实例的创建逻辑,这就直接导致一旦这个工厂出了问题,所有的客户端都会收到牵连。而且由于简单工厂模式的产品是基于一个共同的抽象类或接口,这样一来,当产品的种类增加的时候,就有不同的产品接口或者抽象类的时候,工厂类就需要判断何时创建相应种类的产品,这就和创建何种种类产品混淆在了一起,违背了单一职责,导致系统丧失灵活性和可维护性。而且更重要的是,简单工厂模式违背了”开放封闭原则“,就是违背了”系统对扩展开放,对修改关闭“的原则。因为i当我新增肌啊一个产品的时候必须修改工厂类,相应的工厂类就需要重新编译一遍。

总结一下:简单工厂模式分离产品的创建者和消费者,有利于软件系统结构的优化;但是由于一切逻辑都集中在一个工厂类中,导致了没有很高的内聚性,同时也违背了”开放封闭原则“。另外,简单工厂模式的方法一般都是静态的,而静态工厂方法是无法让子类继承了,因此,简单工厂模式无法形成基于基类的继承树结构。



0 0
原创粉丝点击