简单工厂模式的一种扩展

来源:互联网 发布:python 获取程序父目录 编辑:程序博客网 时间:2024/05/22 01:49
关于简单工厂模式的简单介绍请看这里:
http://blog.csdn.net/lovelion/article/details/9300337
同时,这篇博客其实也是对上文的再次扩展。

我们知道简单工厂模式的一个巨大的不足就是
系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。
例如经典的工厂代码一般如下:
public class ChartFactory {      //静态工厂方法      public static Chart getChart(String type) {          Chart chart = null;          if (type.equalsIgnoreCase("histogram")) {              chart = new HistogramChart();              System.out.println("初始化设置柱状图!");          }          else if (type.equalsIgnoreCase("pie")) {              chart = new PieChart();              System.out.println("初始化设置饼状图!");          }          else if (type.equalsIgnoreCase("line")) {              chart = new LineChart();              System.out.println("初始化设置折线图!");                      }          return chart;      }  } 
一旦我增加一个新的chart,就得修改getChart这个类里面的逻辑。而且一堆if else看着实在难受。所以,我可以让每个chart自己判断。

看代码
package simplefactory;public  interface Chart {  //总的chart接口    public boolean match(String chart);    public void display();    public void init();}


package simplefactory;public class  HistogramChart implements Chart { //柱状图的类,饼状图与折线图类似 不再赘述    public HistogramChart() {        System.out.println("创建柱状图!");    }        public void display() {        System.out.println("显示柱状图!");    }        public boolean match(String chart) {        if (chart.equals("hisrogram"))            return true;                return false;    }    @Override    public void init() {        System.out.println("初始化设置柱状图!");    }}

在这里也有一个xml,如下
其中chartType是所有的chart类型
need 是我们所需要的chart类型
<?xml version="1.0" encoding="UTF-8"?><config>      <chartType>simplefactory.HistogramChart</chartType>      <chartType>simplefactory.LineChart</chartType>    <chartType>simplefactory.PieChart</chartType>            <need>line</need></config> 
 


分析xml的工具类如下:

package xml;import javax.xml.parsers.*;import org.w3c.dom.*;import java.io.*;public class XMLUtil {    // 该方法用于从XML配置文件中提取图表类型,并返回类型名    // 这个类和上文提到的博客里面的差别在于 方法的参数    public static String[] getChartType(String choice) {        try {            // 创建文档对象            DocumentBuilderFactory dFactory = DocumentBuilderFactory                    .newInstance();            DocumentBuilder builder = dFactory.newDocumentBuilder();            Document doc;            doc = builder.parse(new File("src/xml/xmlutil.xml"));            // 获取包含图表类型的文本节点            NodeList nl = doc.getElementsByTagName(choice);            String[] names = new String[nl.getLength()];            for (int i = 0; i < nl.getLength(); i++) {                names[i] = nl.item(i).getFirstChild().getNodeValue().trim();            }            return names;        } catch (Exception e) {            e.printStackTrace();            return null;        }    }}



最后,我们看看重构后的工厂

package simplefactory;import java.util.ArrayList;import org.apache.catalina.tribes.membership.StaticMember;import xml.XMLUtil;public class ChartFactory {        //产品候选列表    static ArrayList<Chart> charts=new ArrayList<Chart>();    //需要的产品    static String[] choise=new String[1];        public static Chart getChart(){        charts=ChartFactory.getAllChart();        choise=XMLUtil.getChartType("need");        for (int i = 0; i < charts.size(); i++)            if (charts.get(i).match(choise[0]))                return charts.get(i);        return null;            }        public static ArrayList<Chart> getAllChart() {        //获得所有chart的路径        String[] name = XMLUtil.getChartType("chartType");        ArrayList<Chart> chart = new ArrayList<Chart>();        try {            //将chart全部new出来            for (int i = 0; i < name.length; i++)                chart.add((Chart) Class.forName(name[i]).newInstance());        } catch (InstantiationException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (IllegalAccessException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (ClassNotFoundException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        return chart;    }}


测试如下
package simplefactory;public class ChartTest {    public static void main(String[] args) {        Chart chart=ChartFactory.getChart();        System.out.println("------");        chart.init();        chart.display();    }}
结果如下:
创建柱状图!
创建折线图!
创建饼状图!
------
初始化设置折线图!
显示折线图!

如果想要饼状图,只需要把xml改成

<need>pie</need>



总结一下:
我现在已经不能说这次重构的结果仍然是工厂模式了。工厂模式是生产一个匹配于所给参数的产品。而我这个等于是把工厂支持的产品先都生产出来,再一个一个问:人家需要的是这个产品,你看你行不?

好处就在于,以后即使要扩展新的产品,只用改xml就好。不用对工厂做改变。

而且我们告别了一大堆if else。


感谢glt

0 0
原创粉丝点击