锁定老帖子 主题:工厂方法模式和抽象工厂模式区别究竟在哪里?
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2006-02-19
Define an interface for create an object,but let subclass decide which class to instantiate.Factory Method lets a class defer instantiation to the subclasses. Abstract Factory: Provide an interface for creating families of related or dependent objects without specifying their concrete classes. 我的疑问是: 1 工厂方法模式能不能看成是一种极端情况的抽象工厂模式,而抽象工厂模式可以看成是工厂方法模式的一种推广? 因为根据定义,工厂方法模式是用来创建一个产品的等级结构的,而抽象工厂模式是用来创建多个产品的等级结构的。 那么假如目前使用工厂方法模式创建不同类型的苹果,示例代码如下: public interface Factory { Apple createApple(); } public class ConcreteFactory1 implements Factory { public Apple createApple() { return new RedApple(); } } public class ConcreteFactory2 implements Factory { public Apple createApple() { return new GreenApple(); } } 上面的代码是使用工厂方法模式。那么现在假如现在我需要创建葡萄,因此需要增加创建葡萄的方法。代码如下: public interface Factory { Apple createApple(); Grape createGrape(); } public class ConcreteFactory1 implements Factory { public Apple createApple() { return new RedApple(); } public Grape createGrape() { return new RedGrape(); } } public class ConcreteFactory2 implements Factory { public Apple createApple() { return new GreenApple(); } public Grape createGrape() { return new GreenGrape(); } } 增加创建葡萄的方法以后,就把一个工厂方法模式变成了一个抽象工厂模式,同样的道理,假如我现在去掉创建葡萄的方法以后,我就把一个抽象工厂模式变成了工厂方法模式。因此可不可以认为这两者之间在不同情况下可以相互转换? 2 “工厂方法模式是采用inheritence,而抽象工厂模式是采用composition。”但是我看不出这就是它们的区别。我同样可以把工厂方法模式中的工厂交给客户端,从而为客户端产生一个产品的不同类型。这样客户端直接依赖于一个工厂,难道这里不也是composition? 3 “工厂方法模式通常和模板方法模式一起结合使用。”但是我仍然看不出来这也是它们的区别。我同样可以把一个抽象工厂模式结合模板方法模式使用。 期待达人解惑! 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2006-02-19
swiminthesea 写道 Factory Method:
Define an interface for create an object,but let subclass decide which class to instantiate.Factory Method lets a class defer instantiation to the subclasses. Abstract Factory: Provide an interface for creating families of related or dependent objects without specifying their concrete classes. 我的疑问是: 1 工厂方法模式能不能看成是一种极端情况的抽象工厂模式,而抽象工厂模式可以看成是工厂方法模式的一种推广? 因为根据定义,工厂方法模式是用来创建一个产品的等级结构的,而抽象工厂模式是用来创建多个产品的等级结构的。 那么假如目前使用工厂方法模式创建不同类型的苹果,示例代码如下: public interface Factory { Apple createApple(); } public class ConcreteFactory1 implements Factory { public Apple createApple() { return new RedApple(); } } public class ConcreteFactory2 implements Factory { public Apple createApple() { return new GreenApple(); } } 上面的代码是使用工厂方法模式。那么现在假如现在我需要创建葡萄,因此需要增加创建葡萄的方法。代码如下: public interface Factory { Apple createApple(); Grape createGrape(); } public class ConcreteFactory1 implements Factory { public Apple createApple() { return new RedApple(); } public Grape createGrape() { return new RedGrape(); } } public class ConcreteFactory2 implements Factory { public Apple createApple() { return new GreenApple(); } public Grape createGrape() { return new GreenGrape(); } } 增加创建葡萄的方法以后,就把一个工厂方法模式变成了一个抽象工厂模式,同样的道理,假如我现在去掉创建葡萄的方法以后,我就把一个抽象工厂模式变成了工厂方法模式。因此可不可以认为这两者之间在不同情况下可以相互转换? 2 “工厂方法模式是采用inheritence,而抽象工厂模式是采用composition。”但是我看不出这就是它们的区别。我同样可以把工厂方法模式中的工厂交给客户端,从而为客户端产生一个产品的不同类型。这样客户端直接依赖于一个工厂,难道这里不也是composition? 3 “工厂方法模式通常和模板方法模式一起结合使用。”但是我仍然看不出来这也是它们的区别。我同样可以把一个抽象工厂模式结合模板方法模式使用。 期待达人解惑! 工厂方法创建一般只有一个方法,创建一种产品。 抽象工厂一般有多个方法,创建一系列产品。 |
|
返回顶楼 | |
发表时间:2006-02-19
pikachu 写道 工厂方法创建一般只有一个方法,创建一种产品。 抽象工厂一般有多个方法,创建一系列产品。 就只有这点区别吗?实在难以让人信服。如果区别就这么简单,为什么要取两个不同的名字呢? |
|
返回顶楼 | |
发表时间:2006-02-19
swiminthesea 写道 pikachu 写道 工厂方法创建一般只有一个方法,创建一种产品。 抽象工厂一般有多个方法,创建一系列产品。 就只有这点区别吗?实在难以让人信服。如果区别就这么简单,为什么要取两个不同的名字呢? 目的不一样 工厂方法创建 "一种" 产品,他的着重点在于"怎么创建",也就是说如果你开发,你的大量代码很可能围绕着这种产品的构造,初始化这些细节上面。也因为如此,类似的产品之间有很多可以复用的特征,所以会和模版方法相随。 抽象工厂需要创建一些列产品,着重点在于"创建哪些"产品上,也就是说,如果你开发,你的主要任务是划分不同差异的产品线,并且尽量保持每条产品线接口一致,从而可以从同一个抽象工厂继承。 举个不太恰当的例子,如果让我设计一款战略游戏,我可能会设计这样的结构 public interface AbstractForceFactory { Unit createUnit(int unitTypeId);; //一般单位 Building createBuilding(int buildingTypeId);; //建筑物 Hero createHero(int heroTypeId);; //英雄人物 } 然后再设计出 AllyFactory ,RussianFactory等几个产品线。 至于V3Unit,我可能会去调用一个V3UnitFactory.create()去创建,而这个Factory很可能是从一个abstract的VehicleFactory继承下来 或者设计一个V3UnitBuilder ?? |
|
返回顶楼 | |
发表时间:2006-02-20
嗯,有点明白了。
但是我想知道Factory Method模式和Abstract Factory模式是否有严格的区分界限。 我也来举一个例子: public abstract class AbstractTerranFactory { //创建机枪兵 public abstract Marine createMarine();; //创建喷火兵 public abstract Fireman createFireman();; //创建医生 public abstract Medical createMedical();; public void prepare(); { Marine marine = createTank();; Fireman fireman = createFireman();; Medical medical = createMedical();; //每个士兵首先要训练 marine.training();; fireman.training();; medical.training();; //然后为每个士兵装备 marine.equip();; fireman.equip();; medical.equip();; } } 现在我为上面得TerranFactory提供一个实现,专门创建某一类机枪兵、喷火兵、医生MM。然后出兵之前,调用TerranFactory.prepare()方法。 好,我的问题来了。现在上述工厂涉及到了“创建一类对象”,但是伴随着创建时,也伴随了一些training,equip方法,用到了Template Method模式。那么现在是使用了Factory Method模式还是Abstract Factory模式? 进一步讲,假如现在我去掉创建喷火兵,医生的方法,只留下创建机枪兵的方法,现在又是Factory Method模式还是Abstract Factory模式? |
|
返回顶楼 | |
发表时间:2006-02-20
swiminthesea 写道 嗯,有点明白了。
但是我想知道Factory Method模式和Abstract Factory模式是否有严格的区分界限。 我也来举一个例子: public abstract class AbstractTerranFactory { //创建机枪兵 public abstract Marine createMarine();; //创建喷火兵 public abstract Fireman createFireman();; //创建医生 public abstract Medical createMedical();; public void prepare(); { Marine marine = createTank();; Fireman fireman = createFireman();; Medical medical = createMedical();; //每个士兵首先要训练 marine.training();; fireman.training();; medical.training();; //然后为每个士兵装备 marine.equip();; fireman.equip();; medical.equip();; } } 现在我为上面得TerranFactory提供一个实现,专门创建某一类机枪兵、喷火兵、医生MM。然后出兵之前,调用TerranFactory.prepare()方法。 好,我的问题来了。现在上述工厂涉及到了“创建一类对象”,但是伴随着创建时,也伴随了一些training,equip方法,用到了Template Method模式。那么现在是使用了Factory Method模式还是Abstract Factory模式? 进一步讲,假如现在我去掉创建喷火兵,医生的方法,只留下创建机枪兵的方法,现在又是Factory Method模式还是Abstract Factory模式? ok,好像讨论到一些本质上了。为什么是Abstract,因为是抽象的(好像是废话:D ) ,从FactoryMethod上抽象出来的。我认为每个AbstractFactory创建的都是一条产品线,而这条产品线会有多个子类派生。比如AbstractTerranFactory ,是否会有或者可能有多种实现方式,比如BlizzardTerranFactory,或者WestWoodTerranFactory,或者MicrosoftTerranFactory。如果是这样的,那么ok,至少是一种Abstract Factory。 至于你的代码,其实并不矛盾,没有人说一个类只能是一种设计模式的,你完全可以认为你的AbstractTerranFactory 是一个AbstractFactory + FactoryMethod+Template,如果去掉创建喷火兵,医生的方法,只留下创建机枪兵的方法,就不是AbstractFactory。 另: design patterns一般是在设计阶段考虑的,所以取名design啊(又是一句废话:D ),真正干活的时候,是先看需求,然后考虑这些需求同哪些模式的适用场合匹配.实际开发中对代码修改后,很可能就随之改变了原来的模式特征,这也很正常,模式之间本来就是可以互相演化和关联的. 再另: 兄弟多大了?现在还玩sc不成? 再再另,你应该refact一下你的代码,Marine marine = createTank();会让人混淆 |
|
返回顶楼 | |
发表时间:2006-02-20
pikachu 写道 ok,好像讨论到一些本质上了。为什么是Abstract,因为是抽象的(好像是废话:D ) ,从FactoryMethod上抽象出来的。我认为每个AbstractFactory创建的都是一条产品线,而这条产品线会有多个子类派生。比如AbstractTerranFactory ,是否会有或者可能有多种实现方式,比如BlizzardTerranFactory,或者WestWoodTerranFactory,或者MicrosoftTerranFactory。如果是这样的,那么ok,至少是一种Abstract Factory。 至于你的代码,其实并不矛盾,没有人说一个类只能是一种设计模式的,你完全可以认为你的AbstractTerranFactory 是一个AbstractFactory + FactoryMethod+Template,如果去掉创建喷火兵,医生的方法,只留下创建机枪兵的方法,就不是AbstractFactory。 另: design patterns一般是在设计阶段考虑的,所以取名design啊(又是一句废话:D ),真正干活的时候,是先看需求,然后考虑这些需求同哪些模式的适用场合匹配.实际开发中对代码修改后,很可能就随之改变了原来的模式特征,这也很正常,模式之间本来就是可以互相演化和关联的. 再另: 兄弟多大了?现在还玩sc不成? 再再另,你应该refact一下你的代码,Marine marine = createTank();会让人混淆 嗯。了解了,谢谢你得回复。 我下个月23岁。以前大学常常打SC,现在没怎么打了,水平很菜了。 BTW: 听说你手下人常常跳槽,呵呵,这不是你的原因,现在的队伍本来就不好带了。 |
|
返回顶楼 | |
发表时间:2006-02-21
TO pikachu:
正好再问你一下Command模式和Adapter模式的区别。现在我怎么觉得它们两个是一样的。 以Webwork为例(因为Webwork使用了Command模式),先看看我的理解是否正确: /** * 这是Webwork里面的Action接口,它充当了抽象Command的角色。 */ public interface Action { public String execute();; } /** * 该类实现了抽象Command,扮演一个具体的Command角色 */ public class LoginAction implements Action{ // 该类是不是可以理解为一个Receiver的角色? private AccountManager accountManager public LoginAction(AccountManager accountManager); { this.accountManager = accountManager; } public String execute(); { accountManager.login();; return "login"; } } 我的理解是:Webwork中的ServletDispather充当了Invoker的角色。在一个典型的Web应用程序中,有各种请求需要处理,例如登录、查看、删除、增加、修改等等。因此根据需求的不同,会出现AccountManger,ProductManager(Receiver)等等相应的类来处理各种不同请求。然而ServletDispather并不知道该如何调用这些Receiver的方法,因此需要通过一个Action(Command)接受不同的Receiver,由Action负责调用Receiver的方法。而SerlvetDispather只需调用Action.execute()就可以了。不知道以上理解是否正确? 同时我又觉得这非常象Adapter模式。因为可以认为ServletDispather只能处理Action(Adapter模式中的Target角色)类型的接口,而我们的业务逻辑层存在大量诸如AccoutManager、ProduntManager的类(Adapter模式中的Adaptee角色),因此为了让ServletDispather来使用业务逻辑层的类,因此我们编写了诸如LoginAction、ProductAction(Adapter模式中的Adapter角色)来使用业务逻辑层的对象。因此我怎么觉得Command模式非常象Adapter模式? |
|
返回顶楼 | |
发表时间:2006-02-21
设计模式的不同主要看意图,你如果只看程序的组织形式会发现很多相似的地方,记得那个地方说过这可能是同于编程语言语法的关系.
|
|
返回顶楼 | |
发表时间:2006-02-21
yb31 写道 设计模式的不同主要看意图,你如果只看程序的组织形式会发现很多相似的地方,记得那个地方说过这可能是同于编程语言语法的关系.
楼上的正解,出发点不同,人员不同,一段代码就可能会有多种看法。 以WW的开发人员看来,他们设计框架,Action是他们的Command。从你看来你的Action像是Adaptor。为了将你的Manager适配到ww的制定接口上。 这些本身就不怎么分的清,不过有一点倒是可以作为参考 command是为了让框架结构处理未知的过程,有点回掉的味道。 Adaptor是为了让已经存在的对象转换为另一套接口上 |
|
返回顶楼 | |