【Java與模式】簡單工廠模式(Simple Factory---吳義)
首先說明,Java與模式一系列的文章均是參考閻宏博士的《Java與模式》一書,加上自身的一些體會的探索,產生如下文章。在此,特意標明。再談Java與模式,在學習模式之前簡單工廠模式(Simple Factory),需瞭解具體的Java模型圖UML圖的意思,Java中UML圖具體含義的講解請參考我博客的其他文章,它類似於機械工程中的AUTO CAD設計圖紙,Java設計模式大類分爲
- 創建模式(簡單工廠模式、工廠方法模式、抽象工廠模式、單例模式、多例模式、建造模式、原始模型模式)
- 結構模式(適配器模式、缺省適配模式、合成模式、裝飾模式、代理模式、享元模式、門面模式、橋樑模式)
- 行爲模式(不變模式、策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、解釋器模式、調停者模式
本文要講述第一個設計模式(其他設計模式請參考我的其他博客),簡單工廠模式,它是創建模式中最基本的模式,創建模式是對類的實例化過程的抽象化,一些系統在創建對象時,需要動態地決定怎樣創建對象,創建哪些對象,以及如何組合和表示這些對象。創建模式描述了怎樣構造和封裝這些動態的決定。
舉例說明,比如有一個農場,專門向市場銷售各種水果。在這個系統裏需要描述下列水果
- 葡萄 Grape
- 草莓 Strawberry
- 蘋果 Apple
水果和其他的植物有很大不同,水果最終是可以採摘食用的。那麼很自然地做法就是建立一個各種水果都適用的通用接口,以便與農場裏的其他植物區分開,如下UML圖所示
水果接口規定出所有的水果必須實現的接口,包括任何水果類必須具備的方法。種植plant(),生長grow(),以及收穫harvest()。
這個水果接口的源代碼如下所示:
package com.wuyi.creationalPattern;
/**
* Created on 2017/6/9
*
* @author WuYi
*/
public interface Fruit {
public void grow();
public void harvest();
public void plant();
}
Apple類是水果的一種,實現接口Fruit的所有方法。另外,由於蘋果是多年生植物,因此多出一個treeAge性質,來描述蘋果樹的樹齡。下面是這個Apple類的源代碼package com.wuyi.creationalPattern;
/**
* Created on 2017/6/9
*
* @author WuYi
*/
public class Apple implements Fruit {
private int treeAge;
public int getTreeAge() {
return treeAge;
}
public void setTreeAge(int treeAge) {
this.treeAge = treeAge;
}
@Override
public void grow() {
log("Apple is growing");
}
@Override
public void harvest() {
log("Apple has been harvest");
}
@Override
public void plant() {
log("Apple has been planted");
}
/**
* 輔助方法
*/
public static void log(String msg){
System.out.println(msg);
}
}
同理,Grape類是水果的一種,但葡萄分爲有籽和無籽兩類,因此多出一個seedless屬性。代碼如下:package com.wuyi.creationalPattern;
/**
* Created on 2017/6/9
*
* @author WuYi
*/
public class Grape implements Fruit{
private boolean seedless;
public boolean isSeedless() {
return seedless;
}
public void setSeedless(boolean seedless) {
this.seedless = seedless;
}
@Override
public void grow() {
log("Grape is growing");
}
@Override
public void harvest() {
log("Grape has been harvested");
}
@Override
public void plant() {
log("Grape has been planted");
}
/**
* 輔助方法
*/
public static void log(String msg){
System.out.println(msg);
}
}
Strawberry草莓類代碼如下:package com.wuyi.creationalPattern;
/**
* Created on 2017/6/9
*
* @author WuYi
*/
public class Strawberry implements Fruit{
@Override
public void grow() {
log("Strawberry is growing");
}
@Override
public void harvest() {
log("Strawberry has been harvested");
}
@Override
public void plant() {
log("Strawberry has been planted");
}
/**
* 輔助方法
*/
public static void log(String msg){
System.out.println(msg);
}
}
農場的園丁也是系統的一部分,自然要由一個合適的類來代表。這個類就是FruitGardener類(就是我們的工廠類了),FruitGardener類根據客戶端的要求,創建出不同的水果對象,比如蘋果Apple,葡萄Grape或草莓Strawberry的實例,而如果收不到合法的要求,就會拋出BadFruitException異常。BadFruitException異常類代碼如下:package com.wuyi.exception;
/**
* Created on 2017/6/10
*
* @author WuYi
*/
public class BadFruitException extends Exception{
public BadFruitException(String msg){
super(msg);
}
}
FruitGardener園丁類的代碼如下:package com.wuyi.creationalPattern;
import com.wuyi.exception.BadFruitException;
import com.wuyi.staticMethodTest.A;
/**
* Created on 2017/6/9
*
* @author WuYi
*/
public class FruitGardener {
/**
* 靜態工廠方法
*
*/
public static Fruit factory(String which) throws BadFruitException {
if (which.equalsIgnoreCase("apple")){
return new Apple();
}
else if (which.equalsIgnoreCase("strawberry")){
return new Strawberry();
}
else if (which.equalsIgnoreCase("grape")){
return new Grape();
}
else {
throw new BadFruitException("Bad fruit request");
}
}
}
測試類代碼如下:package com.wuyi.creationalPattern;
import com.wuyi.exception.BadFruitException;
/**
* Created on 2017/6/10
*
* @author WuYi
*/
public class FactoryTest {
public static void main(String[] args) {
try {
Fruit apple = FruitGardener.factory("apple");
Fruit grape=FruitGardener.factory("grape");
Fruit strawBerry=FruitGardener.factory("strawberry");
apple.grow();
grape.grow();
strawBerry.grow();
} catch (BadFruitException e) {
e.printStackTrace();
}
}
}
結果輸出:"D:\Java JDK1.7\bin\java" "-javaagent:D:\Idea\IntelliJ IDEA 2017.1\lib\idea_rt.jar=9689:D:\Idea\IntelliJ IDEA 2017.1\bin" -Dfile.encoding=UTF-8 -classpath "D:\Java JDK1.7\jre\lib\charsets.jar;D:\Java JDK1.7\jre\lib\deploy.jar;D:\Java JDK1.7\jre\lib\ext\access-bridge-64.jar;D:\Java JDK1.7\jre\lib\ext\dnsns.jar;D:\Java JDK1.7\jre\lib\ext\jaccess.jar;D:\Java JDK1.7\jre\lib\ext\localedata.jar;D:\Java JDK1.7\jre\lib\ext\sunec.jar;D:\Java JDK1.7\jre\lib\ext\sunjce_provider.jar;D:\Java JDK1.7\jre\lib\ext\sunmscapi.jar;D:\Java JDK1.7\jre\lib\ext\zipfs.jar;D:\Java JDK1.7\jre\lib\javaws.jar;D:\Java JDK1.7\jre\lib\jce.jar;D:\Java JDK1.7\jre\lib\jfr.jar;D:\Java JDK1.7\jre\lib\jfxrt.jar;D:\Java JDK1.7\jre\lib\jsse.jar;D:\Java JDK1.7\jre\lib\management-agent.jar;D:\Java JDK1.7\jre\lib\plugin.jar;D:\Java JDK1.7\jre\lib\resources.jar;D:\Java JDK1.7\jre\lib\rt.jar;D:\Idea\Idea WorkSpace\Design_Principles_and_Patterns_In_Java\out\production\Design_Principles_and_Patterns_In_Java" com.wuyi.creationalPattern.FactoryTest
Apple is growing
Grape is growing
Strawberry is growing
Process finished with exit code 0
簡單工廠模式是類的創建模式,這個模式的一般性結構如下圖所示: