学无止境,精益求精

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

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

大话设计模式一书中第一个开讲的设计模式是简单工厂模式,关于简单工厂模式大家可参考鄙人的博客:代码无错就是优?简单工厂模式 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. Tsung CentOS 操作系统下搭建tsung性能测试环境_Part 1

    CentOS 操作系统下搭建tsung性能测试环境_Part 1 by:授客 QQ:1033553122 步骤1.下载软件安装包 CentOS-6.0-x86_64-bin-DVD1.iso jdk- ...

  2. React Refs

    React Refs React 支持一种非常特殊的属性 Ref ,你可以用来绑定到 render() 输出的任何组件上. 这个特殊的属性允许你引用 render() 返回的相应的支撑实例( back ...

  3. check

    private int AddNewstoDB(NewsModels newsModels, string dateTimeStr, string jsonStr, string cid, strin ...

  4. Docker搭建wordpress博客环境(Centos7)

    Docker搭建wordpress博客环境(Centos7) 升级系统 yum -y update 设置docker库 sudo yum install -y yum-utils sudo yum-c ...

  5. MySQL之慢查询日志分析

    在MySQL命令行中查看慢查询日志是否打开了: mysql> show variables like '%slow_query%'; +---------------------------+- ...

  6. kafka的Java客户端示例代码(kafka_2.12-0.10.2.1)

    使用0.9开始增加的KafkaProducer和KafkaConsumer. Pom.xml <project xmlns="http://maven.apache.org/POM/4 ...

  7. Git安装与配置——详细教程1

    1.下载Git客户端 想要安装Git首先要下载Git的安装包程序. Git安装包下载地址:https://git-scm.com/downloads/ 2.安装Git 双击安装程序进行安装: a. 欢 ...

  8. 容器中JVM获取真实的CPU核数

    容器中JVM获取真实的CPU核数 基于 libsysconfcpus的方案,可以为各个版本的JDK提供一个通用的解决方案. libsysconfcpus.so的原理是截获JVM获取CPU核数所用的系统 ...

  9. mysql order by 排序的问题

    参考博客http://blog.csdn.net/hollboy/article/details/13296601 mysql order by 的排序在今天时候遇到了问题 情景是:将排序的字段设置成 ...

  10. 关于pyquery小知识点

    #表示的是取html中的id元素, . 表示的是取html中的class元素. 如果是标签,就直接用标签名 而它们之间的空格,则表示嵌套关系 单冒号(:)用于CSS3伪类,双冒号(::)用于CSS3伪 ...