【设计模式】简单工厂模式

2016-06-29  本文已影响80人  666真666
介绍

工厂模式是最常用的一类创建型设计模式,通常我们所说的工厂模式是指工厂方法模式,它也是使用频率最高的工厂模式。本文描述的简单工厂模式是工厂方法模式的“小弟”,它不属于GoF 23种设计模式,但在软件开发中应用也较为频繁,通常将它作为学习其他工厂模式的入门。此外,工厂方法模式还有一位“大哥”——抽象工厂模式。这三种工厂模式各具特色,难度也逐个加大,在软件开发中它们都得到了广泛的应用,成为面向对象软件中常用的创建对象的工具。

定义

定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。因为在简单工厂模式中用于创建实例的方法是静态(static)方法,因此简单工厂模式又被称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。

如何使用

首先将需要创建的各种不同类似对象的相关代码封装到不同的类中,这些类称为具体产品类,而将它们公共的代码进行抽象和提取后封装在一个抽象产品类中,每一个具体产品类都是抽象产品类的子类;然后提供一个工厂类用于创建各种产品,在工厂类中提供一个创建产品的工厂方法,该方法可以根据所传入的参数不同创建不同的具体产品对象;客户端只需调用工厂类的工厂方法并传入相应的参数即可得到一个产品对象。

UML类图
Alt 简单工厂模式结构图
角色介绍
方案优化

问题:每当新增加一种类型的产品,都需要修改静态工厂方法的参数,违法了“开闭原则”。我们可以将静态工厂方法的参数存储在配置文件中,使用一个工具类来读取配置文件中的字符串参数,如果需要更换具体图标对象,只需要修改配置文件,无需修改任何源代码,符合“开闭原则”。

简单工厂模式的简化

有时候,为了简化简单工厂模式,我们可以将抽象产品类和工厂类合并,将静态工厂方法移至抽象产品类中。



客户端可以通过产品父类的静态工厂方法,根据参数的不同创建不同类型的产品子类对象。

demo代码
//抽象图表接口:抽象产品类  
interface Chart {  
    public void display();  
}  
  
//柱状图类:具体产品类  
class HistogramChart implements Chart {  
    public HistogramChart() {  
        System.out.println("创建柱状图!");  
    }  
      
    public void display() {  
        System.out.println("显示柱状图!");  
    }  
}  
  
//饼状图类:具体产品类  
class PieChart implements Chart {  
    public PieChart() {  
        System.out.println("创建饼状图!");  
    }  
      
    public void display() {  
        System.out.println("显示饼状图!");  
    }  
}  
  
//折线图类:具体产品类  
class LineChart implements Chart {  
    public LineChart() {  
        System.out.println("创建折线图!");  
    }  
      
    public void display() {  
        System.out.println("显示折线图!");  
    }  
}  
  
//图表工厂类:工厂类  
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;  
    }  
}  

编写客户端测试代码

class Client {  
    public static void main(String args[]) {  
        Chart chart;  
        chart = ChartFactory.getChart("histogram"); //通过静态工厂方法创建产品  
        chart.display();  
    }  
}  

用配置文件优化方案改进
如下config.xml所示:

<?xml version="1.0"?>  
<config>  
    <chartType>histogram</chartType>  
</config>  

再通过一个工具类XMLUtil来读取配置文件中的字符串参数,XMLUtil类的代码如下所示:

public class XMLUtil {  
    //该方法用于从XML配置文件中提取图表类型,并返回类型名  
    public static String getChartType() {  
        try {  
            //创建文档对象  
            DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();  
            DocumentBuilder builder = dFactory.newDocumentBuilder();  
            Document doc;                             
            doc = builder.parse(new File("config.xml"));   
          
            //获取包含图表类型的文本节点  
            NodeList nl = doc.getElementsByTagName("chartType");  
            Node classNode = nl.item(0).getFirstChild();  
            String chartType = classNode.getNodeValue().trim();  
            return chartType;  
        }     
        catch(Exception e) {  
            e.printStackTrace();  
            return null;  
        }  
    }  
}  

在引入了配置文件和工具类XMLUtil之后,客户端代码修改如下:

class Client {  
    public static void main(String args[]) {  
        Chart chart;  
        String type = XMLUtil.getChartType(); //读取配置文件中的参数  
        chart = ChartFactory.getChart(type); //创建产品对象  
        chart.display();  
    }  
}
总结
优点
缺点
适用场景
上一篇下一篇

猜你喜欢

热点阅读