当前位置:编程学习 > C#/ASP.NET >>

我把Black_Cat与Walaqi等关于设计模式之工厂方法抽象工厂的讨论整理如下,以方便设计模式爱好者们

答案:工厂方法中如何知道实体产品到底是什么产品呢?
black_cat 发表于 2002-12-10 11:11

虽然模式上说是为了避免客户端知道具体的实体产品。但如果修改了产品的接口,如何能让客户端知道新的接口呢?
比如一个Garden工厂用Create方法创建了两个产品Flower,Glass,都属于抽象产品Plant,但Flower增加了接口Color,而Glass没有该接口,但有另一个接口EverGreenAble。那客户端还是必须根据具体产品来确定该如何工作,但现在客户端只知道是Plant类型,并不知道究竟是哪个产品啊,这种情况怎么办呢?

********************************************************************************在抽象工厂创建新新产品,往往带有较明显的功能取向性的...
epower2002 发表于 2002-12-10 11:22

比如说:
1) 建立一个抽象工厂(Abstract Factory)类HouseFactory,在这个类中声明:
    CreateWall ()
    CreateDoor ()
    CreateFloor ()
    CreateCeiling ()
    CreatePillar ()
2) 建立相应的抽象产品(Abstract Product)类集:
Wall, Door, Floor, Ceiling, Pillar
3) 为不同风格建立相应的具体工厂(Concrete Factory)类(不要忘了实现关系),例如:
    ChinaHouseFactory : HouseFactory
    GreeceHouseFactory : HouseFactory
    …
4) 为不同的风格建立相应的具体产品(Concrete Product)类(实现相应的抽象产品),例如:
    ChinaWall : Wall
    ChinaDoor : Door
    …
    GreeceWall : Wall
    GreeceDoor : Door
    …
具体请见"简话设计模式"

********************************************************************************工厂方法不知道他所得到的产品的具体类型
walaqi 发表于 2002-12-10 11:41 VB.NET

他只是在一个产品接口上进行操作。
例如:factory的createProduct1()返回一个product1类的实例。
penFactory的createproduct1()返回一个penProduct1类的实例,但是他们都必须满足一个条件,。全部要实现product接口

********************************************************************************这我知道,问题是Product的子类除了实现Product接口外应该还可以定义它们自己的接口呀
black_cat 发表于 2002-12-10 12:09 VB.NET

它们自己的接口就需要根据具体是什么产品来决定了。那么假如要访问各产品自己的接口就必须要知道是什么产品。
刚才我在csdn上问了一下,有人说客户端能判断传入的参数是什么类的(用 product is Flower判断),我不知道是根据什么来判断的?好象tij里说过“上溯造型”“下溯造型”,但我还是没有能透彻得理解,请指教。

********************************************************************************当然可以。
walaqi 发表于 2002-12-11 09:31 VB.NET

一个类可以去实现多个接口。但是其他的接口在你是用工厂模式的场景中是被忽略的。那是另外的事情。
另外,一个类实现多个接口的时候需要需要留意的就是,不要给一个类增加额外的同类名比较模糊的责任。

********************************************************************************被忽略?那样的话是不是就不适合工厂模式了?
black_cat 发表于 2002-12-11 09:49

另外,“不要给一个类增加额外的同类名比较模糊的责任。”是什么意思啊?我高考语文没及格:(

********************************************************************************注意前提:在工厂模式的场景中。
walaqi 发表于 2002-12-11 14:17

所谓工厂模式的场景,就是当客户端掉用工厂方法并获得产品实例的时候,这个时候他只关心产品实例是否实现了产品接口,而不关心产品实例实现的其它接口。
所谓模糊的责任,就是瘦,你建立一个猫的实例,让它实现鸟的接口,那么对于实例的类型名:猫来说,鸟的接口所提供的功能是模糊的。

********************************************************************************那就是说在我的问题中不适合用工厂模式了。
black_cat 发表于 2002-12-11 14:22

是否工厂模式和其他模式结合的应用会有作用?

********************************************************************************模式的结合是经常的。
walaqi 发表于 2002-12-11 14:25

你的问题是什么?

********************************************************************************在主帖中,再贴一遍吧
black_cat 发表于 2002-12-11 14:34

比如一个Garden工厂用Create方法创建了两个产品Flower,Glass,都属于抽象产品Plant,但Flower增加了接口Color,而Glass没有该接口,但有另一个接口EverGreenAble。那客户端还是必须根据具体产品来确定该如何工作,但现在客户端只知道是Plant类型,并不知道究竟是哪个产品啊,这种情况怎么办呢?
-----------------
怎么解决我已经知道了(用plant is Flower),不过我觉得好象脱离了工厂方法的本意了,因为这样客户端就必须要知道确切的产品。不知道这种情况是否超出工厂方法的范畴了。如果一定要用模式的观点去考虑的话可能能用什么模式来解决呢?

********************************************************************************嗬嗬,你对工厂方法的应用没有理解
walaqi 发表于 2002-12-11 14:37

首先,工厂方法只能用于创建一系列功能相近的产品。你的flower和glass完全不相关。这是不能放在一个系列中的。

********************************************************************************这要看分析的粒度了
black_cat 发表于 2002-12-11 14:40

我一开始是从植物的角度分析的。但在设计的过程中又发现粒度需要再细化(这在需求不是很确定或需要增加新的功能的情况下是很正常的),从复用的角度来说也许以上代码大部分都有用,但就是接口需要重新定义,该如何处理呢?

********************************************************************************接口需要重新定义是一个麻烦的问题。
walaqi 发表于 2002-12-11 14:56

接口的作用就是为了保证程序结构的稳定性。如果随意修改接口则无疑对程序造成很不好的影响。
不过看你的样子好像还处在分析阶段?那么你完全可以修改你的接口。
如果已经处于编码阶段。则修改接口可以采用两种方法:
1,定义新的接口
2,修改旧的接口,然后重新编译一边,所有实现该接口的类都会出现类型检查错误,逐一修改,保证所有的对该接口的实现都已经被修改。在重新编译,所有引用了该方法的类也会出现类型检查错误。在修改,就好了。
另外,工厂方法可以接受一个方法,来决定需要返回的产品系列。

********************************************************************************一个系列共享一个产品接口。好像你说的样子必须有两个产品接口
walaqi 发表于 2002-12-11 14:40 VB.NET

另外,仔细阅读一下设计模式书中有关工厂模式的缺点一节。里面有说明。

******************************************************************************** 书上没说什么啊。
black_cat 发表于 2002-12-11 14:46

只是说为了创建一个产品就必须先创建工厂,即使这个工厂除了生产该产品外没有任何用途。
对抽象工厂也只是说如果要添加产品功能就必须要重定义所有的产品接口。

********************************************************************************接口需要重新定义是一个麻烦的问题。
walaqi 发表于 2002-12-11 14:56

接口的作用就是为了保证程序结构的稳定性。如果随意修改接口则无疑对程序造成很不好的影响。
不过看你的样子好像还处在分析阶段?那么你完全可以修改你的接口。
如果已经处于编码阶段。则修改接口可以采用两种方法:
1,定义新的接口
2,修改旧的接口,然后重新编译一边,所有实现该接口的类都会出现类型检查错误,逐一修改,保证所有的对该接口的实现都已经被修改。在重新编译,所有引用了该方法的类也会出现类型检查错误。在修改,就好了。
另外,工厂方法可以接受一个方法,来决定需要返回的产品系列。

********************************************************************************
我觉得最可怕的问题是需求分析时没考虑到,但完成编码时才知道不对。
black_cat 发表于 2002-12-11 15:07 VB.NET

另外,在写程序时如何尽量为以后的升级留好接口,这点可能需要对程序以后要实现的功能也要作一个比较清晰的分析,就是在写ver1.0的时候要考虑到ver2.0以后的使用需求状况。这点也很难。斑竹以为然否?

********************************************************************************
任何人都不可能预知未来
walaqi 发表于 2002-12-11 20:47

即便是一个经验丰富足智多谋的设计师也不可能预知未来,为将来的可能出现的需求定义良好的接口。
设计模式正是为了满足这个需要而诞生的,但是设计模式也只是部分的解决了这个问题。学习设计模式的最终目的,其实不是为了学习设计模式所讲述的方法,而是学习他为了扩展而对结构做出设计的过程和方法。例如工厂模式,将一些操

上一个:一番话--结构型模式
下一个:转:“简”话设计模式

CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,