首页 > 代码库 > 设计模式读完总结(2)工厂模式

设计模式读完总结(2)工厂模式

1.问 : 很多时候通过反射机制就可以很灵活地创建对象,为毛还要工厂?技术分享

将对象的创建和使用分开,单一职责两个类A和B之间的关系应该仅仅是A创建B或是A使用B,而不能两种关系都有

与一个对象相关的职责通常有三类:对象本身所具有的职责、创建对象的职责和使用对象的职责

   在Java语言中,我们通常有以下几种创建对象的方式:

       (1) 使用new关键字直接创建对象;  

       (2) 通过反射机制创建对象;

       (3) 通过clone()方法创建对象;

       (4) 通过工厂类创建对象。

new 灵活性不好,不符合开闭原则。

将对象的创建和使用分离还有一个好处:防止用来实例化一个类的数据和代码在多个类中到处都是,可以将有关创建的知识搬移到一个工厂类中

一个类可能拥有多个构造函数,构造函数名字都与类名相同,将对象的创建过程封装在工厂类中,我们可以提供一系列名字完全不同的工厂方法,每一个工厂方法对应一个构造函数,客户端可以以一种更加可读、易懂的方式来创建对象。

 

2.简单工厂模式——提供一个统一的工厂类来创建所有的产品对象

技术分享

abstract class Product {
  //所有产品类的公共业务方法
  public void methodSame() {
  //公共方法的实现
  }
  //声明抽象业务方法
  public abstract void methodDiff();
}

class ConcreteProduct extends Product {
  //实现业务方法
  public void methodDiff() {
    //业务方法的实现
  }
}


class
Factory {   //静态工厂方法 也可用反射机制实现 public static Product getProduct(String arg) { Product product = null; if (arg.equalsIgnoreCase("A")) { product = new ConcreteProductA(); //初始化设置product } else if (arg.equalsIgnoreCase("B")) { product = new ConcreteProductB(); //初始化设置product } return product; } }

class Client {
  public static void main(String args[]) {
    Product product;
    product = Factory.getProduct("A"); //通过工厂类创建产品对象
    product.methodSame();
    product.methodDiff();
  }
}


 

我们可以将静态工厂方法的参数存储在XML或properties格式的配置文件中,如下config.xml所
示:
<?xml version="1.0"?>
<config>
<chartType>histogram</chartType>
</config>
再通过一个工具类XMLUtil来读取配置文件中的字符串参数,XMLUtil类的代码如下所示:

import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import java.io.*;
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;
}
}
}

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

缺点:

(1) 工厂类过于庞大,包含了大量的if…else…代码,导致维护和测试难度增大;
(2) 系统扩展不灵活,如果增加新类型的产品类,必须修改静态工厂方法的业务逻辑,违反了“开闭原则”。

 适用场景
(1) 工厂类负责创建的对象比较少,工厂方法中的业务逻辑不会太过复杂。
(2) 客户端只知道传入工厂类的参数,对于如何创建对象并不关心。

 结论:对象种类比较少的时候用。

 

3.工厂方法针对不同的产品提供不同的工厂,系统提供一个与产品等级结构对应的工厂等级结构

 

 技术分享

 

 

 

 

//*****引入抽象工厂
interface
Factory {   public Product factoryMethod(); }w class ConcreteFactory implements Factory {   public Product factoryMethod() {     return new ConcreteProduct(); } Factory factory; factory = new ConcreteFactory(); //可通过配置文件实现 Product product; product = factory.factoryMethod();}

 

 

 
 

 

设计模式读完总结(2)工厂模式