4 方案的改进

Sunny软件公司开发人员发现在创建具体Chart对象时,每更换一个Chart对象都需要修改客户端代码中静态工厂方法的参数,客户端代码将要重新编译,这对于客户端而言,违反了“开闭原则”,有没有一种方法能够在不修改客户端代码的前提下更换具体产品对象呢?答案是肯定的,下面将介绍一种常用的实现方式。

我们可以将静态工厂方法的参数存储在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;
}
}
}

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

class Client {
public static void main(String args[]) {
Chart chart;
String type = XMLUtil.getChartType(); //读取配置文件中的参数
chart = ChartFactory.getChart(type); //创建产品对象
chart.display();
}
}

不难发现,在上述客户端代码中不包含任何与具体图表对象相关的信息,如果需要更换具体图表对象,只需修改配置文件config.xml,无须修改任何源代码,符合“开闭原则”。

思考

在简单工厂模式中增加新的具体产品时是否符合“开闭原则”?如果不符合,原有系统需作出哪些修改?

5 简单工厂模式的简化

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

图3 简化的简单工厂模式

在图3中,客户端可以通过产品父类的静态工厂方法,根据参数的不同创建不同类型的产品子类对象,这种做法在JDK等类库和框架中也广泛存在。

6 简单工厂模式总结

简单工厂模式提供了专门的工厂类用于创建对象,将对象的创建和对象的使用分离开,它作为一种最简单的工厂模式在软件开发中得到了较为广泛的应用。

         1. 主要优点

简单工厂模式的主要优点如下:

(1) 工厂类包含必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的职责,而仅仅“消费”产品,简单工厂模式实现了对象创建和使用的分离。

(2) 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以在一定程度减少使用者的记忆量。

(3) 通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。

         2. 主要缺点

简单工厂模式的主要缺点如下:

(1) 由于工厂类集中了所有产品的创建逻辑,职责过重,一旦不能正常工作,整个系统都要受到影响。

(2) 使用简单工厂模式势必会增加系统中类的个数(引入了新的工厂类),增加了系统的复杂度和理解难度。

(3) 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。

(4) 简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。

        3. 适用场景

在以下情况下可以考虑使用简单工厂模式:

(1) 工厂类负责创建的对象比较少,由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。

(2) 客户端只知道传入工厂类的参数,对于如何创建对象并不关心。

练习

使用简单工厂模式设计一个可以创建不同几何形状(如圆形、方形和三角形等)的绘图工具,每个几何图形都具有绘制draw()和擦除erase()两个方法,要求在绘制不支持的几何图形时,提示一个UnSupportedShapeException。

【作者:刘伟 http://blog.csdn.net/lovelion

工厂三兄弟之简单工厂模式(四)相关推荐

  1. 工厂三兄弟之简单工厂模式(一)

    工厂三兄弟之简单工厂模式(一) 工厂模式是最常用的一类创建型设计模式,通常我们所说的工厂模式是指工厂方法模式,它也是使用频率最高的工厂模式.本章将要学习的简单工厂模式是工厂方法模式的"小弟& ...

  2. 简单工厂模式-Simple Factory Pattern 工厂三兄弟之简单工厂模式(四):图表库解决方案的改进,简单工厂模式的简化,简单工厂模式总结

    4 方案的改进 Sunny软件公司开发人员发现在创建具体Chart对象时,每更换一个Chart对象都需要修改客户端代码中静态工厂方法的参数,客户端代码将要重新编译,这对于客户端而言,违反了" ...

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

    本文转载自 :http://blog.csdn.net/lovelion/article/details/9300337 工厂模式是最常用的一类创建型设计模式,通常我们所说的工厂模式是指工厂方法模式, ...

  4. java之设计模式工厂三兄弟之简单工厂模式

    [学习难度:★★☆☆☆,使用频率:★★★☆☆] 工厂模式是最常用的一类创建型设计模式,通常我们所说的工厂模式是指工厂方法模式,它也是使用频率最高的工厂模式.本章将要学习的简单工厂模式是工厂方法模式的& ...

  5. 工厂三兄弟之简单工厂模式(二)

    2 简单工厂模式概述 简单工厂模式并不属于GoF 23个经典设计模式,但通常将它作为学习其他工厂模式的基础,它的设计思想很简单,其基本流程如下: 首先将需要创建的各种不同对象(例如各种不同的Chart ...

  6. 工厂三兄弟之抽象工厂模式

    本文转载自 :http://blog.csdn.net/lovelion/article/details/9319181 工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问题,但 ...

  7. 【怎样写代码】工厂三兄弟之抽象工厂模式(四):抽象工厂模式

    如果喜欢这里的内容,你能够给我最大的帮助就是转发,告诉你的朋友,鼓励他们一起来学习. If you like the content here, you can give me the greates ...

  8. 【怎样写代码】工厂三兄弟之抽象工厂模式(六):扩展案例II

    如果喜欢这里的内容,你能够给我最大的帮助就是转发,告诉你的朋友,鼓励他们一起来学习. If you like the content here, you can give me the greates ...

  9. 【怎样写代码】工厂三兄弟之抽象工厂模式(五):扩展案例I

    如果喜欢这里的内容,你能够给我最大的帮助就是转发,告诉你的朋友,鼓励他们一起来学习. If you like the content here, you can give me the greates ...

最新文章

  1. STM32开发 -- md5sum命令
  2. 音视频技术开发周刊 | 196
  3. 自动驾驶中激光雷达如何检测障碍物?
  4. python data frame_Python dataframer包_程序模块 - PyPI - Python中文网
  5. java oracle数据库高效分页查询_Oracle学习之分页查询数据
  6. Uniswap 24h交易量约为10.6亿美元涨2.91%
  7. sql中截取字符串函数_SQL Server 2017中的顶级SQL字符串函数
  8. python面试题及答案2020_2020年python面试题汇总(最新)
  9. UVa 1399 Puzzle
  10. mysql二进制文件如何查看_使用mysqlbinlog查看MySQL二进制文件内容
  11. MyBatis中Mapper接口是怎么和XML文件关联起来的
  12. Python番外篇:segno模块制作WiFi二维码
  13. 计算机论文档案初探,[电子档案管理论文:档案计算机管理技术人才培训工作初探.doc...
  14. Responses 部分 | Http Header
  15. 性能测试---如何确定最大并发用户数
  16. 英文卡通字体_40种独特的卡通和漫画字体
  17. 服务器安卓系统安装教程,云服务器安装安卓系统
  18. 监控和告警系统架构设计
  19. 正宇丨揭秘你不知道的网络水军产业链运作内幕
  20. 全国青少年软件编程等级考试scratch二级考试大纲+考点

热门文章

  1. Amazon DMS 在数据迁移任务可用性及对源数据归档支持的实践
  2. api之removeAll()使用避坑
  3. webview过滤广告终极招式
  4. table 边框: border cellspacing cellpadding
  5. 五、概率和临界值即随机数的产生
  6. java如果不使用多态_深入理解java多态没有烤山药的存在,java就不香了吗?
  7. if js 判断成绩等级_JS 条件语句
  8. C#winform窗体控件之toolStrip
  9. 答案_连连看游戏设计
  10. abstract关键字详解