学无止境,精益求精

十年河东,十年河西,莫欺少年穷

学历代表你的过去,能力代表你的现在,学习代表你的将来

大话设计模式一书中第一个开讲的设计模式是简单工厂模式,关于简单工厂模式大家可参考鄙人的博客:代码无错就是优?简单工厂模式 C#

当然,本篇博客所讲的工厂模式和简单工厂模式还是非常类似的,因此,在进行工厂模式讲解之前,我们有必要重温下简单工厂模式

何为工厂模式?不论是简单工厂模式还是本篇的工厂模式,其工厂类主要负责生产对象,然后通过相应的对象调用相关的方法

在重温简单工厂模式之前,我们再次看下简单工厂模式的UML类图

针对上述的简单工厂模式UML类图,我们得到如下叙述:

1、简单工厂类是和运算类是有关联的(实线加箭头代表关联),简单工厂类的主要功能是生产运算对象

2、运算类用斜体表示,说明运算类为抽象类,运算类有两个属性及一个返回值为 double 的方法

3、加减乘除类继承运算类并实现GetResult()方法。

针对上述三点叙述,我们可用如下代码来实现(如果你还看不懂UML类图,可以参考鄙人博客:UML类图应该怎么看?

    public class 简单工厂类
{
double NumberA, NumberB;
public 简单工厂类() { }
public 简单工厂类(double A, double B)
{
this.NumberA = A;
this.NumberB = B;
}
double Oper = new double();
public double Operate(string 符号)
{
switch (符号)
{
case "+": Oper = new 加法类().GetResult(NumberA, NumberB); break;
case "-": Oper = new 减法类().GetResult(NumberA, NumberB); break;
case "*": Oper = new 乘法类().GetResult(NumberA, NumberB); break;
case "/": Oper = new 除法类().GetResult(NumberA, NumberB); break;
}
return Oper;
}
} public abstract class 运算类
{
public abstract double GetResult(double NumberA, double NumberB);
} public class 加法类:运算类
{
public override double GetResult(double NumberA, double NumberB)
{
return NumberA + NumberB;
}
} public class 减法类 : 运算类
{
public override double GetResult(double NumberA, double NumberB)
{
return NumberA - NumberB;
}
} public class 乘法类 : 运算类
{
public override double GetResult(double NumberA, double NumberB)
{
return NumberA * NumberB;
}
} public class 除法类 : 运算类
{
public override double GetResult(double NumberA, double NumberB)
{
if (NumberB != )
return NumberA / NumberB;
else throw new Exception("被除数不能为零"); }
}
        static void Main(string[] args)
{
double A = ;
double B = ;
string F = "/";
简单工厂类 M = new 简单工厂类(A,B);
double Result = M.Operate(F);
Console.WriteLine(Result);
Console.ReadKey();
}

上述代码是鄙人看着UML类图自己设计的,和博客:代码无错就是优?简单工厂模式 C# 中的设计代码并不一样!当然,这两种代码都准确的表达的简单工厂的理念。有兴趣的也可以看下 代码无错就是优?简单工厂模式 中的代码实现形式。

OK,上述就是简单工厂模式的代码设计方案!

但是简单工厂模式违反了设计模式的开闭原则,所以我们有必要对其进一步优化!

所谓开闭原则:

这个原则其实有两个特性,一个是说对于扩展是开放的,另一个是说,对于修改是封闭的(ASD原则

如何优化呢?

工厂模式闪亮登场...

首先看下工厂模式关于加减乘除的UML类图

额,似乎复杂了很多!

不急,我们慢慢分析,然后再用代码实现!

1、运算工厂接口依赖运算类,加法工厂类依赖加法类,减法工厂类依赖减法类,乘法工厂类依赖乘法类,除法工厂类依赖除法类!(虚线加箭头代表依赖)

2、加减乘除工厂类继承运算工厂接口,加减成熟类继承运算类(三角加实线代表继承)

3、下方的M的N次方类和对应的工厂类是用来扩展的。

那么,分析了UML类图的信息,怎样用代码实现呢?

首先我们来创建左侧部分的五个类(运算类及加减乘除类),如下:

    /// <summary>
/// 运算类
/// </summary>
public class Operation
{
public double NumberA, NumberB;
public virtual double GetResult()
{
return ;
}
} public class Add : Operation
{
public override double GetResult()
{
return NumberA + NumberB;
}
} public class Sub : Operation
{
public override double GetResult()
{
return NumberA - NumberB;
}
} public class Mul : Operation
{
public override double GetResult()
{
return NumberA * NumberB;
}
} public class Div : Operation
{
public override double GetResult()
{
if (NumberB == )
throw new Exception("被除数不能为零");
return NumberA / NumberB;
}
}

其次,我们来构建右侧部分的一个接口及四个类(加减乘除工厂类),如下:

    public interface IFactory
{
Operation GetOperation();
} public class AddFactory : IFactory
{
public Operation GetOperation()
{
return new Add();
}
} public class SubFactory : IFactory
{
public Operation GetOperation()
{
return new Sub();
}
} public class MulFactory : IFactory
{
public Operation GetOperation()
{
return new Mul();
}
} public class DivFactory : IFactory
{
public Operation GetOperation()
{
return new Div();
}
}

客户端代码为:

        static void Main(string[] args)
{
IFactory F = new AddFactory();
Operation AM = F.GetOperation();
AM.NumberA = ;
AM.NumberB = ;
double sum = AM.GetResult();
Console.WriteLine(sum);
Console.ReadKey();
}

最后,我们来运行一下(7+8=15):

写到这儿,我可以自豪的说:如果你要加平方根运算,我只需新增平方根类及平方根工厂。因此,现在的设计是不违反设计模式的开闭规则的!

我们知道,在简单工厂模式中,我们可以通过运工厂类的 Switch Case 来判断具体的运算类型,但是上述所写的工厂模式却做不到了!这样写无形中加重了客户端的负担(客户端必须自己来判断运算类型),因此:有没有好的办法解决这个弊端呢?

答案是有,而且还有一个有趣的名字,叫:雷锋工厂

如何用代码实现呢?

@陈卧龙的博客

大话设计模式之工厂模式 C#的更多相关文章

  1. 负载均衡算法,轮询方式 大话设计模式之工厂模式 C#

    负载均衡算法,轮询方式 2018-04-13 17:37 by 天才卧龙, 13 阅读, 0 评论, 收藏, 编辑 学无止境,精益求精 十年河东,十年河西,莫欺少年穷 学历代表你的过去,能力代表你的现 ...

  2. 大话设计模式--抽象工厂模式 Abstract Factory -- C++实现实例

    1. 抽象工厂模式: 提供一个创建一系列相关或者相互依赖对象的接口,而无需指定他们具体的类. 下面是工厂方法模式: 下面是抽象工厂模式: 和工厂方法模式相比 抽象工厂模式可以有多个Product抽象, ...

  3. C#学习之设计模式:工厂模式

    最近研究一下设计模式中工厂模式的应用,在此记录如下: 什么是工厂模式? 工厂模式属于设计模式中的创造型设计模式的一种.它的主要作用是协助我们创建对象,为创建对象提供最佳的方式.减少代码中的耦合程度,方 ...

  4. linkin大话设计模式--抽象工厂

    linkin大话设计模式--抽象工厂 在前面讲到的简单工厂里面虽然实现了我们那个类和其中的依赖的解耦,但是在产生我们需要的依赖的那个工厂里面还是和具体的产品类耦合了  现在要是还想彻底解耦的话怎么办呢 ...

  5. 设计模式之工厂模式(c++)

    问题描述 在面向对象系统设计中经常可以遇到以下的两类问题:1)为了提高内聚(Cohesion)和松耦合(Coupling),我们经常会抽象出一些类的公共接口以形成抽象基类或者接口.这样我们可以通过声明 ...

  6. C# Json反序列化 C# 实现表单的自动化测试<通过程序控制一个网页> 验证码处理类:UnCodebase.cs + BauDuAi 读取验证码的值(并非好的解决方案) 大话设计模式:原型模式 C# 深浅复制 MemberwiseClone

    C# Json反序列化   Json反序列化有两种方式[本人],一种是生成实体的,方便处理大量数据,复杂度稍高,一种是用匿名类写,方便读取数据,较为简单. 使用了Newtonsoft.Json,可以自 ...

  7. python 设计模式之工厂模式 Factory Pattern (简单工厂模式,工厂方法模式,抽象工厂模式)

    十一回了趟老家,十一前工作一大堆忙成了狗,十一回来后又积累了一大堆又 忙成了狗,今天刚好抽了一点空开始写工厂方法模式 我看了<Head First 设计模式>P109--P133 这25页 ...

  8. 设计模式——抽象工厂模式及java实现

    设计模式--抽象工厂模式及java实现 设计模式在大型软件工程中很重要,软件工程中采用了优秀的设计模式有利于代码维护,方便日后更改和添加功能. 设计模式有很多,而且也随着时间在不断增多,其中最著名的是 ...

  9. 5. 星际争霸之php设计模式--抽象工厂模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

随机推荐

  1. Linux高可靠技术

    1.进程挂死时,有后台监控程序检测重新拉起. 2.进程占用系统资源超过ulimit限定的资源时,会被ulimit杀死,同时配合后台监控程序,重新拉起进程,实现进程可靠性. 3.Linux系统的高可靠性 ...

  2. Loadrunner 脚本开发-利用Loadrunner生成Web service测试脚本

    脚本开发-利用Loadrunner生成Web service测试脚本 1.选择协议--Web Service,如下图 2.导入服务 入口1:点击Manage Services ->弹出窗中选择“ ...

  3. (网页)Http状态码大全(200、404、500等)(转CSDN)

    当我们从客户端向服务器发送请求时 服务器向我们返回状态码 状态码就是告诉我们服务器响应的状态 通过它,我们就可以知道当前请求是成功了还是出现了什么问题 状态码是由3位数字和原因短语组成的(比如最常见的 ...

  4. 11.1、socket连接中的粘包、精确传输问题

    粘包: 发生原因: 当调用send的时候,数据并不是即时发给客户端的.而是放到了系统的socket发送缓冲区里,等缓冲区满了.或者数据等待超时了,数据才会发送,所以有时候发送太快的话,前一份数据还没有 ...

  5. springboot中使用mybatis显示执行sql

    springboot 中使用mybatis显示执行sql的配置,在properties中添加如下 logging.你的包名=debug 2018-11-27 16:35:43.044 [DubboSe ...

  6. sysbench对MySQL的压测,使用sysbench压测磁盘io

    QPS - query per secondTPS - transaction per second 不是特别关注,每个业务场景中事务标准是不一样的 Ⅰ.sysbench测试框架 Ⅱ.常用测试脚本 [ ...

  7. 三种方法更改MAC OS X下的HOSTS文件

    1.终端更改 用程序里面打开终端(terminal),输入 sudo vi /etc/hosts 然后提示输入系统密码 hosts文件就自动打开了 接着输入 i 进入编辑模式 将添加的网站,ip拷贝进 ...

  8. Linux 小知识翻译 - 目录 (完结)

    偶尔在网上看到的这篇文章,总结了linux中一些天天在说的概念.可能是因为天天说的关系, 一直以为自己知道这些概念.其实对有些概念也只是似是而非的了解而已. 为此,决定将所有的小知识点全翻译下来,给自 ...

  9. January 09th, 2018 Week 02nd Tuesday

    Use the smile to change the world. Don't let the world change your smile. 用你的笑容去改变这个世界,别让这个世界改变了你的笑容 ...

  10. Nginx使用教程(一):下载并编译安装Nginx

    安装依赖 <br\>我们已经选择下载程序源代码进行手动编译,而不是使用软件包管理器(如Yum,Aptitude或Yast)进行安装. 这个选择有两个原因. 首先,软件包可能不包含在您的Li ...