软件设计模式系列——简单工厂模式

时间:2021-12-17 15:28:02

一、定义

简单工厂模式,又称为静态方法模式,属于类创建型的模式,可以根据参数的不同返回不同的类的实例。

二、类图

软件设计模式系列——简单工厂模式

三、适用的环境

(1)工厂类创建的对象比较小,这样不会造成工厂方法中业务的逻辑过于复杂。

(2)客户端只是知道传入工厂类的参数、对于如何去创建对象并不关心。客户端不需要去关心创建的细节,只需要明确需要的参数,而由工厂内部负责具体的类的创建。

四、优点

(1)责任分割:工厂类含有处理逻辑,决定何时去创建产品对象,客户端只是需要传递对应的参数,即可以完成产品的创建。

(2)在一定程度上提高了系统的灵活性:可以通过引入配置文件的方法,在不去修改客户端代码的前提下,更换和增减新的产品。

五、缺点

(1)工厂类中集中了所有的判断处理逻辑,是整个系统的核心。

(2)系统拓展困难,如果去添加新的产品就不得不去修改工厂的逻辑,在产品类型较多时,需要修改工厂的内部逻辑,不利于系统的拓展和维护。

六、程序实例

(1)产品接口

 1 package SimpleFactoryPattern;
2
3 /**
4 * @author jiaqing.xu@hand-china.com
5 * @version 1.0
6 * @name
7 * @description 抽象的TV类
8 * @date 2017/10/19
9 */
10 public interface TV {
11 /**
12 * 电视机播放的方法
13 */
14 public void play();
15 }

(2)具体的电视类实现抽象接口

 1 package SimpleFactoryPattern;
2
3 /**
4 * @author jiaqing.xu@hand-china.com
5 * @version 1.0
6 * @name
7 * @description 具体的电视类 海尔电视机
8 * @date 2017/10/19
9 */
10 public class HaierTV implements TV {
11 @Override
12 public void play() {
13 System.out.println("海尔电视机播放中...");
14 }
15 }
 1 package SimpleFactoryPattern;
2
3 /**
4 * @author jiaqing.xu@hand-china.com
5 * @version 1.0
6 * @name
7 * @description
8 * @date 2017/10/19
9 */
10 public class HisenseTV implements TV {
11 @Override
12 public void play() {
13 System.out.println("海信电视机播放中...");
14 }
15 }

(3)产品工厂根据传入的参数的不同去实例化出不同的产品

 1 package SimpleFactoryPattern;
2
3 /**
4 * @author jiaqing.xu@hand-china.com
5 * @version 1.0
6 * @name
7 * @description 电视机工厂
8 * @date 2017/10/19
9 */
10 public class TVFactory {
11 /**
12 *
13 * @param brand
14 * @return
15 * @description 根据不同的brand去生成不同的TV
16 */
17 public static TV produceTV(String brand) throws Exception {
18 //生产Haier电视机
19 if(brand.equalsIgnoreCase("Haier")){
20 System.out.println("生产了一个Haier电视机.");
21 return new HaierTV();
22 }else if(brand.equalsIgnoreCase("Hisense")){
23 System.out.println("生产了一个Hisense电视机.");
24 return new HisenseTV();
25 }else{
26 throw new Exception("对不起,还不能生产该类型的电视机.");
27 }
28 }
29 }

(4)解析xml文件的工具类

 1 package SimpleFactoryPattern;
2
3 import org.w3c.dom.Document;
4 import org.w3c.dom.Node;
5 import org.w3c.dom.NodeList;
6 import org.xml.sax.SAXException;
7
8 import javax.xml.parsers.DocumentBuilder;
9 import javax.xml.parsers.DocumentBuilderFactory;
10 import javax.xml.parsers.ParserConfigurationException;
11 import java.io.File;
12 import java.io.IOException;
13
14 /**
15 * @author jiaqing.xu@hand-china.com
16 * @version 1.0
17 * @name
18 * @description
19 * @date 2017/10/19
20 */
21 public class XMLUtilTV {
22 /**
23 * 从xml中获取品牌的名称并返回该品牌名称
24 */
25 public static String getBrandName() throws ParserConfigurationException, IOException, SAXException {
26 //创建文档对象读取工厂
27 DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
28 DocumentBuilder builder = documentBuilderFactory.newDocumentBuilder();
29 Document doc;
30 doc = builder.parse(new File("configTV.xml"));
31
32 //获取对应的文本节点
33 NodeList nodeList = doc.getElementsByTagName("brandName");
34 Node classNode = nodeList.item(0).getFirstChild();
35 String brandName = classNode.getNodeValue().trim();
36 return brandName;
37 }
38 }

(5)config文件

1 <?xml version="1.0"?>
2 <config>
3 <brandName>Haier</brandName>
4 </config>

(6)测试方法

 1 package SimpleFactoryPattern;
2
3 /**
4 * @author jiaqing.xu@hand-china.com
5 * @version 1.0
6 * @name
7 * @description 测试方法
8 * @date 2017/10/19
9 */
10 public class Test {
11 public static void main(String[] args) throws Exception {
12 TV tv;
13 String brandName = XMLUtilTV.getBrandName();
14 //传入品牌名称 生产电视机
15 tv = TVFactory.produceTV(brandName);
16 tv.play();
17 }
18 }