莫贝拉, 何许人也? 聪明的人一看就知道跟我有关系. 没错, 莫贝拉就是我的小MM, 人长得那是相当的水灵, 年方20, 身材苗条, 皮肤弹指课破, 一条长长的马尾辫特别让人心动, 当然那双水灵灵的大眼睛更让人招架不住.
莫贝拉虽然长的特别俊俏, 可是不误正业, 大学选择艺术, 可是没事经常跑来跟我一起上课, 毕业后工作更是两天打渔三天晒网, 结果可想而知, 毕业短短1年, 竟然换了好几份工作.
前几天刚下班, 就接到莫贝拉的电话, “ 哥哥, 晚上一起吃饭呗!”, 我一听, “遭了, 肯定是没有钱花了”. 还是先下手为强, “ 拉拉, 哥哥最近手头紧, 就不请你吃饭了, 改天手头松点再请你吃”, “哥, 又小人了不是, 我请你吃, 有好消息要跟你分享.”
一会功夫, 就在约好的湘菜馆碰上了, “哥, 想吃啥, 随便点”, 那表情和神态就跟中了六合彩一模一样, 要不然就说这个世界上还是做女人好, 自己能赚多少是多少, 还可以赚多少就可以花多少. 看着我怀疑的表情, 拉拉接着说到”哥哥,放心吧, 我请你吃, 你MM我找到工作了”, 看到我惊讶的表情, 她
莫贝拉, 何许人也? 聪明的人一看就知道跟我有关系. 没错, 莫贝拉就是我的小MM, 人长得那是相当的水灵, 年方20, 身材苗条, 皮肤弹指课破, 一条长长的马尾辫特别让人心动, 当然那双水灵灵的大眼睛更让人招架不住. 莫贝拉虽然长的特别俊俏, 可是不误正业, 大学选择艺术, 可是没事经常跑来跟我一起上课, 毕业后工作更是两天打渔三天晒网, 结果可想而知, 毕业短短1年, 竟然换了好几份工作.
前几天刚下班, 就接到莫贝拉的电话, “ 哥哥, 晚上一起吃饭呗!”, 我一听, “遭了, 肯定是没有钱花了”. 还是先下手为强, “ 拉拉, 哥哥最近手头紧, 就不请你吃饭了, 改天手头松点再请你吃”, “哥, 又小人了不是, 我请你吃, 有好消息要跟你分享.”
一会功夫, 就在约好的湘菜馆碰上了, “哥, 想吃啥, 随便点”, 那表情和神态就跟中了六合彩一模一样, 要不然就说这个世界上还是做女人好, 自己能赚多少是多少, 还可以赚多少就可以花多少. 看着我怀疑的表情, 拉拉接着说到”哥哥,放心吧, 我请你吃, 你MM我找到工作了”, 看到我惊讶的表情, 她举起左手, 嘴里说到“老天在上, 哥哥作证, 我莫贝拉, 可爱漂亮的拉拉, 这次下定决心, 一定要好好工作, 坚持到底”, 说完对我做了个鬼脸. 后来了解到, 她确实找到了一份工作, 在眼睛生产企业的一个设计部门做设计. 至于搞啥, 咱也不懂, 也不想懂, 因为我知道她在那呆不了多久.
这不, 没过几天, 又接到莫贝拉的电话, “哥哥, 你一定的帮我, 我自己搞不定了, 要不然又要走人啦”. 原来事情是这样的. 莫贝拉早上一上班, 就接到上司的任务, 要为一个眼镜生产企业设计一个程序. 由于这家企业是刚创业的, 为了减低投入成本, 该企业目前只生产塑料镜框和玻璃镜片的眼镜. 她想这还不简单, 没过多久程序就设计好了.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MBetter.AbstractFactoryPattern
{
public class GlassesProduceManager
{
public GlassesProduceManager(){}
public PlasticOpticalFrame ProduceGlassFrame()
{
return new PlasticOpticalFrame();
}
public GlassOpticalLens ProduceGlassLenses()
{
return new GlassOpticalLens();
}
}
//眼镜
public class Glass
{
public GlassOpticalLens Lenses { set; get; }
public PlasticOpticalFrame Frame { set; get; }
}
//眼镜镜框
public class PlasticOpticalFrame
{
public string FrameType = "塑料镜框";
public string FrameColor { get; set; }
}
//眼镜镜片
public class GlassOpticalLens
{
public string LensType = "玻璃镜片";
public string LensColor { get; set; }
}
}
客户端程序也很简单,
static void Main(string[] args)
{
//要生产的眼镜
Glass glass = new Glass();
GlassesProduceManager manager = new GlassesProduceManager();
glass.Frame = manager.ProduceGlassFrame();
glass.Lenses = manager.ProduceGlassLenses();
//显示
ShowGlassInfo(glass);
Console.Read();
}
//显示眼镜的信息
static void ShowGlassInfo(Glass glass)
{
Console.WriteLine("本眼镜由"+glass.Frame.FrameType+","+glass.Lenses.LensType+"组成");
} 没过多久,
她就想上司汇报,
工作完成.
领导一阵猛夸,
她就一阵狂晕.
然而这个眼镜企业发展倒是很快, 为了占有更多的眼镜市场和提升业绩, 他们决定增加生产铁框和树脂眼镜, 可是很快他们发现, 这个程序不能满足他们的要求. 结果可想而知, 莫贝拉被领导叫道办公室. 领导说到” 拉拉, 客户要求我们的程序能满足他们生产铁框树脂眼镜, 我们的程序称跟不上人家的发展呀, 当然这个不是你的问题, 你想想办法, 赶紧修改下”.
莫贝拉心里郁闷,
不就是增加个镜片类型吗?
直接让我改就是了,
何必对我发火呢.
不过郁闷归郁闷,
莫贝拉赶紧着手对程序修改,
加了一个ResinOpticalLenses
类来表示树脂镜片,
增加了一个镜片的接口,
让所有镜片都继承这个接口.
程序很快出来啦.
增加树脂镜片种类
public class GlassesProduceManager
{
public GlassesProduceManager() { }
public PlasticOpticalFrame ProduceGlassFrame()
{
//返回塑料镜框
return new PlasticOpticalFrame();
}
public GlassLensType ProduceGlassLenses(int LensType)
{
//返回玻璃镜片
switch (LensType)
{
case 1: return new GlassOpticalLens();
case 2: return new ResinOpticalLens();
default: return new GlassOpticalLens();
}
}
}
//眼镜
public class Glass
{
public GlassLensType Lenses { set; get; }
public PlasticOpticalFrame Frame { set; get; }
}
//塑料眼镜镜框
public class PlasticOpticalFrame
{
public string FrameType = "塑料镜框";
public string FrameColor { get; set; }
}
//玻璃眼镜镜片
public class GlassOpticalLens : GlassLensType
{
public string LensType
{
get { return "玻璃镜片"; }
}
public string LensColor { get; set; }
}
//**************************************新增加一个类和一个接口**************************************
//树脂镜片
public class ResinOpticalLens : GlassLensType
{
public string LensType
{
get { return "树脂镜片"; }
}
public string LensColor { get; set; }
}
//镜片接口
public interface GlassLensType
{
string LensType { get; }
string LensColor { get; }
} 客户端也做了相应的修改
client调用
static void Main(string[] args)
{
//要生产的眼镜
Glass glass = new Glass();
GlassesProduceManager manager = new GlassesProduceManager();
glass.Frame = manager.ProduceGlassFrame();
//选择镜片种类
Console.WriteLine("目前有两种镜片,1: 玻璃镜片,2: 树脂镜片, 请输入相应的数字");
int lensType = int.Parse(Console.ReadLine());
glass.Lenses = manager.ProduceGlassLenses(lensType);
//显示
ShowGlassInfo(glass);
Console.Read();
}
//显示眼镜的信息
static void ShowGlassInfo(Glass glass)
{
Console.WriteLine("本眼镜由" + glass.Frame.FrameType + "," + glass.Lenses.LensType + "组成");
} 顺便做了下测试,结果毫无疑问的正确.
然而这次莫贝拉不但没有得到夸奖, 反而得到一顿批评. 诸如"莫贝拉, 你这就完成了? 思考了吗? 如果客户增加什么老化镜片,平光镜片,你是不是又要修改你的Switch语句......". 不过让女孩子去动脑筋思考,就跟要她命似的, 所以也就是为什么我接到莫贝拉的电话啦.
了解这个过程后, 我分析了她的程序, 确实如她老板所说, 如果增加其他的镜片种类, 又要大改程序. 而我们做程序最基本的原则之一就是" 对开展开放,对修改关闭".
仔细思考了一会, 心里琢磨着, 何不增加一个创建镜片的接口,然后让它的子类去决定到底返回什么类型的镜片. 实践是检验真理的唯一标准, 立即行动.
增加工厂方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace MBetter.FactoryMethodPattern
{
public class GlassesProduceManager
{
public GlassesProduceManager() { }
public PlasticOpticalFrame ProduceGlassFrame()
{
//返回塑料镜框
return new PlasticOpticalFrame();
}
public GlassLensType ProduceGlassLenses(string strfactoryName)
{
LensTypeCreator creator = (LensTypeCreator)Assembly.Load("MBetter.FactoryMethodPattern").CreateInstance("MBetter.FactoryMethodPattern." + strfactoryName);
return creator.CreateLenses();
}
}
//眼镜
public class Glass
{
public GlassLensType Lenses { set; get; }
public PlasticOpticalFrame Frame { set; get; }
}
//塑料眼镜镜框
public class PlasticOpticalFrame
{
public string FrameType = "塑料镜框";
public string FrameColor { get; set; }
}
//玻璃眼镜镜片
public class GlassOpticalLens : GlassLensType
{
public string LensType
{
get { return "玻璃镜片"; }
}
public string LensColor { get; set; }
}
//**************************************新增加一个类和一个接口**************************************
//树脂镜片
public class ResinOpticalLens : GlassLensType
{
public string LensType
{
get { return "树脂镜片"; }
}
public string LensColor { get; set; }
}
//镜片接口
public interface GlassLensType
{
string LensType { get; }
string LensColor { get; }
}
//**************************************增加几个工厂类**************************************
public abstract class LensTypeCreator
{
public abstract GlassLensType CreateLenses();
}
public class GlassOpticalLensCreator : LensTypeCreator
{
public override GlassLensType CreateLenses()
{
return new GlassOpticalLens();
}
}
public class ResinOpticalLensCreator : LensTypeCreator
{
public override GlassLensType CreateLenses()
{
return new ResinOpticalLens();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace MBetter.FactoryMethodPattern
{
public class GlassesProduceManager
{
public GlassesProduceManager() { }
public PlasticOpticalFrame ProduceGlassFrame()
{
//返回塑料镜框
return new PlasticOpticalFrame();
}
public GlassLensType ProduceGlassLenses(string strfactoryName)
{
LensTypeCreator creator = (LensTypeCreator)Assembly.Load("MBetter.FactoryMethodPattern").CreateInstance("MBetter.FactoryMethodPattern." + strfactoryName);
return creator.CreateLenses();
}
}
//眼镜
public class Glass
{
public GlassLensType Lenses { set; get; }
public PlasticOpticalFrame Frame { set; get; }
}
//塑料眼镜镜框
public class PlasticOpticalFrame
{
public string FrameType = "塑料镜框";
public string FrameColor { get; set; }
}
//玻璃眼镜镜片
public class GlassOpticalLens : GlassLensType
{
public string LensType
{
get { return "玻璃镜片"; }
}
public string LensColor { get; set; }
}
//**************************************新增加一个类和一个接口**************************************
//树脂镜片
public class ResinOpticalLens : GlassLensType
{
public string LensType
{
get { return "树脂镜片"; }
}
public string LensColor { get; set; }
}
//镜片接口
public interface GlassLensType
{
string LensType { get; }
string LensColor { get; }
}
//**************************************增加几个工厂类**************************************
public abstract class LensTypeCreator
{
public abstract GlassLensType CreateLenses();
}
public class GlassOpticalLensCreator : LensTypeCreator
{
public override GlassLensType CreateLenses()
{
return new GlassOpticalLens();
}
}
public class ResinOpticalLensCreator : LensTypeCreator
{
public override GlassLensType CreateLenses()
{
return new ResinOpticalLens();
}
}
}
增加了配置文件
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="factoryName" value="ResinOpticalLensCreator"/>
</appSettings>
</configuration> client 也做了相应的修改
client
static void Main(string[] args)
{
//要生产的眼镜
Glass glass = new Glass();
GlassesProduceManager manager = new GlassesProduceManager();
glass.Frame = manager.ProduceGlassFrame();
//选择镜片种类
string strfactoryName = ConfigurationSettings.AppSettings["factoryName"];
glass.Lenses = manager.ProduceGlassLenses(strfactoryName);
//显示
ShowGlassInfo(glass);
Console.Read();
}
//显示眼镜的信息
static void ShowGlassInfo(Glass glass)
{
Console.WriteLine("本眼镜由" + glass.Frame.FrameType + "," + glass.Lenses.LensType + "组成");
} 经过测试, 完全正确, 而且也满足客户的需求, 如果客户再增加其他种类的镜片,我们只要相应的扩展, 镜片类和工厂类 和重新配置App.config外,其他的需要修改.
<<后记>>程序发给拉拉之后,还没有忘记教育一番.上面我们用到的是设计模式中的工厂方法, 定义是什么,用途.....
概述
在 软件系统中,经常面临着“某个对象”的创建工作,由于需求的变化,这个对象的具体实现经常面临着剧烈的变化,但是它却拥有比较稳定的接口。如何应对这种变化?提供一种封装机制来隔离出“这个易变对象”的变化,从而保持系统中“其它依赖该对象的对象”不随着需求的改变而改变?这就是要说的Factory Method模式了。
定义: 工厂方法的本质是"定义一个创建对象的接口, 并让子类去决定到底要实例化哪个对象"
原文如下:
The essence of the Factory Pattern is to "Define an interface for creating an object, but let the subclasses decide which class to instantiate. The Factory method lets a class defer instantiation to subclasses."
意图
定义一个用户创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。
结构图
参考:http://en.wikipedia.org/wiki/Factory_method_pattern