工厂三兄弟之简单工厂模式

来源:互联网 发布:淘宝商品被下架找不到 编辑:程序博客网 时间:2024/04/29 12:15

简单工厂模式概述


简单工厂模式并不属于GoF 23个经典设计模式,但通常将它作为学习其他工厂模式的基础,它的设计思想很简单,其基本流程如下:


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


简单工厂模式定义如下:

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


简单工厂模式的要点在于:当你需要什么,只需要传入一个正确的参数,就可以获取你所需要的对象,而无须知道其创建细节。简单工厂模式结构比较简单,其核心是工厂类的设计,其结构如图1所示:

1  简单工厂模式结构图

在简单工厂模式结构图中包含如下几个角色:

       ● Factory(工厂角色):工厂角色即工厂类,它是简单工厂模式的核心,负责实现创建所有产品实例的内部逻辑;工厂类可以被外界直接调用,创建所需的产品对象;在工厂类中提供了静态的工厂方法factoryMethod(),它的返回类型为抽象产品类型Product

       ● Product(抽象产品角色):它是工厂类所创建的所有对象的父类,封装了各种产品对象的公有方法,它的引入将提高系统的灵活性,使得在工厂类中只需定义一个通用的工厂方法,因为所有创建的具体产品对象都是其子类对象。

       ● ConcreteProduct(具体产品角色):它是简单工厂模式的创建目标,所有被创建的对象都充当这个角色的某个具体类的实例。每一个具体产品角色都继承了抽象产品角色,需要实现在抽象产品中声明的抽象方法。


在简单工厂模式中,客户端通过工厂类来创建一个产品类的实例,而无须直接使用new关键字来创建对象,它是工厂模式家族中最简单的一员。


在使用简单工厂模式时,首先需要对产品类进行重构,不能设计一个包罗万象的产品类,而需根据实际情况设计一个产品层次结构,将所有产品类公共的代码移至抽象产品类,并在抽象产品类中声明一些抽象方法,以供不同的具体产品类来实现,典型的抽象产品类代码如下所示:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. abstract class Product {  
  2.     //所有产品类的公共业务方法  
  3.     public void methodSame() {  
  4.         //公共方法的实现  
  5.     }  
  6.   
  7.     //声明抽象业务方法  
  8.     public abstract void methodDiff();  
  9. }  


在具体产品类中实现了抽象产品类中声明的抽象业务方法,不同的具体产品类可以提供不同的实现,典型的具体产品类代码如下所示:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. class ConcreteProduct extends Product {  
  2.     //实现业务方法  
  3.     public void methodDiff() {  
  4.         //业务方法的实现  
  5.     }  
  6. }  


简单工厂模式的核心是工厂类,在没有工厂类之前,客户端一般会使用new关键字来直接创建产品对象,而在引入工厂类之后,客户端可以通过工厂类来创建产品,在简单工厂模式中,工厂类提供了一个静态工厂方法供客户端使用,根据所传入的参数不同可以创建不同的产品对象,典型的工厂类代码如下所示:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. class Factory {  
  2.     //静态工厂方法  
  3.     public static Product getProduct(String arg) {  
  4.         Product product = null;  
  5.         if (arg.equalsIgnoreCase("A")) {  
  6.             product = new ConcreteProductA();  
  7.             //初始化设置product  
  8.         }  
  9.         else if (arg.equalsIgnoreCase("B")) {  
  10.             product = new ConcreteProductB();  
  11.             //初始化设置product  
  12.         }  
  13.         return product;  
  14.     }  
  15. }  


在客户端代码中,我们通过调用工厂类的工厂方法即可得到产品对象,典型代码如下所示:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. class Client {  
  2.     public static void main(String args[]) {  
  3.         Product product;   
  4.         product = Factory.getProduct("A"); //通过工厂类创建产品对象  
  5.         product.methodSame();  
  6.         product.methodDiff();  
  7.     }  
  8. }  

例子:
Sunny软件公司欲基于Java语言开发一套图表库,该图表库可以为应用系统提供各种不同外观的图表,例如柱状图、饼状图、折线图等。Sunny软件公司图表库设计人员希望为应用系统开发人员提供一套灵活易用的图表库,而且可以较为方便地对图表库进行扩展,以便能够在将来增加一些新类型的图表。

解决方案:

为了将Chart类的职责分离,同时将Chart对象的创建和使用分离,Sunny软件公司开发人员决定使用简单工厂模式对图表库进行重构,重构后的结构如图2所示:

图表库结构图


在图2中,Chart接口充当抽象产品类,其子类HistogramChartPieChartLineChart充当具体产品类,ChartFactory充当工厂类。完整代码如下所示:

[java] view plaincopy
  1. //抽象图表接口:抽象产品类  
  2. interface Chart {  
  3.     public void display();  
  4. }  
  5.   
  6. //柱状图类:具体产品类  
  7. class HistogramChart implements Chart {  
  8.     public HistogramChart() {  
  9.         System.out.println("创建柱状图!");  
  10.     }  
  11.       
  12.     public void display() {  
  13.         System.out.println("显示柱状图!");  
  14.     }  
  15. }  
  16.   
  17. //饼状图类:具体产品类  
  18. class PieChart implements Chart {  
  19.     public PieChart() {  
  20.         System.out.println("创建饼状图!");  
  21.     }  
  22.       
  23.     public void display() {  
  24.         System.out.println("显示饼状图!");  
  25.     }  
  26. }  
  27.   
  28. //折线图类:具体产品类  
  29. class LineChart implements Chart {  
  30.     public LineChart() {  
  31.         System.out.println("创建折线图!");  
  32.     }  
  33.       
  34.     public void display() {  
  35.         System.out.println("显示折线图!");  
  36.     }  
  37. }  
  38.   
  39. //图表工厂类:工厂类  
  40. class ChartFactory {  
  41.     //静态工厂方法  
  42.     public static Chart getChart(String type) {  
  43.         Chart chart = null;  
  44.         if (type.equalsIgnoreCase("histogram")) {  
  45.             chart = new HistogramChart();  
  46.             System.out.println("初始化设置柱状图!");  
  47.         }  
  48.         else if (type.equalsIgnoreCase("pie")) {  
  49.             chart = new PieChart();  
  50.             System.out.println("初始化设置饼状图!");  
  51.         }  
  52.         else if (type.equalsIgnoreCase("line")) {  
  53.             chart = new LineChart();  
  54.             System.out.println("初始化设置折线图!");              
  55.         }  
  56.         return chart;  
  57.     }  
  58. }  

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

[java] view plaincopy
  1. class Client {  
  2.     public static void main(String args[]) {  
  3.         Chart chart;  
  4.         chart = ChartFactory.getChart("histogram"); //通过静态工厂方法创建产品  
  5.         chart.display();  
  6.     }  
  7. }  

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

创建柱状图!

初始化设置柱状图!

显示柱状图!


在客户端测试类中,我们使用工厂类的静态工厂方法创建产品对象,如果需要更换产品,只需修改静态工厂方法中的参数即可,例如将柱状图改为饼状图,只需将代码:

chart = ChartFactory.getChart("histogram");

改为:

chart = ChartFactory.getChart("pie");


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

创建饼状图!

初始化设置饼状图!

显示饼状图!


文章来自:http://blog.csdn.net/lovelion

0 0