工厂的那些事儿
下午考完试了,挺轻松的,不过现在不知道要干嘛了,随便写两句吧,也不知道要取个什么名字,就也时尚一下,叫成《工厂的那些事儿》吧 :)
既然标题取成了工厂,那就是Factory Pattern了,前段时间看TerryLee大哥的工厂方法的文章,迷惑了几天,不过在某天早醒来的瞬间,我突然想通了,不过一直没有时间把它前下来,就趁这会儿有空,把它记录下来吧。
First, 贴上TerryLee讲工厂方法那篇文章的地址:http://terrylee.cnblogs.com/archive/2006/01/04/310716.html
下面引用的两段原文就是曾经引起我疑问的地方了:
我曾一直想不通,如果把Segment 1中的 EventLog eventlog = new EventLog();改成Log log = new EventLog(),那会跟下面采用了Factory Method的情况会有多大的差别?大家都把变化范围缩小到了new的那一句,segment 1中只要 new EventLog()后,对后面的代码而言,都只是持有对抽象的Log的引用,segment 2中也一样,在后面都是持有对LogFactory这个抽象类的引用,大家的变化都在new的那一行,那引入工厂方法的意义在哪里?为什么TerryLee说Segment1中“这样的工作量是可想而知的”,而Segment中“只要修改一处”?
带着这个疑问我用我笨重的大脑想了又想,终于在某一天早上醒来的瞬间想通了(好像我需要反醒我的智商了)。
其实如果仅仅只是new了一个具体的日志类的话,引入工厂方法确实没有意义,如我的疑问中所说,两者的修改都只集中在对象的创建那一句,但是,如果我们在程序中需要用到十个不同的日志对象呢?在没有用工厂方法时,我们就要出现10次的Log log = new EventLog(),于是,依赖就开始在程序中遍布,一旦某天要改成文件日志,那就要在这10处修改,改成Log log = new FileLog()。
而我们看看使用Factory Method的情形,首先创建一个工厂对象LogFactory logfactory = new EventLogFactory(),以后每次需要创建日志对象的时候,我们只需要:Log log = logFactory.Create(),为了得到10个不同的日志对象,我们只需要在创建工厂的那一行代码中依赖实现,其余地方都是依赖于抽象,一旦某日要换成文件日志,则只要在创建工厂的地方进行改动就可以了,相对于没有使用工厂方法的程序,耦合度的降低可想而知。
如果在LogFactory logfactory = new EventLogFactory()这里利用反射来创建工厂,那就可以通过修改配置文件实现EventLog和FileLog以及将来要添加的日志记录器之间的更换,当然,你也可以想到在Segment1中使用反射,但如果这样的话,我们创建10个日志对象,就得在10个地方写上反射代码,而这些代码都是冗余的。
总结一下,工厂方法引入后到底解决了什么问题?工厂工厂,从空面意思就可以想到,它一定跟创建大量的产品有关,就像上面的Segment1和Segment2,如果程序只需要一个日志对象(Log)就完事儿,那引入工厂方法反而多写了代码,没有意义,但是当要创建多个产品(Log)时,工厂的优势就出来了,他可以让耦合隔离到一行代码中,而Segment1中则不行。
这是工厂方法,还有一种Design Pattern叫做Abstract Factory,大家都跟工厂有关,那也就是说,他们对大批量创建产品(对象)的情况是很有用的,但他跟工厂方法又不同,如上所述,工厂方法生产来生产去也就生产出了一种产品――日志对象,而抽象工厂相对于它,不同的地方就在于抽象工厂可以生厂“一系列”的产品,和和,看来抽象工厂的规模比较大,厂长也比较有钱咯。
就像工厂方法一样,如果只是创建一个实例,工厂就没有什么太大意义(要是只创建一个,我自己手工做就好了,何必要去盖一个工厂来呢?钱太多了么?),抽象工厂的外观就像下面这样:
当然,各种的Product不能完全没有关系,要不然把牛头和马嘴放到一个工厂类中去生产,那好像就有点对不起“高内聚”大哥了哈。
之后,要创建产品时,只要new一个继承了Factory的具体工厂,再不停的CreateProduct*(),就可以得到许多的产品了。
总结一句,工厂方法和抽象工厂,前者只生产一种产品,而后者是生产一个产品系列。当然,如果本身产品种类就是多变的,今天要让工厂会生产ProductE,后天又要让工厂会生厂ProductM,那抽象工厂也无能为力了。
THE END.
既然标题取成了工厂,那就是Factory Pattern了,前段时间看TerryLee大哥的工厂方法的文章,迷惑了几天,不过在某天早醒来的瞬间,我突然想通了,不过一直没有时间把它前下来,就趁这会儿有空,把它记录下来吧。
First, 贴上TerryLee讲工厂方法那篇文章的地址:http://terrylee.cnblogs.com/archive/2006/01/04/310716.html
下面引用的两段原文就是曾经引起我疑问的地方了:
我曾一直想不通,如果把Segment 1中的 EventLog eventlog = new EventLog();改成Log log = new EventLog(),那会跟下面采用了Factory Method的情况会有多大的差别?大家都把变化范围缩小到了new的那一句,segment 1中只要 new EventLog()后,对后面的代码而言,都只是持有对抽象的Log的引用,segment 2中也一样,在后面都是持有对LogFactory这个抽象类的引用,大家的变化都在new的那一行,那引入工厂方法的意义在哪里?为什么TerryLee说Segment1中“这样的工作量是可想而知的”,而Segment中“只要修改一处”?
带着这个疑问我用我笨重的大脑想了又想,终于在某一天早上醒来的瞬间想通了(好像我需要反醒我的智商了)。
其实如果仅仅只是new了一个具体的日志类的话,引入工厂方法确实没有意义,如我的疑问中所说,两者的修改都只集中在对象的创建那一句,但是,如果我们在程序中需要用到十个不同的日志对象呢?在没有用工厂方法时,我们就要出现10次的Log log = new EventLog(),于是,依赖就开始在程序中遍布,一旦某天要改成文件日志,那就要在这10处修改,改成Log log = new FileLog()。
而我们看看使用Factory Method的情形,首先创建一个工厂对象LogFactory logfactory = new EventLogFactory(),以后每次需要创建日志对象的时候,我们只需要:Log log = logFactory.Create(),为了得到10个不同的日志对象,我们只需要在创建工厂的那一行代码中依赖实现,其余地方都是依赖于抽象,一旦某日要换成文件日志,则只要在创建工厂的地方进行改动就可以了,相对于没有使用工厂方法的程序,耦合度的降低可想而知。
如果在LogFactory logfactory = new EventLogFactory()这里利用反射来创建工厂,那就可以通过修改配置文件实现EventLog和FileLog以及将来要添加的日志记录器之间的更换,当然,你也可以想到在Segment1中使用反射,但如果这样的话,我们创建10个日志对象,就得在10个地方写上反射代码,而这些代码都是冗余的。
总结一下,工厂方法引入后到底解决了什么问题?工厂工厂,从空面意思就可以想到,它一定跟创建大量的产品有关,就像上面的Segment1和Segment2,如果程序只需要一个日志对象(Log)就完事儿,那引入工厂方法反而多写了代码,没有意义,但是当要创建多个产品(Log)时,工厂的优势就出来了,他可以让耦合隔离到一行代码中,而Segment1中则不行。
这是工厂方法,还有一种Design Pattern叫做Abstract Factory,大家都跟工厂有关,那也就是说,他们对大批量创建产品(对象)的情况是很有用的,但他跟工厂方法又不同,如上所述,工厂方法生产来生产去也就生产出了一种产品――日志对象,而抽象工厂相对于它,不同的地方就在于抽象工厂可以生厂“一系列”的产品,和和,看来抽象工厂的规模比较大,厂长也比较有钱咯。
就像工厂方法一样,如果只是创建一个实例,工厂就没有什么太大意义(要是只创建一个,我自己手工做就好了,何必要去盖一个工厂来呢?钱太多了么?),抽象工厂的外观就像下面这样:
public abstract Factory {
public AbstractProductA CreateProductA();
public AbstractProductB CreateProductB();
public AbstractProductC CreateProductC();
//… …
}
public AbstractProductA CreateProductA();
public AbstractProductB CreateProductB();
public AbstractProductC CreateProductC();
//… …
}
当然,各种的Product不能完全没有关系,要不然把牛头和马嘴放到一个工厂类中去生产,那好像就有点对不起“高内聚”大哥了哈。
之后,要创建产品时,只要new一个继承了Factory的具体工厂,再不停的CreateProduct*(),就可以得到许多的产品了。
总结一句,工厂方法和抽象工厂,前者只生产一种产品,而后者是生产一个产品系列。当然,如果本身产品种类就是多变的,今天要让工厂会生产ProductE,后天又要让工厂会生厂ProductM,那抽象工厂也无能为力了。
THE END.