程式扎記: [OO 設計模式] Gossip@DesignPattern : Creational - Abstract Factory 模式

標籤

2014年4月4日 星期五

[OO 設計模式] Gossip@DesignPattern : Creational - Abstract Factory 模式

來源自 這裡 
Preface: 
如果您需要一組可以隨時抽換的元件,並且希望可以簡單地 一次抽換,則可以考慮使用Abstract Factory。例如視窗程式中視感(Look-and- feel)元件的調換,就是應用的場合. 

Abstract Factory Usage: 
以下是 Abstract Factory 的簡單實現,程式中 Rectangle 依賴於 PointCornerFactory 的公開定義,使用 PointCornerFactory 所提供的一組元件來繪製矩形: 
  1. interface PointCornerFactory {  
  2.     Point getPoint();  
  3.     Corner getCorner();  
  4. }  
  5.   
  6. interface Point {  
  7.     void line(int width);  
  8. }  
  9.   
  10. interface Corner {  
  11.     void leftUp();  
  12.     void rightUp();  
  13.     void leftDown();  
  14.     void rightDown();  
  15. }  
  16.   
  17. class Rectangle {  
  18.     private int width;  
  19.     private int height;  
  20.       
  21.     Rectangle(int width, int height) {  
  22.         this.width = width;  
  23.         this.height = height;  
  24.     }  
  25.       
  26.     void paint(PointCornerFactory factory) {  
  27.         Point point = factory.getPoint();  
  28.         Corner corner = factory.getCorner();  
  29.         corner.leftUp();  
  30.         point.line(width - 2);  
  31.         corner.rightUp();  
  32.         System.out.println();  
  33.         for(int i = 0; i < height - 2; i++) {  
  34.             point.line(width);  
  35.             System.out.println();  
  36.         }  
  37.         corner.leftDown();  
  38.         point.line(width - 2);  
  39.         corner.rightDown();  
  40.         System.out.println();  
  41.     }  
  42. }  
依您所提供的 PointCornerFactoryPoint 與 Corner 實作之不同,可以繪製出不同外觀的矩形,例如: 
  1. public class Main {  
  2.     public static void main(String[] args) {  
  3.         Rectangle rect = new Rectangle(2010);  
  4.         PointCornerFactory factory =  
  5.             new PointCornerFactory() {  
  6.                 public Point getPoint() {  
  7.                     return new Point() {  
  8.                         public void line(int width) {  
  9.                             for(int i = 0; i < width; i++) {  
  10.                                 System.out.print("-");  
  11.                             }  
  12.                         }  
  13.                     };  
  14.                 }  
  15.                   
  16.                 public Corner getCorner() {  
  17.                     return new Corner() {  
  18.                         public void leftUp() { System.out.print('+'); }  
  19.                         public void rightUp() { System.out.print('+'); }  
  20.                         public void leftDown() { System.out.print('+'); }  
  21.                         public void rightDown() { System.out.print('+'); }  
  22.                     };  
  23.                 }  
  24.             };  
  25.         rect.paint(factory);          
  26.     }  
  27. }  
如果您要呈現不同的矩形外觀,則可以提供另一組 PointCornerFactoryPoint 與 Corner 實作,對 Rectangle 而言,就可達成一次抽象所有元件的需求! 

UML class diagram: 
下圖為 AbstractFactory 的類別圖: 
 

圖中 AbstractFactory、Part 指的是,物件必須具有 AbstractFactory、Part 所定義之公 開協定,而非專指 Java 中的 interface 定義。對於靜態語言來說,例如 Java,必須使用型態來宣告變數,因此根 據需求,可以使用 interfact 或 abstract class 來定義 AbstractFactory、Part 所定 義之公開協定。對於動態語言來說,例如 Python,真正的型態資訊是在物件之上(而非變數),因此要求的是物件必須具有 AbstractFactory、 Part 之公開方法(無論是「哪一種」物件). 

AbstractFactory 這個名詞是從的建立可抽換的一組 物件角度來看這個模式,如果將焦點放 在使用抽象工廠物件的方法上,因為方法定義了一個樣版流程,流程中真正需要實際物件運作的部份,則呼叫 callback 物件(工廠物件)來建立,所以從流 程的觀點來看,又稱之為 Template-callback 模式。例 如在範例的 paint() 方法中定義了繪製的流程,真正繪製的物件則是透過 callback 物件(工廠物件)來建立.

沒有留言:

張貼留言

網誌存檔

關於我自己

我的相片
Where there is a will, there is a way!