C#设计模式之工厂

时间:2022-09-07 18:51:07

IronMan之工厂

前言

实用为主,学一些用得到的技术更能在如今的社会里保命。 虽然在日常的工作中设计模式不是经常的用到,但是呢,学习它只有好处没有坏处。

设计模式像是一种“标签”,它是代码编写者思想的体现。有木有感觉到这样很便捷?看到一些代码的时候就很清楚的了解编写者的思想了,这是为什么呢?因为编写者们用了“标签”,而你恰恰是知道“标签”意思的。 跟一异曲同工,在学习框架、了解框架的对象模型的时候,“标签”是时常出现,如果你不了解“标签”的意思那多痛苦啊!!!!! 还有好多,不去一一阐述了。

工作中需求的变更时常令我们头疼不已,总是要按着需求来重新的修改代码,然后发布新的产品版本,或者是出更新包。 在需求变更中,对应着代码也要修改,但是这修改也是分层次的。比如修改的模板在当初设计的时候遵循了开闭原则(OCP)的话,代码的修改就变的轻松的多了。

我想制造出一个像电影《钢铁侠》里面那样的的一身盔甲,又或者说是机器吧,我把这个想法告诉了我的朋友们,他们都认为我疯了。

好吧,我说的是用代码抽象的制造出”钢铁侠“

废话不多说,下面这个系列是用钢铁侠(IronMan)作为主题的设计模式 今天来学习简单工厂模式、工厂方法模式、以及抽象工厂模式。

问题的发现

需求:
“玩具厂”有一天找到我说:“Jin叫兽我们这需要一些部件,我们会提供“图纸”,请您帮忙制造,您看有问题吗?”。
我:“当然没有问题了。很乐意帮助你们”。
“玩具厂”:“噢!好的。Jin叫兽,时间方面还有什么问题嘛?”
我:“没问题的,我会尽快的”。
“玩具厂”:“那真的太感谢您了,Jin叫兽。我们就不打扰您了,先走了。”
我:“晚上一起吃顿饭吧”。
“玩具厂”:“Jin叫兽不必客气啊”。
我:“好,你们慢走”。

生产车间:
“一点挑战性都没有,随随便便就制造出来了。先从组成‘钢铁侠’的部件开始生产吧。”
既然是这样,那就从部件开始生产吧。
这里是“玩具厂”提供的“钢铁侠”右臂的“图纸”:

     public class RightHandComponent
{
public RightHandComponent()
{
this.strName = "毅代先锋号一代右部件"; }
public RightHandComponent(string strname)
{
this.strName = strname;
}
private string strName = string.Empty;
public string Name
{
get { return strName; }
set { strName = value; }
}
}

还有一个左臂部件的“图纸”:

     public class LeftHandComponent
{
public LeftHandComponent()
{
this.strName = "毅代先锋号一代左部件";
}
private string strName = string.Empty;
public string Name
{
get { return strName; }
set { strName = value; }
}
}

还有若干“图纸”…… 不在这篇一一列举了,在后面文章中会全面的讲解到。

开始生产

RightHandComponent rightcomponent = new RightHandComponent();
LeftHandComponent leftcomponent = new LeftHandComponent();

若干的部件
被我一个个的按照图纸给制造了出来。
这样就可以拿rightcomponent、leftcomponent……等等的一些制造好的部件组装了。
我也可以给“玩具厂”打电话了,可以交货收钱。可是电话打完情况又变了,
中间的对话就不说了,“玩具厂”的意思就是这样的。比如说“运输途中”出现“损坏”,他们希望用一个很快捷便利的方式能得到部件。

简单工厂

嗯,我想了一下,不过对于我Jin叫兽来说都是小事,待我造出来一台部件生产器来。他们拿着机器自己回家生产不就ok了。

    public class IronManComponentFactory
{
public static object CreateComponent(string comname)
{
switch (comname)
{
case "RightCom":
return new RightHandComponent();
case "LeftCom":
return new LeftHandComponent(); 等等……
}
return null;
}
}

这样生产的“机器”就好了,我得自己试用一下,看看效果怎么样。

 RightHandComponent rightcomponent = IronManComponentFactory.CreateComponent("RightCom") as RightHandComponent;
LeftHandComponent leftcomponent = IronManComponentFactory.CreateComponent("LeftCom") as LeftHandComponent;

这样反而多此一举了,第一步,向机器输入了命令以便自己获得想要的部件,第二步,在生产出来后我还得把“图纸”拿过来比对一下。 在我一筹莫展的时候,“玩具厂”给我发了个邮件,给我发了一份“部件规范说明书”,要求我的机器生产出的部件是达到说明书标准的。

那我们就来看一下这个所谓的“部件规范说明书”

    public abstract class Component
{
private string strName = string.Empty;
/// <summary>
/// 名称
/// </summary>
public string Name
{
get { return strName; }
set { strName = value; }
}
/// <summary>
/// 自我描述
/// </summary>
public abstract void Self_Described();
}

看完这个“部件规范说明书”,我已经无力吐槽,没办法了,只有重新设计部件了,“图纸”要重新绘制,因为要按照那该死的“规范说明书”。
再看一下各个部件的“图纸”

     public class RightHandComponent:Component
{
public RightHandComponent()
{
base.Name = "毅代先锋号一代右部件";
//fWeight=材质输出
}
public RightHandComponent(string strname)
{
base.Name = strname;
}
public override void Self_Described()
{
Console.WriteLine(base.Name);
}
}
public class LeftHandComponent:Component
{
public LeftHandComponent()
{
base.Name = "毅代先锋号一代左部件";
}
public LeftHandComponent(string strname)
{
base.Name = strname;
}
public override void Self_Described()
{
Console.WriteLine(base.Name);
}
}

等等一些部件……

这下我再把原来的搭好的“生产机器”拆了,内部修改一下,来看一下修改后的“机器”

     public class IronManComponentFactory
{
public static Component CreateComponent(string comname)
{
switch (comname)
{
case "RightCom":
return new RightHandComponent();
case "LeftCom":
return new LeftHandComponent(); }
return null;
}
}

自己来测试一下:

 Component rightcomponent = IronManComponentFactory.CreateComponent("RightCom");
Component leftcomponent = IronManComponentFactory.CreateComponent("LeftCom");
rightcomponent.Self_Described();
leftcomponent.Self_Described();

于是,我很放心的就交给了“玩具厂”使用了,还得了个好评。

工厂方法

好景不长,“玩具厂”再次来电,提出一个要求,想让我的“生产机器”里面还可以生产更多的符合“部件规范说明书”的部件。

这样说来是要改装“生产机器”了。 可以说“玩具厂”是故意的,绝对是故意的。这下整蒙圈了,亏血本了,“生产机器”又要拆了…… 直接来看“生产机器”的图纸

 public abstract class IronManComponentFactory
{
protected string factoryName = string.Empty;
protected void InitDataMessage()
{
Console.WriteLine("生产机器:" + factoryName + ".准备就绪");
}
public abstract Component CreateComponent();
}
public class RightComFactory:IronManComponentFactory
{ public override Component CreateComponent()
{
base.factoryName = "右臂部件生产器";
InitDataMessage();
return new RightHandComponent();
}
}
public class LeftComFactory:IronManComponentFactory
{ public override Component CreateComponent()
{
base.factoryName = "左臂部件生产器";
InitDataMessage();
return new LeftHandComponent();
}
}
public class PottingFactrory
{
/// <summary>
/// 取件口
/// </summary>
/// <param name="comFactory"></param>
/// <returns></returns>
public static Component ComExit(IronManComponentFactory comFactory)
{
if (comFactory != null)
{
return comFactory.CreateComponent();
}
return null;
}
}

C#设计模式之工厂

我们通过“取件口”取件

 Component component = PottingFactrory.ComExit(new RightComFactory());
component.Self_Described();

C#设计模式之工厂

我们只要通过更换“生产插件”,从“取件口”获得不同的部件。 或者更改需求,又要生产符合“规范说明书”的另一些产品的时候,可以自定义来实现“生产插件”,插入“生产机器”即可。

这样可以送给“玩具厂”使用了。这次得到了很好的一个评价,我也可以休息一下了。

这里的工厂方法是开闭原则(OCP)的实现,很优雅的显示出了设计原则和设计模式的美。

抽象工厂

“对,没错。‘玩具厂’又来了……。”
这次“玩具厂”是把Iron部件升级了,二代部件出来了,是在一代的基础上做了一些个性化的设计。来看新增部件的“图纸”

     public class RightHandComponent2 : Component
{
public RightHandComponent2() : this("毅代先锋号二代右部件") { }
public RightHandComponent2(string strname)
{
base.Name = strname;
}
public override void Self_Described()
{
Console.WriteLine("自描述:我是->" + base.Name);
}
} public class LeftHandComponent2 : Component
{
public LeftHandComponent2() : this("毅代先锋号一代左部件") { }
public LeftHandComponent2(string strname)
{
base.Name = strname;
}
public override void Self_Described()
{
Console.WriteLine("自描述:我是->" + base.Name);
}
}

按照“规范说明书”,添加了两张“图纸”,它们分别是二代的左右手部件。

部件的整体结构没怎么变,但是“生产机器”的“规范说明”就要更改了,以为在上面说到的“生产插件”也要重新更改。

先来看一下“生产机器”的“规范说明”:

    public abstract class IronManComponentFactory
{
protected string factoryName = string.Empty;
protected void InitDataMessage()
{
Console.WriteLine("生产机器:" + factoryName + ".准备就绪");
}
public abstract Component CreateComponent();
public abstract Component CreateComponent2(); }

当然喽,“规范说明”都改了,那上面说过的两个生产插件也得改了:

 public class RightComFactory : IronManComponentFactory                   //右部件生产插件
{ public override Component CreateComponent()
{
base.factoryName = "新右臂部件生产器";
InitDataMessage();
return new RightHandComponent();
} public override Component CreateComponent2()
{
base.factoryName = "新右臂部件生产器";
InitDataMessage();
return new RightHandComponent2();
}
} public class LeftComFactory : IronManComponentFactory //左部件生产插件
{ public override Component CreateComponent()
{
base.factoryName = "新左臂部件生产器";
InitDataMessage();
return new LeftHandComponent();
} public override Component CreateComponent2()
{
base.factoryName = "新左臂部件生产器";
InitDataMessage();
return new LeftHandComponent2();
}
}

所要做的修改都是连带关系,包装”生产机器“的”取件口“也要改:

 public class PottingFactory
{
private IronManComponentFactory comFactory = null; public IronManComponentFactory ComFactory
{
get { return comFactory; }
set { comFactory = value; }
}
public PottingFactory(IronManComponentFactory comFactory)
{
this.comFactory = comFactory;
}
/// <summary>
/// 取件口
/// </summary>
/// <param name="comFactory"></param>
/// <returns></returns>
//public static Component ComExit(IronManComponentFactory comFactory)
//{
// if (comFactory != null)
// {
// return comFactory.CreateComponent();
// }
// return null;
//}
}

到这里就差不多结束了。在工厂方法模式上 做了稍稍的(几乎全改了)改动。

当然自己要先来测试一下喽:

 PottingFactory pottingfact = new PottingFactory(new RightComFactory());
Component component= pottingfact.ComFactory.CreateComponent();
component.Self_Described();
component = pottingfact.ComFactory.CreateComponent2();
component.Self_Described();

我们来看一下结果:

C#设计模式之工厂

End   IronMan之旅才刚刚开始

作者:金源

出处:http://www.cnblogs.com/jin-yuan/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面

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

  1. C&num;设计模式&lpar;3&rpar;——工厂方法模式

    一.概念:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类. 二.代码实现 namespace 设计模式之工厂方法模式 { /// <summary&g ...

  2. Java设计模式之工厂模式(Factory)

    前言: 前面学习了建造者设计模式,接下来学习一下Retrofit中使用的另外一个设计模式,工厂设计模式!!!里面采用工厂模式使得数据转换得到完全解耦,工厂模式的好处用到了极致,如此好的设计模式我们怎能 ...

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

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

  4. java 23 - 1 设计模式之工厂方法模式

    转载: JAVA设计模式之工厂模式(简单工厂模式+工厂方法模式)

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

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

  6. 3&period; 星际争霸之php设计模式--简单工厂模式

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

  7. iOS 设计模式之工厂模式

    iOS 设计模式之工厂模式 分类: 设计模式2014-02-10 18:05 11020人阅读 评论(2) 收藏 举报 ios设计模式 工厂模式我的理解是:他就是为了创建对象的 创建对象的时候,我们一 ...

  8. 设计模式之工厂模式&lpar;Factory&rpar;

    设计模式的工厂模式一共有三种:简单工厂模式,工厂模式,抽象工厂模式 简单工厂模式原理:只有一个工厂类,通过传参的形式确定所创建的产品对象种类 代码如下: #include <stdio.h&gt ...

  9. php设计模式:工厂模式

    php设计模式:工厂模式 意图: 定义一个用于创建对象的接口,让子类决定实例化哪一个类. 工厂模式实现: 工厂模式中任何创建对象的工厂类都要实现这个接口,实现接口的方法体中都要实现接口中的方法,它声明 ...

  10. 浅析JAVA设计模式之工厂模式&lpar;一&rpar;

    1 工厂模式简单介绍 工厂模式的定义:简单地说,用来实例化对象,取代new操作. 工厂模式专门负责将大量有共同接口的类实例化.工作模式能够动态决定将哪一个类实例化.不用先知道每次要实例化哪一个类. 工 ...

随机推荐

  1. &lbrack;&period;NET&rsqb; 打造一个很简单的文档转换器 - 使用组件 Spire&period;Office

    打造一个很简单的文档转换器 - 使用组件 Spire.Office [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6024827.html 序 之前,& ...

  2. Loading加载小插件&comma;用户可以选择html格式或canvas格式,自定义loading图片,canvas色彩搭配可根据个人喜好

    ;(function($) { $.Loading = function(options) { //暴漏插件默认值 $.Loading.defaults = { speed: 200, //弹出层淡出 ...

  3. 打开U盘后文件都不见了的解决方法

    碰到了好几次这种情况,明明占着U盘的空间,却看不到任何内容,典型的病毒.在网上找了一种方法,用的不错,顿时感叹网友的犀利步骤: (1)新建一个文本文档(2)打开此文档,在里面输入“attrib -s ...

  4. Codeforces 366C Dima and Salad

    http://codeforces.com/problemset/problem/366/C 题意:在一个冰箱里有n种水果,并且这些水果每一种都有一个美味度和一个卡路里的属性, 小明要从这些水果中选出 ...

  5. hdu To and Fro

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1200 代码: #include <stdio.h> #include <string ...

  6. python之numpy库&lbrack;2&rsqb;

    python-numpy csv文件的写入和存取 写入csv文件 CSV (Comma‐Separated Value, 逗号分隔值),是一种常见的文件格式,用来存储批量数据. 写入csv文件 np. ...

  7. vs2010等宽字体设置

    VS2010自带的字体非等宽,不同行的代码采用同样的缩进空格时,可能左侧未对齐. 这个里有一款字体很帮,字体名字叫Fixedsys Excelsior 3.01,下载地址:http://www.fix ...

  8. Spring Security 入门(1-9)国际化的使用

  9. 【Unity Shaders】Diffuse Shading——使用2D ramp texture来创建一个假的BRDF(双向反射分布函数)

    本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...

  10. 使用CocoaPods时遇到 Permission denied 问题

    报错: Setting up CocoaPods master repo [!] /usr/bin/git clone fatal: could not create work tree dir 'm ...