《Head of First》中讲到,简单工厂其实并不能算作是一种设计模式,只是编程过程中对问题经常处理的一种习惯。但在Java代码中可以经常看到使用。将到工厂模式的时候不可避免的就要介绍简单工厂。
正是由于简单工厂比较简单,对处理一些简单的问题还是很有效的,至少它能将产品的生产和消费解耦出来。
图1.1
制造者生产产品,具体的产品类都是从父类继承下来的。下面举生产电脑为例。我们知道,现在电脑包括传统的台式电脑(desktop),笔记本电脑(notebook)还有比较新的平板电脑(pad)。 他们都有着共同的祖先—PC,因此有下图
图1.2
父类:
1: public interface PC {
2: public void start();
3: public void shutdown();
4: public void reboot();
5: }
Desktop类:
1: public class Desktop implements PC {
2: public void start() {
3: System.out.println("Desktop start");
4: }
5: public void shutdown() {
6: System.out.println("Desktop shutdown");
7: }
8: public void reboot() {
9: System.out.println("Desktop reboot");
10: }
11: }
Notebook类:
1: public class Notebook implements PC {
2:
3: public void start() {
4: System.out.println("Notebook start");
5: }
6: public void shutdown() {
7: System.out.println("Notebook shutdown");
8: }
9: public void reboot() {
10: System.out.println("Notebook reboot");
11: }
12:}
Pad类:
1: public class Pad implements PC {
2:
3: public void start() {
4: System.out.println("Pad start");
5: }
6: public void shutdown() {
7: System.out.println("Pad shutdown");
8: }
9: public void reboot() {
10: System.out.println("Pad reboot");
11: }
12: }
工厂类:
1: public class ComputerFactory {
2:
3:
4: public static PC computersFactory(String type){
5: if(type.equals("Desktop")){
6: return new Desktop();
7: }
8: if(type.equals("Notebook")){
9: return new Notebook();
10 }
11: if(type.equals("Pad")){
12: return new Pad();
13: }
14: else throw new BmentException("there is not such" + type + "computer");
15: }
16:
17: }
客户如果需要产品的时候,直接调用工厂方法,传入自己需要的产品类型,然后获取相应的产品。
1: public class Customer {
2:
3: public static void main(String[] args){
4: PC pc = null;
5: pc = ComputerFactory.computersFactory("Notebook");
6: pc.reboot();
7: }
8: }
从上面例子及分析知道,简单工厂一般包含有3个角色:工厂(此例中的Computerfactory)、抽象产品(此例中的PC)及具体产品(此例中的Desktop,Notebook和Pad).
工厂:担任着这个模式的核心,它接受从消费者传入的指令,然后按照这条指令制造出相应的具体产品,然后返回给消费者。往往由一个具体的类来实现。在
实际使用过程中,从很多源代码中可以看到,实现生产的方法往往是静态方法,例子很多,比如java.lang包下的Integer类中;
1: static Integer getInteger(String nm);
2: static Integer getInteger(String nm, int val);
3: static Integer getInteger(String nm, Integer val);
抽象产品:一般是接口或者是抽象类,它一般扮演着工厂制造产品方法的返回值。
具体产品:是客户需要的产品,由工厂制造放回给客户。由具体的类来充当这个角色,从抽象产品那里继承而来,并且一般情况有多个类似的具体产品。
简单工厂在应用中还有一些简单的变形,例如,抽象产品同具体产品融合,模式中只有工厂和具体产品;抽象产品同工厂融合,只有抽象产品和具体产品还有工厂、抽象产品及具体产品都融合到一起,这个变形的很多用在单例模式中,以后会涉及到。
在第一种情况中,工厂中生产的方法直接返回具体的产品类型,而不是抽象的产品类型。这中情况很简单,一般需要返回的产品没有共同的抽象类。
第二种情况中,只有抽象产品和具体产品,可以参见java.text.DataFormat类。
第三中情况,一般经常可见于单例模式中。
简单工厂的优缺点:
优点:
1. 简单,容易实现,工厂是简单工厂的核心,必须包含有必要的逻辑判断。
2. 在一定程度上将产品的消费同产品的生产隔离
缺点:
1. 有限程度的支持“开-闭”原则,从上面的例子可以看到如果需要增加一个具体产品,代码的修改是比较多的,工厂类的生产方法要添加新的逻辑判断。
2. 系统的后续扩展性比较差。系统所有逻辑判断都集中到工厂类,增大了系统风险的严重性。因为工厂是整个模式的核心,如果该工厂停止工作,整个模式将处于崩溃。而且工厂类承担了所有的生产工作,形成了一个无所不知的“全能类”。
3. 工厂类生产产品的方法一般是静态方法,静态方法不能为子类所继承,无法形成等级继承关系。
参考文献
1. 《java与模式》阎宏 电子工业出版社 2009.12
Technorati Tags: ,,
阅读(823) | 评论(0) | 转发(0) |