??xml version="1.0" encoding="utf-8" standalone="yes"?>91ph在线,国产精品区免费视频,国产真实乱对白精彩久久http://www.aygfsteel.com/jesson2005/category/21662.htmlN文hQ乃?jng)井一俗h也,ȝ?rn)卷书Q跨江河千里Q故甛_一游; 一两滴辛酸Q三四年学业Q五六点_墨Q七八笔买卖Q九(ji)十道人情?/description>zh-cnThu, 19 Apr 2007 13:18:06 GMTThu, 19 Apr 2007 13:18:06 GMT60Design Pattern: Prototype 模式http://www.aygfsteel.com/jesson2005/articles/111168.html张金?/dc:creator>张金?/author>Tue, 17 Apr 2007 02:35:00 GMThttp://www.aygfsteel.com/jesson2005/articles/111168.htmlhttp://www.aygfsteel.com/jesson2005/comments/111168.htmlhttp://www.aygfsteel.com/jesson2005/articles/111168.html#Feedback0http://www.aygfsteel.com/jesson2005/comments/commentRss/111168.htmlhttp://www.aygfsteel.com/jesson2005/services/trackbacks/111168.html
Prototype模式的作用有些類g面的描述Q?zhn)在父別中定一個clone()Ҏ(gu)Q而在子類別中重新定義它,當客戶端於所產生的物件有興趣並想加以利用Q而?zhn)又不想破壞原來的物gQ?zhn)可以產生一個物件的複本i它?br>
Prototypeh展示的意呻I像是展覽會上的原型車款Q當(zhn)對某個車ƾ感興趣時,(zhn)可以購L(fng)同款C的車,而不是車展上的車?br>
在軟體設a上的例子會更清楚的說明Z要進行物g複製Q假a?zhn)要設a一個室內設a軟體,軟體中有一個展C家L(fng)工具列,(zhn)只要點選工具列可以產生一個家兯本,例如一?j)|子或桌子Q?zhn)可以拖曳這個複製的物g臌a圖中,隨時改變它的位置、顏色等{,當?zhn)改變a計圖中的物件時Q工具列上的原型工具列是不會跟著一h變的Q這個道理是無需解釋的?br>
下面?UML 別圖表CZ(jin)上述的簡單概念:(x)
Prototype

Prototype模式的重點在於clone()Q它負K複製物g本n並傳回,但這個clone()本n在實作上存在一些困難,其是當物g本n又繼承另一個物件時Q如何確保複製的物g完整無誤Q在不同的程式語a中有不同的作法?br>
在Java中的作法是透過實作一個Cloneable介面Q它只是一個聲明的介面Q並無規定Q何實作的Ҏ(gu)Q?zhn)的目的是改寫Object的clone ()Ҏ(gu)Q其具備有複製物g的功能,這個方面徏議?zhn)參考:(x)How to avoid traps and correctly override methods from java.lang.Object?br>
用一個簡單的例子來實作上圖中的結構,這個例子利用了(jin)Java語言本n的cloneҎ(gu):(x)
  • AbstractFurniture.java
public abstract class AbstractFurniture 
implements Cloneable {
public abstract void draw();

// 在Design Pattern上,以下的clone是抽象未實作?br> // 實際上在Java中class都繼承自Object
// 所以在這邊我們直接重新定clone()
// 這是Z(jin)W合Java現行的clone制
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}

CircleTable與SquareTableJ承?jin)AbstractFurnitureQ並實作cloneҎ(gu)Q用於傳回本w的複製品:(x)
  • CircleTable.java
import java.awt.*;

public class CircleTable extends AbstractFurniture {
protected Point center;

public void setCenter(Point center) {
this.center = center;
}

protected Object clone ()
throws CloneNotSupportedException {
Object o = super.clone();
if(this.center != null) {
((CircleTable) o).center = (Point) center.clone();
}

return o;
}

public void draw() {
System.out.println("\t圓桌\t中心(j)Q?" + center.getX()
+ ", " + center.getY()+ ")");
}
}

  • SquareTable.java
import java.awt.*;

public class SquareTable extends AbstractFurniture {
protected Rectangle rectangle;

public void setRectangle(Rectangle rectangle) {
this.rectangle = rectangle;
}

protected Object clone ()
throws CloneNotSupportedException {
Object o = super.clone();
if(this.rectangle != null) {
((SquareTable) o).rectangle = (Rectangle) rectangle.clone();
}

return o;
}

public void draw() {
System.out.print("\tҎ(gu)\t位置Q?" + rectangle.getX()
+ ", " + rectangle.getY()+ ")");
System.out.println(" / 寬高Q?" +
rectangle.getWidth()
+ ", " + rectangle.getHeight()+ ")");
}
}

House是個虛擬的房屋物gQ從Prototype複製Z的物件加入至House中:(x)
  • House.java
import java.util.*;

public class House {
private Vector vector;

public House() {
vector = new Vector();
}

public void addFurniture(AbstractFurniture furniture) {
vector.addElement(furniture);

System.out.println("現有家具....");

Enumeration enumeration = vector.elements();
while(enumeration.hasMoreElements()) {
AbstractFurniture f =
(AbstractFurniture) enumeration.nextElement();
f.draw();
}
System.out.println();
}
}

再來是應用程式本w:(x)
  • Application.java
import java.awt.*;

public class Application {
private AbstractFurniture circleTablePrototype;

public void setCircleTablePrototype(
AbstractFurniture circleTablePrototype) {
this.circleTablePrototype = circleTablePrototype;
}

public void runAppExample() throws Exception {
House house = new House();
CircleTable circleTable = null;

// 從工具列選擇一個家具加入房子中
circleTable =
(CircleTable) circleTablePrototype.clone();
circleTable.setCenter(new Point(10, 10));
house.addFurniture(circleTable);

// 從工具列選擇一個家具加入房子中
circleTable =
(CircleTable) circleTablePrototype.clone();
circleTable.setCenter(new Point(20, 30));
house.addFurniture(circleTable);
}

public static void main(String[] args) throws Exception {
Application application = new Application();
application.setCircleTablePrototype(
new CircleTable());
application.runAppExample();
}
}

Java中的clone()Ҏ(gu)是繼承自ObjectQAbstractFurniture的子別則override這個clone()Ҏ(gu)Q以複製其本w並傛_?br>
下圖為Prototype模式的類別結構圖Q?
Prototype
?Gof 的設a模式書中Z個原型模式的應用Q一個通用的圖型編輯器 Framework。在這?Framework中有一個工具列Q?zhn)可以在上面選擇音樂符號以加入樂譜中,並可以隨時調整音樂符號的位置{等?br>
圖型R輯器Framework是通用的,然而它並不知道這些x(chng)W號的型態,有h或許會想到繼承圖型編輯器Framework來為每個音樂符號設a一個框架子別Q但由於x(chng)W號的種很多,這會產生相當多的子類別,Z(jin)避免這種情況Q可以透過Prototype模式來減子別的數目,可以a計Z下的i構Q?br>
Prototype

依照這個結構,圖型R輯器的Framework可以獨立D套用的特定類別之外,雖然不知道被複製傛_的對象型態是什|但總可以按照 Graphics所定義的介面來操作這些物g?br>

]]>
Design Pattern: Builder 模式http://www.aygfsteel.com/jesson2005/articles/111169.html张金?/dc:creator>张金?/author>Tue, 17 Apr 2007 02:35:00 GMThttp://www.aygfsteel.com/jesson2005/articles/111169.htmlhttp://www.aygfsteel.com/jesson2005/comments/111169.htmlhttp://www.aygfsteel.com/jesson2005/articles/111169.html#Feedback0http://www.aygfsteel.com/jesson2005/comments/commentRss/111169.htmlhttp://www.aygfsteel.com/jesson2005/services/trackbacks/111169.html
(zhn)可以在E式中定兩個角Ԍ一個是指導q宮建立的Director角色Q一個是按照指導者指C徏立迷宮的Builder角色QDirectorҎ(gu)定義的迷宮陣列來指導BuilderQ只要更換BuilderQ就可以完成不同材質的迷宮?br>
可以使用下面的UML 別圖來表示上述的概念:(x)
Builder
實際上的E式a計如下Q?br>
  • MazeDirector.java
public class MazeDirector {
private int[][] maze;
private IMazeBuilder mazeBuilder;

public void setMaze(int[][] maze) {
this.maze = maze;
}

public void setMazeBuilder(IMazeBuilder mazeBuilder) {
this.mazeBuilder = mazeBuilder;
}

public void buildMaze() {
for(int i = 0; i < maze.length; i++) {
for(int j = 0; j < maze[i].length; j++) {
// 由於mazeBuilder是IMazeBuilder型態
// 所以無論Builder實例ZQ這邊的程式都無需變動
 switch (maze[i][j]) {
case 0:
mazeBuilder.createRoadBlock();
break;
case 1:
mazeBuilder.createWallBlock();
break;
case 2:
mazeBuilder.createTreasureBlock();
break;
default:
System.out.println("undefined");
}
}
mazeBuilder.nextRow();
}
}
}

  • IMazeBuilder.java
public interface IMazeBuilder {
public void createRoadBlock();
public void createWallBlock();
public void createTreasureBlock();
public void nextRow();
}

  • SoliderMazeBuilder.java
public class SolidMazeBuilder implements IMazeBuilder {
public void createWallBlock() {
System.out.print("?);
}

public void createRoadBlock() {
System.out.print(" ");
}

public void createTreasureBlock() {
System.out.print("$ ");
}

public void nextRow() {
System.out.println();
}
}

  • DiamondMazeBuilder.java
public class DiamondMazeBuilder implements IMazeBuilder {
public void createWallBlock() {
System.out.print("?);
}

public void createRoadBlock() {
System.out.print(" ");
}

public void createTreasureBlock() {
System.out.print("* ");
}

public void nextRow() {
System.out.println();
}
}

使用下面的程式來測試一下,它將產生兩個迷宮圖形:(x)
public class Main {
public static void main(String[] args) {
int[][] maze = {{1, 1, 1, 1, 1, 1, 1},
{1, 0, 0, 0, 0, 2, 1},
{1, 0, 1, 0, 1, 0, 1},
{1, 0, 2, 1, 0, 1, 1},
{1, 1, 0, 1, 0, 1, 1},
{1, 0, 0, 2, 0, 0, 1},
{1, 1, 1, 1, 1, 1, 1}};

MazeDirector mazeDirector = new MazeDirector();
mazeDirector.setMaze(maze);

System.out.println("Build SolidMaze....");
mazeDirector.setMazeBuilder(new SolidMazeBuilder());
mazeDirector.buildMaze();

System.out.println("Build DiamondMaze....");

mazeDirector.setMazeBuilder(
new DiamondMazeBuilder());
mazeDirector.buildMaze();
}
}

Builder

在迷宮例子中並沒有產生或q回產品物gQ這視(zhn)的需求而定Q迷宮例子只是將i果輸出至主控台Q?zhn)也可以設a一個產品物Ӟ或是結果直接出為文g?br>
?a > Gof 中有i出?jin)一個不錯的例子Q以a計文g剖析器為例,該剖析器可以文件轉換為其它的格式,以DOC文g剖析器為例好?jin),假設希望析剖器可以將DOC文g轉換為RTF或是PDF文gQ可以如下設a結構:(x)
Builder

單來說Q徏者模式適用的場合Q在g得?zhn)可以依賴抽象的徏藍圖,而實際徏造時可以使用不同的實例,這是其之所以命為Builder的原?

]]>
Design Pattern: Singleton 模式http://www.aygfsteel.com/jesson2005/articles/111166.html张金?/dc:creator>张金?/author>Tue, 17 Apr 2007 02:33:00 GMThttp://www.aygfsteel.com/jesson2005/articles/111166.htmlhttp://www.aygfsteel.com/jesson2005/comments/111166.htmlhttp://www.aygfsteel.com/jesson2005/articles/111166.html#Feedback0http://www.aygfsteel.com/jesson2005/comments/commentRss/111166.htmlhttp://www.aygfsteel.com/jesson2005/services/trackbacks/111166.html
很多時候,(zhn)會需要Singleton模式Q例如印表機理Q?zhn)希望E式中只能有一個Print SpoolerQ以避免兩個列印動作同時入至印表中Q例如資料n理Q因為徏立連接QConnectionQ物件會耗用資源Q?zhn)希望E式中只能有一個連接物gQ所有其它的E式都透過這個物件來連接資料庫,以避免連接物g的重複開啟造成資源的耗用Q例如系iq式屬性檔的讀取,(zhn)用單一個物件來讀取屬性內容,而程式的其它部䆾都向這個物件要求屬性資料,而不是自行讀取屬性資料?br>
以印表機a計ZQ有的設ah員會採取全域變數的方式來建立實例Q並在程式中隨機取用這個實例,Java雖然不支援全域變數,但透過物件包裝在一個類別之中,也有人會採用這樣的寫法:(x)
 public class PrintSpooler {
    public PrintSpooler() {
        // ....
    }

    public Connection getSpooler(){
       ....
    }
}

 public class GlobalObject {
    private PrintSpooler printSpooler;
    public GlobalObject () {
        printSpooler = new PrintSpooler();
        ...
    }
   
    public void getPrintSpooler() {
        return printSpooler;
    }
 }

無論全域變數或是以上的例子,都無法保證只產生唯一個實例,(zhn)也a會注意不犯這個錯誤,但與(zhn)共同工作的夥伴也許會直覺的使用建構Ҏ(gu)來產生一?PrintSpooler實例?br>
Singleton模式可以保證一個類別只有一個實例,並提供一個訪問(visitQ這個實例的Ҏ(gu)?br>
一個Singleton實作即為Java中的java.lang.Runtime別Q每個JavaE式埯時都有一個唯一的Runtime物gQ可以透過它提供的靜態Ҏ(gu)getRuntime()Ҏ(gu)來取得這個物Ӟ例如Q?
Runtime runtime = Runtime.getRuntime();

取得Runtime物g之後Q?zhn)可以透過它進行一些外部命令的埯、進行垃圾處理{等指o(h)Q?zhn)可以開啟Runtime.java別Q開頭的q行是這樣寫的Q?br>
public class Runtime {
    private static Runtime currentRuntime = new Runtime();

    public static Runtime getRuntime() {
        return currentRuntime;
    }

   /** Don't let anyone else instantiate this class */
   private Runtime() {}

    // 以下?
}
 
上面i構x(chng)用Singleton模式a計Q其i構使用 UML 來表卛_下所C:(x)
Singleton
如上所C的QJava使用 靜態工廠 來取得Runtime物gQ其中Runtime的徏構函式被宣告為privateQ這樣可以L其他Z用徏構方法來建立實例Q用更一般化的表C單例的UMLi構Q如下圖所C:(x)
Singleton

有幾個實作上面結構的Ҏ(gu)Q可以在W一ơ需要實例時再徏立物Ӟ也就是採用所的Lazy InitializationQ?br>
public class Singleton {
    private static Singleton instance = null;

    private Singleton() {
        // ....
    }

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }

        return instance;
    }

    // .. 其它實作
}

上面的實作適用於單執行緒的程式,在多埯R的E式下,以下的寫法在多個執行緒的競爭資源下Q將仍有可能產生兩個以上的實例Q例如下面的情況Q?br>
Thread1: if(instance == null) // true
Thread2: if(instance == null) // true

Thread1: instance = new Singleton(); // 產生一個實?/span>
Thread2: instance = new Singleton(); // 又產生一個實?/span>

Thread1: return instance; // 回傳一個實?/span>
Thread2: return instance; // 又回傳一個實?/span>

在多埯R的環境下,Z(jin)避免資源同時競爭而導致如上產生多個實例的情況Q加上同步(synchronizedQ機Ӟ(x)
public class Singleton {
    private static Singleton instance = null;
    private Singleton(){}
    synchronized static public Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}
 
不過這種單的寫法不適合用於像伺服器這種服務很多埯R的E式上,同步制會造成相當的效能低落,Z(jin)及(qing)Singleton、Lazy Initialization與效能問,因而有?jin)Double-check Locking的模式:(x)
public class Singleton {
    private static Singleton instance = null;
    private Singleton(){}
    public static Singleton getInstance() {
        if (instance == null){
            synchronized(Singleton.class){
                if(instance == null) {
                     instance = new Singleton();
                }
            }
        }
        return instance;
    }
}
 
Java中Runtime別的作法就單多了(jin)Q它捨棄?jin)Lazy InitializationQ如果?zhn)的實例初始化不是很久的話Q可以用這種方式Q?br>
public class Singleton {
    private static Singleton instance = new Singleton();

    private Singleton() {
        // ....
    }

    public static Singleton getInstance() {
        return instance;
    }

    // 其它實作
}
 
Singleton本n的觀늰單但應用很廣Q因而很多時候必須對實際環境作一些考量與調_(d)(zhn)也看看有關於Singleton的這篇 a論?br>

]]>
Design Pattern: Registry of Singleton 模式http://www.aygfsteel.com/jesson2005/articles/111167.html张金?/dc:creator>张金?/author>Tue, 17 Apr 2007 02:33:00 GMThttp://www.aygfsteel.com/jesson2005/articles/111167.htmlhttp://www.aygfsteel.com/jesson2005/comments/111167.htmlhttp://www.aygfsteel.com/jesson2005/articles/111167.html#Feedback0http://www.aygfsteel.com/jesson2005/comments/commentRss/111167.htmlhttp://www.aygfsteel.com/jesson2005/services/trackbacks/111167.htmlSingleton 模式 時擁有子別的問,在Singleton模式中的getInstance()通常是一個靜態方法,不能在子別中重新定它Q關於子別實例的產生交由getInstance()來進行是最好的選擇Q例如:(x)
public class Singleton {
    private static Singleton instance = null;
    private Singleton() {
        // ....
    }

    public static Singleton getInstance() {
        if (instance == null) {
            // getEnv表示pȝ(dng)環境變數
            String style = getEnv("style");

            if (style.equals("child1"))
                instance = new ChildSingleton1();
            else if (style.equals("child2r"))
                instance = new ChildSingleton2();
            else
                instance = new Singleton();
        }

        return _instance;
    }

    // ....
}

上面這個程式片D|寫自 Gof ?/a>中關於Singleton的例子,並用Java實現Q在怸指出Q這個例子的~點是每增加一個子別QgetInstance()必須重C改,這個問在Java中可以用Reflection制來解決:(x)
public class Singleton {
    private static Singleton instance = null;
    private Singleton() {
        // ....
    }

    public static Singleton getInstance() {
        if (instance == null) {
            // getEnv表示環境變數
            String style = getEnv("style");

            try {
                instance = (Singleton)
                          Class.forName(style).newInstance();
            }
            catch(Exception e) {
                System.out.println(
                   "Sorry! No such class defined!");
            }
        }

        return instance;
    }

    // ....
}

上面的方式用了(jin)Java的Reflection制Q並透過環境變數a定要產生的子類SingletonQ如果不使用Reflection的話QGof 怸提出的改進方法是使用Registry of SingletonҎ(gu)Q?br>
import java.util.*;

public class Singleton {
    // ad表,用於ad子類別物?/span>
    private static Map registry = new HashMap();
    private static Singleton instance;

    public static void register(
                 String name, Singleton singleton) {
        registry.put(name, singleton);
    }

    public static Singleton getInstance() {
        if (instance == null) {
            // getEnv表示取得環境變數
            String style = getEnv("style");
            instance = lookup(style);
        }

        return instance;
    }

    protected static Singleton lookup(String name) {
        return (Singleton) registry.get(name);
    }
}

在Gof怸使用List來實現註冊表Q而在這邊使用HasMap別來實現,它是由Java SE所提供的;在父別中提供一個register() 以註冊Singleton的子別所產生之實例,而註冊的時機可以攑֜子類別的建構Ҏ(gu)中加以實現,例如Q?
public class ChildSingleton1 extends Singleton {
    public ChildSingleton1() {
        // ....
        // ad子類別物?/span>
        register(getClass().getName(), this); 
    }
}
 
若要利用SingletonQ則先用這個子別產生物gQ這會向父別ad物gQ之後透過Singleton爉別來取得物gQ?br>
// 必須先啟始這段adE序
// 產生並註冊ChildSingleton1物g
new ChildSingleton1();
// 產生並註冊ChildSingleton2物g
new ChildSingleton2();

// ad完成Q可以用父別來取得子的Singleton
// x(chng)取回何哪一個,視?zhn)的環境變數設|決?/span>
Singleton childSingleton = Singleton.getInstance();
 

這種方式的缺點是(zhn)必須在E式中啟始一D늨序,先向爉別註冊子的SingletonQ之後才能透過爉別來取得指定的子別Singleton實例Q好處是可以適用於沒有Reflection制的語aQ如果?zhn)惌改變Singleton爉傛_的子SingletonQ可以在上面?Singleton別中加入一個reset()Ҏ(gu)Q將instancea定為nullQ然後重新設定環境變數,之後再利?Singleton爉的getInstance()Ҏ(gu)重新取得ad表中的其它子?br>
事實上Registry of Singleton的真正優點正在於此,(zhn)可以用父別來箔(dng)一理多個繼承的子類別之Singleton實例Q?zhn)可以在需要的時候再向父別ad子類 SingletonQ必要時隨時調整傛_的子別Singleton?br>

]]>
Design Pattern: Factory Method 模式http://www.aygfsteel.com/jesson2005/articles/111165.html张金?/dc:creator>张金?/author>Tue, 17 Apr 2007 02:32:00 GMThttp://www.aygfsteel.com/jesson2005/articles/111165.htmlhttp://www.aygfsteel.com/jesson2005/comments/111165.htmlhttp://www.aygfsteel.com/jesson2005/articles/111165.html#Feedback0http://www.aygfsteel.com/jesson2005/comments/commentRss/111165.htmlhttp://www.aygfsteel.com/jesson2005/services/trackbacks/111165.html
(zhn)不能將生產進度停下?jin),相反的(zhn)必須定一些事情,(zhn)知道有關於螢幕控制的所有介面,(zhn)可以將這些介面的操作溝通先實現Q等到螢q到?jin),直接螢q與(zhn)的半成品組合v來,一個完整的成品卛_出廠?br>
Factory Method模式在一個抽象類中留下某個創建元件的抽象Ҏ(gu)沒有實作Q其它與元g操作盔R聯的Ҏ(gu)都先依賴於元件所定義的介面,而不是依賴於元g的實現,當?zhn)的成品中有一個或多個元件無法確定時Q?zhn)先確定與這些元g的操作介面,然後用元件的抽象操作介面先完成其它的工作Q元件的實作Q實現)(j)則推遲至實現元g介面的子完成,一旦元件加入,卛_完成(zhn)的成品?br>
再舉一個例子,假設(zhn)要完成一個文件編輯器Q?zhn)希望這個編輯器可以適用於所有類型的檔案R輯Q例如RTF、DOC、TXT{等Q儘這些文g有著不同的格式,(zhn)先定的是這些文g必然具備的一些操作介面,例如儲存、開啟、關閉等{,(zhn)用一個IDocument型來進行操作Q這麼一來這個框架就無需考慮實際的儲存、開啟等細節是如何進行的?

?UML 別圖來表現以下的概念:(x)
FactoryMethod

AbstractEditor中的createDocument()Ҏ(gu)是個抽象方法,因為框架不知道?zhn)實現一個什麼類型的文gQ這個抽象方法將推遲至繼承AbstractEditor的子中實現?br>
這個架構可用以下簡單的C意E式來作C範Q當中實現了(jin)一個RTFDocumentQ雖然在AbstractEditor中並不知道我們會套用這個RTFDocumentQ但(zhn)可以看刎ͼ透過多型操作Q?zhn)的框架可以進行文件的盔R操作?br>
  • AbstractEditor.java
public abstract class AbstractEditor {
private IDocument document;
public abstract IDocument createDocument();

public void newDocument() {
document = createDocument();
document.open();
}

public void saveDocument() {
if(document != null)
document.save();
}

public void closeDocument() {
if(document != null)
document.close();
}
}

  • IDocument.java
public interface IDocument {
public void open();
public void save();
public void close();
}

  • RTFEditor.java
public class RTFEditor extends AbstractEditor { 
public IDocument createDocument() {
return new RTFDocument();
}
}

  • RTFDocument.java
public class RTFDocument implements IDocument {
public RTFDocument() {
System.out.println("建立RTF文g");
}

public void open() {
System.out.println("開啟文g");
}

public void save() {
System.out.println("儲存文g");
}

public void close() {
System.out.println("關閉文g");
}
}

Factory Method的結構繪出如下:(x)
FactoryMethod

Factory Method中的AbstractOperator中擁有一個抽象的factoryMethod()Ҏ(gu)Q它負K生成一個IProduct型的物Ӟ由於目前還不知道如何實N個類型,所以將之推遲至子類別中實現Q在AbstractOperator中先實現IProduct操作介面溝通的部䆾Q只要介面箔(dng)一?jin),利用多型操作卛_完成各種不同的IProduct型之物件操作?br>
也就是說Q對AbstractOperator來說Q其操作的IProduct是可以抽換的?

]]>
Design Pattern: Abstract Factory 模式http://www.aygfsteel.com/jesson2005/articles/111031.html张金?/dc:creator>张金?/author>Mon, 16 Apr 2007 09:41:00 GMThttp://www.aygfsteel.com/jesson2005/articles/111031.htmlhttp://www.aygfsteel.com/jesson2005/comments/111031.htmlhttp://www.aygfsteel.com/jesson2005/articles/111031.html#Feedback0http://www.aygfsteel.com/jesson2005/comments/commentRss/111031.htmlhttp://www.aygfsteel.com/jesson2005/services/trackbacks/111031.html
  • CustomDialog.java
public class CustomDialog {
private IButton button;
private ITextField textField;

public void setButton(IButton button) {
this.button = button;
}

public void setTextField(ITextField textField) {
this.textField = textField;
}

public void layoutAllComponents() {
// ....
}

public void showDialog() {
this.paintDialog();
button.paintButton();
textField.paintTextField();
}

public void paintDialog() {
System.out.println("custom dialog paints....");
}
}

很簡單,這是最基本的介面依_(d)Setter依賴於IButton與ITextField兩個介面,而不是其實作別Q不過這邊還有個進一步的要求Q用上面的方式還必須親自呼叫Setter、layout{方法,(zhn)希望視感的更換可以更簡單些Q例如只要透一個元件的替換可以完成對話方塊上所有元件的視感更換?br>
(zhn)可以用Abstract Factory模式Q將所有對話方塊所需要的產生的元件加以封裝,話方塊依賴於Abstract FactoryQ實際上具體的Factory實現則分別產生對話方塊所需要的視感元gQ下面的 UML 別圖展N種概念?br>
AbstractFactory

珑֜如果要更換所有的視感元gQ就只要抽象掉具體的Factory可以了(jin)Q例如:(x)
CustomDialog windowsDialog =
      new CustomDialog(new WindowsWidgetFactory());
windowsDialog.showDialog();
               
CustomDialog macDialog =
      new CustomDialog(new MacWidgetFactory());
macDialog.showDialog();

來將上面的UML圖具體實珑և來?br>
  • CustomDialog.java
public class CustomDialog {
private IButton button;
private ITextField textField;

public CustomDialog(IWidgetFactory widgetFactory) {
setWidgetFactory(widgetFactory);
}

// 由於客戶端只依賴於抽象的工廠Q工廠如何實作並無關客戶端的?br> // 要抽換工廠並不需要改動客戶端的程?br> public void setWidgetFactory(IWidgetFactory widgetFactory) {
setButton(widgetFactory.getButton());
setTextField(widgetFactory.getTextField());

}

public void layoutAllComponents() {
// layout all components
}

// 這邊也是依賴抽象Q實際改變了(jin)元g實例
// 客戶端代g不用更改
public void setButton(IButton button) {
this.button = button;
}

public void setTextField(ITextField textField) {
this.textField = textField;
}

public void showDialog() {
this.paintDialog();
button.paintButton();
textField.paintTextField();
}

public void paintDialog() {
System.out.println("custom dialog paints....");
}
}

  • IButton.java
public interface IButton {
public void paintButton();
}

  • ITextField.java
public interface ITextField {
public void paintTextField();
}

  • IWidgetFactory.java
public interface IWidgetFactory {
public IButton getButton();
public ITextField getTextField();
}

  • MacButton.java
public class MacButton implements IButton {
public void paintButton() {
System.out.println("Mac button paints....");
}
}

  • WindowsButton.java
public class WindowsButton implements IButton {
public void paintButton() {
System.out.println("Windows button paints....");
}
}

  • MacTextField.java
public class MacTextField implements ITextField {
public void paintTextField() {
System.out.println("Mac textField paints....");
}
}

  • WindowsTextField.java
public class WindowsTextField implements ITextField {
public void paintTextField() {
System.out.println("Windows textField paints....");
}
}

  • MacWidgetFactory.java
public class MacWidgetFactory implements IWidgetFactory {
public IButton getButton() {
return new MacButton();
}

public ITextField getTextField() {
return new MacTextField();
}
}

  • WindowsWidgetFactory.java
public class WindowsWidgetFactory 
implements IWidgetFactory {
public IButton getButton() {
return new WindowsButton();
}

public ITextField getTextField() {
return new WindowsTextField();
}
}

下圖是Abstract Factory模式的UMLi構圖:(x)
AbstractFactory

單的說Q在Abstract Factory模式中將具體的Product裝在具體Factory實現中,而客戶仍只要面對Factory與Product的抽象介面,避免依賴於具體的Factory與ProductQ由於Factory裝?jin)所必須的ProductQ所以要更換掉所有的元gQ只要簡單的抽換掉Factory可以了(jin)Q不用修改客戶端的程式?br>


]]>
Design Pattern: Simple Factory 模式http://www.aygfsteel.com/jesson2005/articles/111029.html张金?/dc:creator>张金?/author>Mon, 16 Apr 2007 09:39:00 GMThttp://www.aygfsteel.com/jesson2005/articles/111029.htmlhttp://www.aygfsteel.com/jesson2005/comments/111029.htmlhttp://www.aygfsteel.com/jesson2005/articles/111029.html#Feedback0http://www.aygfsteel.com/jesson2005/comments/commentRss/111029.htmlhttp://www.aygfsteel.com/jesson2005/services/trackbacks/111029.html
假設有一個音樂盒工廠Q購買音樂盒的客Z用知道音樂盒是如何製作的Q他只要知道如何播放x(chng)盒就可以?jin),?UML 別圖來表示以上的概念:(x)
SimpleFactory
如上圖所C的QMusicBoxDemo代表?jin)客戶的角色Q它只依賴於IMusicBox介面Q而不關心(j)特定的實作,實際如何產生IMusicBox的實例由MusicBoxFactory完成Q以一個簡單的E式來實現上面這個UML別圖:(x)
  • IMusicBox.java
public interface IMusicBox {
public void play();
}

  • PianoBox.java
public class PianoBox implements IMusicBox {
public void play() {
System.out.println("撥放鋼琴x(chng):)");
}
}

  • ViolinBox.java
public class ViolinBox implements IMusicBox {
public void play() {
System.out.println("撥放提琴音樂^_^");
}
}

  • MusicBoxFactory.java
public class MusicBoxFactory {
public static IMusicBox createMusicBox(String name)
throws InstantiationException,
IllegalAccessException,
ClassNotFoundException {
// 這邊使用的是Java的Reflection制來產生實?br> // 不過客戶端不用管?br> // 以後q改變?jin)這邊的程式,客戶端程式是不用更改?br> return (IMusicBox) Class.forName(name).newInstance();
}
}

  • MusicBoxDemo.java
public class MusicBoxDemo {
public static void main(String[] args) throws Exception {
playMusicBox(MusicBoxFactory.createMusicBox("PianoBox"));
playMusicBox(MusicBoxFactory.createMusicBox("ViolinBox"));
}

public static void playMusicBox(IMusicBox musicBox) {
musicBox.play();
}
}

由於客戶端只依賴於IMusicBox介面Q所以即使?zhn)日後改變了(jin)createMusicBox()中的實作方式Q對客戶端是一點媄(jing)響也沒有的?br>
來看看Simple Factory的類別結構:(x)
SimpleFactory

客戶只要面對FactoryQ客戶依賴於產品介面Q產品的具體實作是可以與客戶隔開的,它們也是可以抽換的?br>


]]>
վ֩ģ壺 | | | | ũ| ʡ| û| | | Ͻ| ̫| ګ| ˮ| | | Ϊ| ϴ| ɽ| | ͨɽ| | Ƹ| | ̽| ζ| | ݸ| ʯ| Ͻ| ɽ| | ʯ| | | ̫| | | Զ| ʩ| | Ƥɽ|