這幾天正在學習設計模式,看完書,總得寫點簡單的執行個體吧:-)
所以呢,從今天開始認真寫點簡單的純設計模式實現的Java代碼,先比較淺顯地體會一下設計模式的思想。以便以後在實際項目中正確地使用它。
在這個例子中,ArtTracer的指責是根據客戶的要求繪製各種各樣的圖形;Shape介面是提供一些常用的繪圖操作,3個圖形類分別實現了它;繪圖異常時拋出BadShapeException。
1. 簡單工廠執行個體UML類圖
2. Java實現代碼
package cn.edu.ynu.sei.simpleFactory;
/**
* 客戶,要求繪圖器(<code>ArtTracer</code>)執行個體繪製需要的圖形
*
* @author 88250
* @version 1.0.0, 2007-8-12
*/
public class Client
{
/**
* @param args
*/
public static void main(String[] args)
{
Shape myShape = null;
try
{
myShape = ArtTracer.factory("Circle");
myShape.draw();
myShape = ArtTracer.factory("Square");
myShape.draw();
myShape = ArtTracer.factory("Triangle");
myShape.draw();
myShape.erase();
// ArtTracer.factory("Diamond"); // 將拋出異常
}
catch (BadShapeException bse)
{
bse.printStackTrace();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
package cn.edu.ynu.sei.simpleFactory;
/**
* 圖形繪製器,繪製客戶需要的圖形
* @author 88250
* @version 1.0.0, 2007-8-12
* @uml.dependency supplier="cn.edu.ynu.sei.simpleFactory.Shape"
* @uml.dependency supplier="cn.edu.ynu.sei.simpleFactory.BadShapeException"
*/
public class ArtTracer
{
/**
* 產生需要的圖形執行個體
* @param which 圖形描述
* @return 圖形執行個體
* @throws BadShapeException 產生需要圖形異常
*/
public static Shape factory(String which) throws BadShapeException
{
if (which.equalsIgnoreCase("circle"))
{
return new Circle();
}
else if (which.equalsIgnoreCase("square"))
{
return new Square();
}
else if (which.equalsIgnoreCase("triangle"))
{
return new Triangle();
}
else
{
throw new BadShapeException(which);
}
}
}
package cn.edu.ynu.sei.simpleFactory;
/**
* 圖形異常<br>
* 例如在不能產生客戶需要的圖形時將拋出此異常
* @author 88250
* @version 1.0.0, 2007-8-12
*/
public class BadShapeException extends Exception
{
/**
* 異常類版本ID
*/
private static final long serialVersionUID = 4781771889363091309L;
/**
* 構造器
* @param message 異常資訊
*/
public BadShapeException(String message)
{
super(message + " has any implementation!");
}
}
package cn.edu.ynu.sei.simpleFactory;
/**
* 廣義的圖形操作介面
* @author 88250
* @version 1.0.0, 2007-8-12
*/
public interface Shape
{
/**
* 繪製圖形
*/
public abstract void draw();
/**
* 擦除圖形
*/
public abstract void erase();
}
package cn.edu.ynu.sei.simpleFactory;
/**
* 圓
*
* @author 88250
* @version 1.0.0, 2007-8-12
*/
public class Circle implements Shape
{
@Override
public void draw()
{
System.out.println("Circle.draw()");
}
@Override
public void erase()
{
System.out.println("Circle.erase()");
}
}
package cn.edu.ynu.sei.simpleFactory;
/**
* 正方形
* @author 88250
* @version 1.0.0, 2007-8-12
*/
public class Square implements Shape
{
@Override
public void draw()
{
System.out.println("Square.draw()");
}
@Override
public void erase()
{
System.out.println("Square.erase()");
}
}
package cn.edu.ynu.sei.simpleFactory;
/**
* 三角形
*
* @author 88250
* @version 1.0.0, 2007-8-12
*/
public class Triangle implements Shape
{
@Override
public void draw()
{
System.out.println("Triangle.draw()");
}
@Override
public void erase()
{
System.out.println("Triangle.erase()");
}
}
3. 總結簡單工廠的核心是工廠類。它決定在什麼時候去建立需要的產品,用戶端可以免除直接建立產品的重任,
要什麼只管對工廠說就可以,這也更符合我們日常的生活邏輯。舉個例子,當你需要一把牙刷的時候很
少人會自己去做個自己的牙刷吧?大多人應該都是去牙具店裡買XX牌XX型號的牙刷,付錢是當然的了,
但省心哦,嘿嘿。但牙具店老闆就費心了,管理那麼多不同品種、不同型號的牙刷,一有新品種還要急著
去進貨>_<~~~所以,工廠類的責任很重的,如果加入了新的產品就必然要修改它的原始碼。
還記得在 物件導向設計原則摘要 裡提到的OCP(開-閉原則)嗎?這是OOD中相當重要的一個原則,好
的設計都應該做到這一點,那麼簡單原廠模式是否支援OCP呢?
答案:只能在有限程度上支援。因為OCP要求不能對以“發布”的行為做修改,例如欄位或方法,但是可
以進行擴充,可以增加欄位或方法。而簡單原廠模式中的工廠類不能做到這一點,當加入新的產品類的時候
不得不修改工廠類建立產品方法的邏輯。
儘管如此,簡單原廠模式還是相當重要的,因為它是很多設計模式的基礎之一,而且有的時候往往簡單
的設計可以把工作完成得更出色!
4. 參考文獻
《Design Patterns》、《Java與模式》