作者dream1124 (全新开始)
看板java
标题[问题] 为什麽工厂方法模式的实作要用继承的?
时间Sun Aug 29 01:43:43 2010
O'Relly的head first design patterns有些例子不错,
但Factory Method这边我看不太懂意义在哪....
想麻烦大家解答一下︰
书上一开始从Simple Factory模式着手,接着用现成的案例延伸到工厂方法模式。
首先他们用pizza类比为工厂产品,PizzaShop负责丢出产品生产与加工後的结果
而SimpleFactory则作为PizzaShop类别的建构子参数,简单说就是这样︰
public PizzaShop(SimpleFactory simpleFactory){
this.simpleFactory = simpleFactory; }
public Pizza orderPizza(){
Pizza pizza = simpleFactory.createPizza();
//以上是物件的生产过程 以下是处理物件的SOP流程
pizza.bake();
pizza.box();
return pizza;
}
到这边我都明白这样做的用意︰
产生物件与处理物件的SOP流程应该要分开,这样才不会改一项就动到整个类别。
可是当这例子延伸到工厂方法模式之後,我就不明白为什麽要定义抽象方法?
工厂模式下,PizzaShop变成抽象类别
public Pizza orderPizza(){
Pizza pizza = createPizza();
//内容和上个例子相同 故省略
}
public abstract Pizza createPizza(){
//交给次类别实作
}
书上在这边是说,PizzaShop类别不需要了解次类别的实作方式就能取得物件。
因此,当产生物件的工厂有好几种时,就不用像简单工厂模式那样,
需要产生多种参数不同的建构式给不同的工厂类别。
选择实作createPizza次类别的同时,也就决定了产生物件的工厂种类。
但我的问题是,PizzaShop类别可以透过泛型,统一所有工厂类别的呼叫方法,
那为什麽要在PizzaShop设计抽象方法呢?
例如︰
public class PizzaFactory{
public Pizza createPizza(){
//继承後可覆写的内容,或是createPizza直接设计为抽象类别
}
}
public class PizzaShop<F extends PizzaFactory>{
private F factory;
public PizzaShop(F factory){ this.factory = factory; } //建构式
public Pizza orderPizza(){
Pizza pizza = factory.createPizza();
//下略 一样是处理pizza的SOP流程
}
}
写成这样,可以同时搞定简单工厂模式的目地--生产与加工分离,
而且还能弹性地决定生产物件的工厂种类--也就是工厂方法模式想达到的目地,
同时还可以让物件工厂彼此的生产过程都能有些不同,不需限制细节。
因此我不明白工厂方法模式搞到这麽复杂的意义在哪里....?
他们到底是想松绑哪些物件之间的依赖关系啊?
工厂方法模式的精髓是在哪里呢?
还是说,这个模式的发展背景是在Java还没有泛型的年代,
他们只好用这个模式来解决问题?
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 61.231.147.11
1F:→ ogamenewbie:你或许可以去查一下 interface 的 method 是... 08/29 03:58
没事,我只是不太熟泛型罢了.... 给人贴上interface的基础定义实在很冏....
最後的例子原先是用泛型内继承写的,写了以後,想说看能不能增加工厂类别
实作上的弹性,於是直觉地以为可以限制泛型里填入的类别都实作特定介面
供orderPizza()呼叫就好,而不必非得要继承自某个物件....
结果我却忘记泛型里面不能implements interface,现在我改回原本构想的样子。
只是改了以後的物件操作方式就和工厂方法模式类似了....
4F:→ qrtt1:抽象方法会比泛型复杂吗!? 08/29 12:00
哈,是没错啦,泛型没有比抽象方法单纯....而且潜藏一些初始化过程不当使用的危险
不过原本例子改回当初构想的样子之後,用哪种方法都没有什麽本质上的差别。
我想应该就可以不用再讨论用哪种方法实作工厂方法比较好罗....
※ 编辑: dream1124 来自: 61.228.46.154 (08/29 12:08)
5F:→ qrtt1:那建议您重写一个问题呗. 不然後续想回的人, 有点难理解 08/29 12:11
6F:→ qrtt1:潜藏一些初始化过程不当使用的危险=>不太明白, 有例子吗? 08/29 12:59