学无止境,精益求精

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

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

大话设计模式一书中第一个开讲的设计模式是简单工厂模式,关于简单工厂模式大家可参考鄙人的博客:代码无错就是优?简单工厂模式 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. loadrunner 场景设计-目标场景设计

    场景设计-目标场景设计 by:授客 QQ:1033553122 A.   概述 Goals Types for Goal-Oriented Scenarios 在以目标为向导的场景中,定义你想实现的测 ...

  2. RabbitMQ延迟消息学习

    准备做一个禁言自动解除的功能,立马想到了订单的超时自动解除,刚好最近在看RabbitMQ的实现,于是想用它实现,查询了相关文档发现确实可以实现,动手编写了这篇短文. 准备工作 1.Erlang安装请参 ...

  3. puppeteer入门

    转自: https://www.jianshu.com/p/a89d8d6c007b 作者: ppCode puppeteer新手入门(chromium下载跳坑) ppCode 关注 2017.12. ...

  4. XP环境下C# 调用Pocess.start()时提示文件找不到的错误解决办法

    错误提示如下: System.ComponentModel.Win32Exception (0x80004005): 系统找不到指定的文件. 在 System.Diagnostics.Process. ...

  5. 安装VisualSVN Server 报"Service 'VisualSVN Server' failed to start. Please check VisualSVN Server log in Event Viewer for more details"错误.原因是启动"VisualSVN Server"失败

    安装VisualSVN Server 报"Service 'VisualSVN Server' failed to start. Please check VisualSVN Server ...

  6. 万能Makefile,前戏做足项目做起来才顺畅。

    # 获取要编译的源码 SRC :=$(wildcard *.cpp) OBJ :=$(patsubst %.cpp,%.o,$(SRC)) # 编译参数 CC :=g++ STD :=-std=c++ ...

  7. win7计划任务报该任务映像己损坏或己篡改

    目录 win7计划任务报该任务映像己损坏或己篡改 前言 解决方案 排查损坏的计划任务映像 win7计划任务报该任务映像己损坏或己篡改 文:铁乐与猫 2018-9-20 前言 win7下想自定义一些计划 ...

  8. Java面试题以及答案精选(架构师面试题)-基础题1

    基础题 一.String,StringBuffer, StringBuilder 的区别是什么?String为什么是不可变的?1. String是字符串常量,StringBuffer和StringBu ...

  9. Django之权限管理

    Django权限管理之初步完整版 项目背景:这是一个权限管理系统(给一些角色和他们的权限指URL和页面可以删除的按钮比如:增删改查) 使用到了中间件,和初始化权限,使用了admin的后台管理系统. 我 ...

  10. Linux基础第四课——文件操作

    文件的创建 touch sudo touch 文件1 文件2 文件3 #支持批量创建文件 sudo rm -f 文件1 文件2 文件3 #支持批量创建 也支持批量删除 echo '谁动谁输,对不起我输 ...