C#之工厂模式

IronMan之工厂

前言

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

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

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

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

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

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

问题的发现

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

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


 1     public class RightHandComponent
2 {
3 public RightHandComponent()
4 {
5 this.strName = "毅代先锋号一代右部件";
6
7 }
8 public RightHandComponent(string strname)
9 {
10 this.strName = strname;
11 }
12 private string strName = string.Empty;
13 public string Name
14 {
15 get { return strName; }
16 set { strName = value; }
17 }
18 }

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


 1     public class LeftHandComponent
2 {
3 public LeftHandComponent()
4 {
5 this.strName = "毅代先锋号一代左部件";
6 }
7 private string strName = string.Empty;
8 public string Name
9 {
10 get { return strName; }
11 set { strName = value; }
12 }
13 }

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

开始生产


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;
}
}

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


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

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

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


 1    public abstract class Component
2 {
3 private string strName = string.Empty;
4 /// <summary>
5 /// 名称
6 /// </summary>
7 public string Name
8 {
9 get { return strName; }
10 set { strName = value; }
11 }
12 /// <summary>
13 /// 自我描述
14 /// </summary>
15 public abstract void Self_Described();
16 }

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


 1     public class RightHandComponent:Component
2 {
3 public RightHandComponent()
4 {
5 base.Name = "毅代先锋号一代右部件";
6 //fWeight=材质输出
7 }
8 public RightHandComponent(string strname)
9 {
10 base.Name = strname;
11 }
12 public override void Self_Described()
13 {
14 Console.WriteLine(base.Name);
15 }
16 }
17 public class LeftHandComponent:Component
18 {
19 public LeftHandComponent()
20 {
21 base.Name = "毅代先锋号一代左部件";
22 }
23 public LeftHandComponent(string strname)
24 {
25 base.Name = strname;
26 }
27 public override void Self_Described()
28 {
29 Console.WriteLine(base.Name);
30 }
31 }

等等一些部件……

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


 1     public class IronManComponentFactory
2 {
3 public static Component CreateComponent(string comname)
4 {
5 switch (comname)
6 {
7 case "RightCom":
8 return new RightHandComponent();
9 case "LeftCom":
10 return new LeftHandComponent();
11
12 }
13 return null;
14 }
15 }

自己来测试一下:


1 Component rightcomponent = IronManComponentFactory.CreateComponent("RightCom");
2 Component leftcomponent = IronManComponentFactory.CreateComponent("LeftCom");
3 rightcomponent.Self_Described();
4 leftcomponent.Self_Described();

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

工厂方法

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

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


 1 public abstract class IronManComponentFactory
2 {
3 protected string factoryName = string.Empty;
4 protected void InitDataMessage()
5 {
6 Console.WriteLine("生产机器:" + factoryName + ".准备就绪");
7 }
8 public abstract Component CreateComponent();
9 }
10 public class RightComFactory:IronManComponentFactory
11 {
12
13 public override Component CreateComponent()
14 {
15 base.factoryName = "右臂部件生产器";
16 InitDataMessage();
17 return new RightHandComponent();
18 }
19 }
20 public class LeftComFactory:IronManComponentFactory
21 {
22
23 public override Component CreateComponent()
24 {
25 base.factoryName = "左臂部件生产器";
26 InitDataMessage();
27 return new LeftHandComponent();
28 }
29 }
30 public class PottingFactrory
31 {
32 /// <summary>
33 /// 取件口
34 /// </summary>
35 /// <param name="comFactory"></param>
36 /// <returns></returns>
37 public static Component ComExit(IronManComponentFactory comFactory)
38 {
39 if (comFactory != null)
40 {
41 return comFactory.CreateComponent();
42 }
43 return null;
44 }
45 }

我们通过“取件口”取件


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

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

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

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

抽象工厂

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


 1     public class RightHandComponent2 : Component
2 {
3 public RightHandComponent2() : this("毅代先锋号二代右部件") { }
4 public RightHandComponent2(string strname)
5 {
6 base.Name = strname;
7 }
8 public override void Self_Described()
9 {
10 Console.WriteLine("自描述:我是->" + base.Name);
11 }
12 }
13
14 public class LeftHandComponent2 : Component
15 {
16 public LeftHandComponent2() : this("毅代先锋号一代左部件") { }
17 public LeftHandComponent2(string strname)
18 {
19 base.Name = strname;
20 }
21 public override void Self_Described()
22 {
23 Console.WriteLine("自描述:我是->" + base.Name);
24 }
25 }

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

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

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


 1    public abstract class IronManComponentFactory
2 {
3 protected string factoryName = string.Empty;
4 protected void InitDataMessage()
5 {
6 Console.WriteLine("生产机器:" + factoryName + ".准备就绪");
7 }
8 public abstract Component CreateComponent();
9 public abstract Component CreateComponent2();
10
11
12 }

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


 1 public class RightComFactory : IronManComponentFactory                   //右部件生产插件
2 {
3
4 public override Component CreateComponent()
5 {
6 base.factoryName = "新右臂部件生产器";
7 InitDataMessage();
8 return new RightHandComponent();
9 }
10
11 public override Component CreateComponent2()
12 {
13 base.factoryName = "新右臂部件生产器";
14 InitDataMessage();
15 return new RightHandComponent2();
16 }
17 }
18
19 public class LeftComFactory : IronManComponentFactory //左部件生产插件
20 {
21
22 public override Component CreateComponent()
23 {
24 base.factoryName = "新左臂部件生产器";
25 InitDataMessage();
26 return new LeftHandComponent();
27 }
28
29 public override Component CreateComponent2()
30 {
31 base.factoryName = "新左臂部件生产器";
32 InitDataMessage();
33 return new LeftHandComponent2();
34 }
35 }

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


 1 public class PottingFactory
2 {
3 private IronManComponentFactory comFactory = null;
4
5 public IronManComponentFactory ComFactory
6 {
7 get { return comFactory; }
8 set { comFactory = value; }
9 }
10 public PottingFactory(IronManComponentFactory comFactory)
11 {
12 this.comFactory = comFactory;
13 }
14 /// <summary>
15 /// 取件口
16 /// </summary>
17 /// <param name="comFactory"></param>
18 /// <returns></returns>
19 //public static Component ComExit(IronManComponentFactory comFactory)
20 //{
21 // if (comFactory != null)
22 // {
23 // return comFactory.CreateComponent();
24 // }
25 // return null;
26 //}
27 }

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

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


1 PottingFactory pottingfact = new PottingFactory(new RightComFactory());
2 Component component= pottingfact.ComFactory.CreateComponent();
3 component.Self_Described();
4 component = pottingfact.ComFactory.CreateComponent2();
5 component.Self_Described();

我们来看一下结果:

End   IronMan之旅才刚刚开始

作者:金源

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

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

C#之工厂模式,码迷,mamicode.com

时间: 2024-11-10 12:03:39

C#之工厂模式的相关文章

抽象工厂模式

思考:工厂方法模式:http://www.cnblogs.com/maggiejyt/p/7561253.html 工厂方法模式UML: 问题:如果这家工厂不止要生产Ball(球),还要还有Sneakers(球鞋)等 则UML图为 当Product有多种类时则是抽象工厂模式 代码(Ball的代码见简单工厂模式:http://www.cnblogs.com/maggiejyt/p/7561253.html) Sneakers(球鞋抽象类) package com.maggie.FactoryMet

设计模式 2/23 工厂模式

工厂模式是最常用的设计模式之一,用好了,代码优雅,可维护性高,对系统设计会上一个台阶 为什么这么说,因为工厂模式可以牵扯出抽象工厂模式,也有大家都会聊到的简单工厂模式 我们要了解一点,23中设计模式中,不包含简单工厂模式,之所以大家会去聊这个,四个字,渐进明细 通过对简单工厂模式的了解,我们引入工厂这个词,不然一个写代码的,天天给他讲工厂,工厂,工厂,西厂,东厂,会晕 同时,通过逐步的深入,从简单工厂,到工厂模式,再到抽象工厂,渐进明细的过程,逐步深入的理解,比较优劣,择优而为我们所用. 试想我

简单工厂模式

目前正在看<大话设计模式>,写此系列的文章记录下学习的经过. 简单工厂模式 先看如下代码,使用面向对象的原理实现计算器功能 Operation运算类 1 public class Operation 2 { 3 private double numberA = 0; 4 private double numberB = 0; 5 6 public double NumberA 7 { 8 get { return numberA; } 9 set { numberA = value; } 10

设计模式——介绍与工厂模式(扁平管理模式VS职业经理人模式)

本文主要对设计模式进行大概解说.特别是对工厂模式进行简明的解析: 一.设计模式的分类 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元模式. 行为型模式,共十一种:策略模式.模板方法模式.观察者模式.迭代子模式.责任链模式.命令模式.备忘录模式.状态模式.訪问者模式.中介者模式.解释器模式. 事实上还有两类:并发型模式和线程池模式. 二.设计模式的六大原则 1.开闭原则(Op

工厂模式

工厂模式属于创建型模式,由一个工厂对象决定创建出哪一种产品类的实例. 角色: IProduct: 产品共同的接口 Product1:具体的产品类 Creator:工厂类,可根据参数决定创建的产品类型 示例: public interface IProduct { void myfunction(); } --- class Product1 implements IProduct{ public void myfunction(){ System.out.println("function1&q

Java设计模式—工厂方法模式&amp;抽象工厂模式

工厂方法模式与抽象工厂模式都是设计模式中重要而且常见的模式.       工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. 通用类图如下: 在工厂方法模式中,抽象产品类Product负责定义产品的共性,实现对事物最抽象的定义:Creator为抽象创建 类,也就是抽象工厂,具体如何创建产品类是由具体的实现工厂ConcreteCreator完成的. 工厂方法模式的扩展方式有很多种,下边是工厂方法模式一个比较实用的源代码: 抽象产品类: pub

java设计模式--工厂模式

总结 (1)简单工厂模式是由一个具体的类去创建其他类的实例,父类是相同的,父类是具体的. (2)工厂方法模式是有一个抽象的父类定义公共接口,子类负责生成具体的对象,这样做的目的是将类的实例化操作延迟到子类中完成. (3)抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无须指定他们具体的类.它针对的是有多个产品的等级结构.而工厂方法模式针对的是一个产品的等级结构. 一.工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的. 工厂模式在<Java

大话设计模式:简单工厂模式

由于面向过程编程造成的代码膨胀问题越来越严重,使其维护的代价高,灵活性很低.为了使代码易维护.易扩展.易复用和灵活性好,所以我们在采用面向对象编程的时候,防止采用面向对象的语言实际上却做着面向过程的事儿,更需要采用某种设计模式,核心就是使程序变得高内聚,低耦合,这样的程序才能达到上面的四个优点.而简单工厂模式的出现也正是为了达到这样一种效果,将工厂和产品分块,具体解决了实例化那个对象(具体产品)的需求.从而实现了高内聚,低耦合.使程序易维护.易扩展.易复用和灵活性好.同时也用到了面向对象编程的三

大话设计模式:抽象工厂模式

抽象方法模式:提供一个创建一系列相关或互相依赖对象的接口,而无需指定他们具体的类. 三种模式的对比:   简单工厂模式 工厂模式 抽象工厂模式 产品 可以有多个但是都属于同一类, 同一等级.都继承产品抽象类. 可以有多个但是都属于同一类,同一等级. 都继承产品抽象类. 可以有不同种类的产品,每类有多中 具体产品: 抽象产品 只能有一个 只能有一个; 多个抽象产品类:每个抽象产品类可 以派生多种具体产品: 抽象工厂类   只能有一个,可以派生出多个具体工厂类: 只有一个,可派生出多个具体工厂类:

【设计模式】1、抽象工厂模式

对于这个抽象工厂的相应的代码实现 /** * 功能:抽象工厂模式的作用 适用性 1.一个系统要独立于它的产品的创建.组合和表示时. 2.一个系统要由多个产品系列中的一个来配置时. 3.当你要强调一系列相关的产品对象的设计以便进行联合使用时. 4.当你提供一个产品类库,而只想显示它们的接口而不是实现时. * 时间:2016年2月11日22:18 * 作者:cutter_point */ package com.shejimoshi.create.AbstractFactory; public in