一、引子
話說十年前,有一個暴發戶,他家有三輛汽車——Benz奔馳、Bmw寶馬、Audi奧迪,還雇了司機為他開車。不過,暴發戶坐車時總是怪怪的:上Benz 車后跟司機說“開奔馳車!”,坐上Bmw后他說“開寶馬車!”,坐上Audi說“開奧迪車!”。你一定說:這人有病!直接說開車不就行了?!
而當把這個暴發戶的行為放到我們程序設計中來時,會發現這是一個普遍存在的現象。幸運的是,這種有病的現象在OO(面向對象)語言中可以避免了。下面就以 Java語言為基礎來引入我們本文的主題:工廠模式。
二、分類
工廠模式主要是為創建對象提供過渡接口,以便將創建對象的具體過程屏蔽隔離起來,達到提高靈活性的目的。
工廠模式在《Java與模式》中分為三類:
1)簡單工廠模式(Simple Factory)
2)工廠方法模式(Factory Method)
3)抽象工廠模式(Abstract Factory)
這三種模式從上到下逐步抽象,并且更具一般性。
GOF在《設計模式》一書中將工廠模式分為兩類:工廠方法模式(Factory Method)與抽象工廠模式(Abstract Factory)。將簡單工廠模式(Simple Factory)看為工廠方法模式的一種特例,兩者歸為一類。
兩者皆可,在本文使用《Java與模式》的分類方法。下面來看看這些工廠模式是怎么來“治病”的。
三、簡單工廠模式
簡單工廠模式又稱靜態工廠方法模式。重命名上就可以看出這個模式一定很簡單。它存在的目的很簡單:定義一個用于創建對象的接口。
先來看看它的組成:
1) 工廠類角色:這是本模式的核心,含有一定的商業邏輯和判斷邏輯。在java中它往往由一個具體類實現。
2) 抽象產品角色:它一般是具體產品繼承的父類或者實現的接口。在java中由接口或者抽象類來實現。
3) 具體產品角色:工廠類所創建的對象就是此角色的實例。在java中由一個具體類實現。
那么簡單工廠模式怎么來使用呢?我們就以簡單工廠模式來改造暴發戶坐車的方式——現在暴發戶只需要坐在車里對司機說句:“開車”就可以了。
-
- public interface Car{
- public void drive();
- }
-
-
- public class Benz implements Car{
- public void drive() {
- System.out.println("Driving Benz ");
- }
- }
-
- public class Bmw implements Car{
- public void drive() {
- System.out.println("Driving Bmw ");
- }
- }
- ...(奧迪我就不寫了)
-
-
- public class Driver{
-
- public static Car driverCar(String s)throws Exception{
-
- if(s.equalsIgnoreCase("Benz"))
- return new Benz();
- else if(s.equalsIgnoreCase("Bmw"))
- return new Bmw();
- ......
- else throw new Exception();
- ...
-
-
- public class Magnate{
- public static void main(String[] args){
- try{
-
- Car car = Driver.driverCar("benz");
-
- car.drive();
- ...
//抽象產品角色
public interface Car{
public void drive();
}
//具體產品角色
public class Benz implements Car{
public void drive() {
System.out.println("Driving Benz ");
}
}
public class Bmw implements Car{
public void drive() {
System.out.println("Driving Bmw ");
}
}
...(奧迪我就不寫了)
//工廠類角色
public class Driver{
//工廠方法.注意 返回類型為抽象產品角色
public static Car driverCar(String s)throws Exception{
//判斷邏輯,返回具體的產品角色給Client
if(s.equalsIgnoreCase("Benz"))
return new Benz();
else if(s.equalsIgnoreCase("Bmw"))
return new Bmw();
......
else throw new Exception();
...
//歡迎暴發戶出場......
public class Magnate{
public static void main(String[] args){
try{
//告訴司機我今天坐奔馳
Car car = Driver.driverCar("benz");
//下命令:開車
car.drive();
...
將本程序空缺的其他信息填充完整后即可運行。如果你將所有的類放在一個文件中,請不要忘記只能有一個類被聲明為public。本程序在jdk1.4 下運行通過。
這便是簡單工廠模式了。怎么樣,使用起來很簡單吧?那么它帶來了什么好處呢?
首先,使用了簡單工廠模式后,我們的程序不在“有病”,更加符合現實中的情況;而且客戶端免除了直接創建產品對象的責任,而僅僅負責“消費”產品(正如暴發戶所為)。
下面我們從開閉原則(對擴展開放;對修改封閉)上來分析下簡單工廠模式。當暴發戶增加了一輛車的時候,只要符合抽象產品制定的合同,那么只要通知工廠類知道就可以被客戶使用了。所以對產品部分來說,它是符合開閉原則的;但是工廠部分好像不太理想,因為每增加一輛車,都要在工廠類中增加相應的業務邏輯或者判斷邏輯,這顯然是違背開閉原則的。可想而知對于新產品的加入,工廠類是很被動的。對于這樣的工廠類(在我們的例子中是為司機師傅),我們稱它為全能類或者上帝類。
我們舉的例子是最簡單的情況,而在實際應用中,很可能產品是一個多層次的樹狀結構。由于簡單工廠模式中只有一個工廠類來對應這些產品,所以這可能會把我們的上帝累壞了,也累壞了我們這些程序員:(
于是工廠方法模式作為救世主出現了。
posted on 2009-03-30 08:24
Werther 閱讀(280)
評論(1) 編輯 收藏 所屬分類:
10.Java