`
guafei
  • 浏览: 323237 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

抽象工厂模式

阅读更多
假如你要制作一个对话框控件,你希望这个对话框可以有不同的Look&Feel,最基本的想法是,使用setter将不同的Look&Feel注入到这个对话框,例如:

CustomDialog.java
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类图将展示这种概念。


现在如果要更换所有的控件,只需要注入具体的Factory就可以了,例如:
Java代码
1. CustomDialog windowsDialog = 
2.       new CustomDialog(new WindowsWidgetFactory()); 
3. windowsDialog.showDialog(); 
4.                 
5. CustomDialog macDialog = 
6.       new CustomDialog(new MacWidgetFactory()); 
7. macDialog.showDialog(); 


将上面的UML图实现出来:
CustomDialog.java
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.createButton()); 
13.         setTextField(widgetFactory.createTextField()); 
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
Java代码
1. public interface IButton { 
2.     public void paintButton(); 
3. }  


ITextField.java
Java代码
1. public interface ITextField { 
2.     public void paintTextField(); 
3. }  


IWidgetFactory.java
Java代码
1. public interface IWidgetFactory { 
2.     public IButton createButton(); 
3.     public ITextField createTextField(); 
4. }  


MacButton.java
Java代码
1. public class MacButton implements IButton { 
2.     public void paintButton() { 
3.         System.out.println("Mac button paints...."); 
4.     } 
5. }  


WindowsButton.java
Java代码
1. public class WindowsButton implements IButton { 
2.     public void paintButton() { 
3.         System.out.println("Windows button paints...."); 
4.     } 
5. }  


MacTextField.java
Java代码
1. public class MacTextField implements ITextField { 
2.     public void paintTextField() { 
3.         System.out.println("Mac textField paints...."); 
4.     } 
5. }  


WindowsTextField.java
Java代码
1. public class WindowsTextField implements ITextField { 
2.     public void paintTextField() { 
3.         System.out.println("Windows textField paints...."); 
4.     } 
5. }  


MacWidgetFactory.java
Java代码
1. public class MacWidgetFactory implements IWidgetFactory { 
2.     public IButton createButton() { 
3.         return new MacButton(); 
4.     } 
5.      
6.     public ITextField createTextField() { 
7.         return new MacTextField(); 
8.     } 
9. }  


WindowsWidgetFactory.java
Java代码
1. public class WindowsWidgetFactory  
2.                           implements IWidgetFactory { 
3.     public IButton createButton() { 
4.         return new WindowsButton(); 
5.     } 
6.      
7.     public ITextField createTextField() { 
8.         return new WindowsTextField(); 
9.     } 
10. } 


下图是Abstract Factory模式的UML结构图:

简单的说,在Abstract Factory模式中将具体的Product封装在Factory实现中,而库户仍只要面对Factory与Product的抽象界面,避免依赖于具体的 Factory与Product,由于Factory封装了所有必须的Product,所以要更换所有的控件,只需要简单地替换掉Factory的具体实 现就可以了,不需要修改客户端的程序。


事例2:
The intent of Abstract Factory is to provide for the creation of a family of related, or dependent, objects. see pic:

Additional note is below:( reference from http://www.dofactory.com) :
• AbstractFactory  (ContinentFactory)
o declares an interface for operations that create abstract products
• ConcreteFactory   (AfricaFactory, AmericaFactory)
o implements the operations to create concrete product objects
• AbstractProduct   (Herbivore, Carnivore)
o declares an interface for a type of product object
• Product  (Wildebeest, Lion, Bison, Wolf)
o defines a product object to be created by the corresponding concrete factory
o implements the AbstractProduct interface
• Client  (AnimalWorld)
o uses interfaces declared by AbstractFactory and AbstractProduct classes
using the term: 产品族(Product Family),the former pic is like:
 

In this pattern, speaking loosely, a package is usually a "family" of classes, and an abstract factory produces a "family" of objects.



•  /* GUIFactory example -- 
•  The output should be either "I'm a WinButton" or "I'm an OSXButton" 
•  depending on which kind of factory was used. Note that the Application 
•  has no idea what kind of GUIFactory it is given or even what kind of 
•  Button that factory creates.*/ 
•    
•  interface GUIFactory { 
•      public Button createButton(); 
•  } 
•    
•    
•  class WinFactory implements GUIFactory { 
•      public Button createButton() { 
•          return new WinButton(); 
•      } 
•  } 
•    
•    
•  class OSXFactory implements GUIFactory { 
•      public Button createButton() { 
•          return new OSXButton(); 
•      } 
•  } 
•    
•    
•    
•  interface Button { 
•      public void paint(); 
•  } 
•    
•    
•  class WinButton implements Button { 
•      public void paint() { 
•          System.out.println("I'm a WinButton"); 
•      } 
•  } 
•    
•    
•  class OSXButton implements Button { 
•      public void paint() { 
•          System.out.println("I'm an OSXButton"); 
•      } 
•  } 
•    
•    
•  class Application { 
•      public Application(GUIFactory factory){ 
•          Button button = factory.createButton(); 
•          button.paint(); 
•      } 
•  } 
•    
•  public class ApplicationRunner { 
•      public static void main(String[] args) { 
•          new Application(createOsSpecificFactory()); 
•      } 
•    
•      public static GUIFactory createOsSpecificFactory() { 
•          int sys = readFromConfigFile("OS_TYPE"); 
•          if (sys == 0) { 
•              return new WinFactory(); 
•          } else { 
•              return new OSXFactory(); 
•          } 
•      } 
•  }
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics