抽象工厂模式(四):界面皮肤库的抽象工厂模式解决方案

来源:互联网 发布:知乎提问后自己找不到 编辑:程序博客网 时间:2024/04/30 03:58

4 完整解决方案

       Sunny公司开发人员使用抽象工厂模式来重构界面皮肤库的设计,其基本结构如图6所示:

界面皮肤库结构图

       在图6中,SkinFactory接口充当抽象工厂,其子类SpringSkinFactorySummerSkinFactory充当具体工厂,接口ButtonTextFieldComboBox充当抽象产品,其子类SpringButtonSpringTextFieldSpringComboBoxSummerButtonSummerTextFieldSummerComboBox充当具体产品。完整代码如下所示:

[java] view plaincopy
  1. //在本实例中我们对代码进行了大量简化,实际使用时,界面组件的初始化代码较为复杂,还需要使用JDK中一些已有类,为了突出核心代码,在此只提供框架代码和演示输出。  
  2. //按钮接口:抽象产品  
  3. interface Button {  
  4.     public void display();  
  5. }  
  6.   
  7. //Spring按钮类:具体产品  
  8. class SpringButton implements Button {  
  9.     public void display() {  
  10.         System.out.println("显示浅绿色按钮。");  
  11.     }  
  12. }  
  13.   
  14. //Summer按钮类:具体产品  
  15. class SummerButton implements Button {  
  16.     public void display() {  
  17.         System.out.println("显示浅蓝色按钮。");  
  18.     }     
  19. }  
  20.   
  21. //文本框接口:抽象产品  
  22. interface TextField {  
  23.     public void display();  
  24. }  
  25.   
  26. //Spring文本框类:具体产品  
  27. class SpringTextField implements TextField {  
  28.     public void display() {  
  29.         System.out.println("显示绿色边框文本框。");  
  30.     }  
  31. }  
  32.   
  33. //Summer文本框类:具体产品  
  34. class SummerTextField implements TextField {  
  35.     public void display() {  
  36.         System.out.println("显示蓝色边框文本框。");  
  37.     }     
  38. }  
  39.   
  40. //组合框接口:抽象产品  
  41. interface ComboBox {  
  42.     public void display();  
  43. }  
  44.   
  45. //Spring组合框类:具体产品  
  46. class SpringComboBox implements ComboBox {  
  47.     public void display() {  
  48.         System.out.println("显示绿色边框组合框。");  
  49.     }  
  50. }  
  51.   
  52. //Summer组合框类:具体产品  
  53. class SummerComboBox implements ComboBox {  
  54.     public void display() {  
  55.         System.out.println("显示蓝色边框组合框。");  
  56.     }     
  57. }  
  58.   
  59. /** 界面皮肤工厂接口:抽象工厂 */
  60. interface SkinFactory {  
  61.     public Button createButton();  
  62.     public TextField createTextField();  
  63.     public ComboBox createComboBox();  
  64. }  
  65.   
  66. //Spring皮肤工厂:具体工厂  
  67. class SpringSkinFactory implements SkinFactory {  
  68.     public Button createButton() {  
  69.         return new SpringButton();  
  70.     }  
  71.   
  72.     public TextField createTextField() {  
  73.         return new SpringTextField();  
  74.     }  
  75.   
  76.     public ComboBox createComboBox() {  
  77.         return new SpringComboBox();  
  78.     }  
  79. }  
  80.   
  81. //Summer皮肤工厂:具体工厂  
  82. class SummerSkinFactory implements SkinFactory {  
  83.     public Button createButton() {  
  84.         return new SummerButton();  
  85.     }  
  86.   
  87.     public TextField createTextField() {  
  88.         return new SummerTextField();  
  89.     }  
  90.   
  91.     public ComboBox createComboBox() {  
  92.         return new SummerComboBox();  
  93.     }  
  94. }  

       为了让系统具备良好的灵活性和可扩展性,我们引入了工具类XMLUtil和配置文件,其中,XMLUtil类的代码如下所示:

[java] view plaincopy
  1. import javax.xml.parsers.*;  
  2. import org.w3c.dom.*;  
  3. import org.xml.sax.SAXException;  
  4. import java.io.*;  
  5.   
  6. public class XMLUtil {  
  7. //该方法用于从XML配置文件中提取具体类类名,并返回一个实例对象  
  8.     public static Object getBean() {  
  9.         try {  
  10.             //创建文档对象  
  11.             DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();  
  12.             DocumentBuilder builder = dFactory.newDocumentBuilder();  
  13.             Document doc;                             
  14.             doc = builder.parse(new File("config.xml"));   
  15.           
  16.             //获取包含类名的文本节点  
  17.             NodeList nl = doc.getElementsByTagName("className");  
  18.             Node classNode=nl.item(0).getFirstChild();  
  19.             String cName=classNode.getNodeValue();  
  20.               
  21.             //通过类名生成实例对象并将其返回  
  22.             Class c=Class.forName(cName);  
  23.             Object obj=c.newInstance();  
  24.             return obj;  
  25.         }     
  26.         catch(Exception e) {  
  27.             e.printStackTrace();  
  28.             return null;  
  29.         }  
  30.     }  
  31. }  

       配置文件config.xml中存储了具体工厂类的类名,代码如下所示:

[java] view plaincopy
  1. <?xml version="1.0"?>  
  2. <config>  
  3.     <className>SpringSkinFactory</className>  
  4. </config>  

       编写如下客户端测试代码:

[java] view plaincopy
  1. class Client {  
  2.     public static void main(String args[]) {  
  3.         //使用抽象层定义  
  4.         SkinFactory factory;  
  5.         Button bt;  
  6.         TextField tf;  
  7.         ComboBox cb;  
  8.         factory = (SkinFactory)XMLUtil.getBean();  
  9.         bt = factory.createButton();  
  10.         tf = factory.createTextField();  
  11.         cb = factory.createComboBox();  
  12.         bt.display();  
  13.         tf.display();  
  14.         cb.display();  
  15.     }  
  16. }  

       编译并运行程序,输出结果如下:

显示浅绿色按钮。

显示绿色边框文本框。

显示绿色边框组合框。

       如果需要更换皮肤,只需修改配置文件即可,在实际环境中,我们可以提供可视化界面,例如菜单或者窗口来修改配置文件,用户无须直接修改配置文件。如果需要增加新的皮肤(不能增加新的产品等级结构),只需增加一族新的具体组件并对应提供一个新的具体工厂,修改配置文件即可使用新的皮肤,原有代码无须修改,符合“开闭原则”。

  疑问    

扩展

       在真实项目开发中,我们通常会为配置文件提供一个可视化的编辑界面,类似Struts框架中的struts.xml编辑器,大家可以自行开发一个简单的图形化工具来修改配置文件,实现真正的纯界面操作。


【作者:刘伟  http://blog.csdn.net/lovelion

0 0
原创粉丝点击