閱讀359 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Design Pattern: Abstract Factory 模式

  學習是分享和合作式的!

轉載請注明出處:https://blog.csdn.net/wdzxl198/article/details/9219421; 

文章摘自: https://www.riabook.cn/doc/designpattern/;  

假設您要製作一個對話方塊(Dialog)元件,您希望的是這個對話方塊可以有不同的視感(Look-and- feel),最基本的想法是,藉由Setter將不同視感的元件設定給這個對話方塊,例如:
  • CustomDialog.java
   1: public class CustomDialog {
   2:     private IButton button;
   3:     private ITextField textField;
   4:     
   5:     public void setButton(IButton button) {
   6:         this.button = button;    
   7:     }
   8:     
   9:     public void setTextField(ITextField textField) {
  10:         this.textField = textField;
  11:     }
  12:  
  13:     public void layoutAllComponents() {
  14:         // ....
  15:     }
  16:     
  17:     public void showDialog() {
  18:         this.paintDialog();
  19:         button.paintButton();
  20:         textField.paintTextField();
  21:     }
  22:   
  23:     public void paintDialog() {
  24:         System.out.println("custom dialog paints....");
  25:     }
  26: }
很簡單,這是最基本的介麵依賴,Setter依賴於IButton與ITextField兩個介麵,而不是其實作類別,不過這邊還有個進一步的要求,使用 上麵的方式還必須親自唿叫Setter、layout等方法,您希望視感的更換可以更簡單些,例如隻要透一個元件的替換就可以完成對話方塊上所有元件的視 感更換。
您可以使用Abstract Factory模式,將所有對話方塊所需要的產生的元件加以封裝,對話方塊依賴於Abstract Factory,實際上具體的Factory實現則分別產生對話方塊所需要的視感元件,下麵的 UML 類別圖展現這種概念。

AbstractFactory

現在如果要更換所有的視感元件,就隻要抽象掉具體的Factory就可以了,例如:

   1: CustomDialog windowsDialog =
   2:  new CustomDialog(new WindowsWidgetFactory());
   3: windowsDialog.showDialog();
   4: CustomDialog macDialog =
   5:  new CustomDialog(new MacWidgetFactory());
   6: macDialog.showDialog();

來將上麵的UML圖具體實現出來。

  • CustomDialog.java
   1: public class CustomDialog {
   2:     private IButton button;
   3:     private ITextField textField;
   4:     
   5:     public CustomDialog(IWidgetFactory widgetFactory) {
   6:         setWidgetFactory(widgetFactory);
   7:     }
   8:     
   9:     // 由於客戶端隻依賴於抽象的工廠,工廠如何實作並無關客戶端的事
  10:     // 要抽換工廠並不需要改動客戶端的程式
  11:     public void setWidgetFactory(IWidgetFactory widgetFactory) {
  12:         setButton(widgetFactory.getButton());
  13:         setTextField(widgetFactory.getTextField());
  14:      
  15:     }
  16:  
  17:     public void layoutAllComponents() {
  18:         // layout all components
  19:     }
  20:     
  21:     // 這邊也是依賴抽象,實際改變了元件實例
  22:     // 客戶端代碼也不用更改
  23:     public void setButton(IButton button) {
  24:         this.button = button;    
  25:     }
  26:     
  27:     public void setTextField(ITextField textField) {
  28:         this.textField = textField;
  29:     }
  30:     
  31:     public void showDialog() {
  32:         this.paintDialog();
  33:         button.paintButton();
  34:         textField.paintTextField();
  35:     }
  36:   
  37:     public void paintDialog() {
  38:         System.out.println("custom dialog paints....");
  39:     }
  40: } 
  • IButton.java
   1: public interface IButton {
   2:     public void paintButton();
   3: } 
  • ITextField.java
   1: public interface ITextField {
   2:     public void paintTextField();
   3: } 
  • IWidgetFactory.java
   1: public interface IWidgetFactory {
   2:     public IButton getButton();
   3:     public ITextField getTextField();
   4: } 
  • MacButton.java
   1: public class MacButton implements IButton {
   2:     public void paintButton() {
   3:         System.out.println("Mac button paints....");
   4:     }
   5: } 
  • WindowsButton.java
   1: public class WindowsButton implements IButton {
   2:     public void paintButton() {
   3:         System.out.println("Windows button paints....");
   4:     }
   5: } 
  • MacTextField.java
   1: public class MacTextField implements ITextField {
   2:     public void paintTextField() {
   3:         System.out.println("Mac textField paints....");
   4:     }
   5: } 
  • WindowsTextField.java
   1: public class WindowsTextField implements ITextField {
   2:     public void paintTextField() {
   3:         System.out.println("Windows textField paints....");
   4:     }
   5: } 
  • MacWidgetFactory.java
   1: public class MacWidgetFactory implements IWidgetFactory {
   2:     public IButton getButton() {
   3:         return new MacButton();
   4:     }
   5:     
   6:     public ITextField getTextField() {
   7:         return new MacTextField();
   8:     }
   9: } 
  • WindowsWidgetFactory.java
   1: public class WindowsWidgetFactory 
   2:                           implements IWidgetFactory {
   3:     public IButton getButton() {
   4:         return new WindowsButton();
   5:     }
   6:     
   7:     public ITextField getTextField() {
   8:         return new WindowsTextField();
   9:     }
  10: }
下圖是Abstract Factory模式的UML結構圖:

AbstractFactory

簡單的說,在Abstract Factory模式中將具體的Product封裝在具體Factory實現中,而客戶仍隻要麵對Factory與Product的抽象介麵,避免依賴於具 體的Factory與Product,由於Factory封裝了所必須的Product,所以要更換掉所有的元件,隻要簡單的抽換掉Factory就可以 了,不用修改客戶端的程式。

Edit bt Atlas

Time 2013/7/1 09:49

最後更新:2017-04-03 16:59:48

  上一篇:go HDU 4342 水數學
  下一篇:go JSTL標簽 參考手冊