-
转载地址:http://www.iteye.com/problems/22426
-
工厂模式是:定义一个用于创建对象的接口,让子类决定实例化哪一个类,使一个类的实例化延迟到子类。
它有个特点,就是通常工厂的类层次与产品的类层次几乎是一样的树。如果说工厂是你的影子,你就是产品了。在你平时未用到模式的时候,你需要什么就new一个,这种情况就好比你躺在地上,人影合一了。那什么时候需要工厂模式呢。看看定义:“使一个类的实例化延迟到子类”,这个是关键,当你有必要延迟实例化的时候才需要用工厂模式。那什么情况下要延迟呢,在单例模式中有惰性单例(就是单例那个静态属性)……等等,就是一开始你还不适合立刻就创建该对象,你还需要一些资源或其它准备工作。整个系统的运行不像单个程序那样,系统需要很多资源和多方面的协同工作。
抽象工厂是:提供一个创建一系列相关或相互依赖对象的接口,而无虚指定他们的具体类。
抽象工厂比工厂模式复杂的多。如果楼主说他们像可能是他们都叫工厂,都生成产品,都是接口型设计模式。但是我觉得他们是两个不同的设计模式。首先他们的目的是不同的。工厂是为了“延迟创建”,而抽象工厂是提供一系列的接口,是为了组织创建对象的灵活性,避免重复,避免耦合低内聚。
设计模式本身语言晦涩难懂,这个抽象工厂我也是没次都看着头昏眼花^_^,举个运用他的场景:
1。你有两台单色打印机,一台黑白墨的,一台彩墨的。
2。你有两种文件要打,一种讲演搞,一种图片
3。要求是讲演稿如果是有图就打黑白的,没图打彩色的,照片有字的就打黑白的,没字就打彩色的。
class Print{
……
void doTalk(){
if(flag)
//color 1
else
//non-color 2
}
void doPicture(){
if(flag)
//color 3
else
//non-color 4
}
……
}
上面的这个场景就是可以运用抽象工厂来重构的。
public abstract class AbsFactory{
abstract TalkPrint getTalkPrint(); //打讲演稿
abatract PicPrint getPicPrint(); //打图片的
}
public class ColorFactory extends AbsFactory{
TalkPrint getTalkPrint(){
//彩色讲演稿打印
}
PicPrint getPicPrint(){
//彩色图片打印
}
}
public class NonColorFactory extends AbsFactory{
TalkPrint getTalkPrint(){
//黑白讲演稿打印
}
PicPrint getPicPrint(){
//黑白图片打印
}
}
public abstract class TalkPrint{
//抽象的讲演稿打印
}
public class colorTalkPrint extends TalkPrint{
//彩色讲演稿打印
}
public class noncolorTalkPrint extends TalkPrint{
//黑白讲演稿打印
}
public abstract class PicPrint{
//抽象的图片打印
}
public class colorPicPrint extends PicPrint{
//彩色图片打印
}
public class noncolorPicPrint extends PicPrint{
//黑白图片打印
}
进一步解释这个场景,就是当你做相似的工作又多种选择的时候,可以考虑用抽象工厂。
这里你要打印各种文件是一组相似的工作,打印有彩色、黑白等针对打印的不同要求。
这里仅仅举了一个方面的例子。
我们可以看出,虽然抽象工厂和工厂在代码形式上很相似,甚至抽象工作可以有工厂来拓展,但是他们的出发点是不一样的。
在搞单例模式的时候我们针对多线程拓展了为“双重检查模式”,那是同一个场景同一个任务,跟这里是不一样的。
关于单例模式,我有笔记留在我的博客,欢迎大家来一起讨论:
http://zhaipuhong.iteye.com/blog/214675
下面是一个形象的比喻: 无论是简单工厂模式、工厂模式还是抽象工厂模式,它们本质上都是将不变的部分提取出来,将可变的 部分留作接口,以达到最大程度上的复用。拿一个生产水杯(cup)的工厂举例:起初,不用工厂模式,我 必须在生产水杯之前知道水杯的材料和形状等水杯的所有特征才能生产,这就是我们的new Cup();这个Cup必须是具体的。厂主 发现同一形状的被子,只是材料不同,如一个是玻璃(glass)的,一个是瓷(china)的,但是确要两条生产线,显然有资源浪费的嫌疑 。现在厂主生产杯子时先不让生产线知道我要产的是玻璃的还是瓷的,而是让它在不知道具体材料的情况下先做它能做的,等到它把 模具做好,只需要向其中填充玻璃原料或者瓷原料就可以造出同一形状的具体杯子了。但是很可惜,java并不能new一个抽象的Cup,所以 就有了简单工厂模式。原来是Cup cup=new Cup;现在是SimpleCupFactory.createCup(String cupName),根据cup的名字生产Cup,而createCu p返回的是一个实现了 Cup接口或抽象类的具体Cup。简单抽象工厂模式有一个问题,就是当我现在想生产一个同样形状的铁杯时,工厂里并没有 定义相应的处理流程,只能更改createCup方法,这就不合理了。我现在只是想生产铁杯,你只要在最后的时候把玻璃原料换成铁的不就行了吗, 干嘛还要更改整条生产线呢?于是就有了工厂模式。原来生产线在生产模具的时候还要考虑是为玻璃杯生产的模具还是为铁杯生产的模具,现在它不用 管了。CupFactory.createCup()创建Cup.CupFactory是接口或抽象类。实现它的具体子类会创建符合Cup接口的具体Cup。那么现在厂主想要生产水壶(ke ttle),用工厂模式就不得不再造一条水壶生产线,能不能在水杯生产线同时生产水壶呢?这就是抽象工厂模式。