设计模式学习笔记(工厂方法模式)
来源:互联网 发布:5g网络手机有哪些 编辑:程序博客网 时间:2024/05/16 23:49
转载自:http://www.impeng.org/factory-method.html
工厂方法模式属于创建型模式,即负责对象的创建。
为什么要有工厂?工厂的作用是将对象的创建和调用分离开来,对象的创建由工厂负责。因为在很多时候,对象的创建并不是new一个这么简单,其中可能会包含很多初始化函数。如果用传统的new方法实例化对象,当需要多次实例化时,会造成大量代码重复;而有工厂存在时,调用者只需要向工厂发出请求,工厂即返回所需对象,并且对调用者屏蔽了对象创建的细节,从而可以让调用者只需关注对象的使用,而不是其创建上。
要了解工厂方法模式(FactoryMethod),我们首先需要了解简单工厂(SimpleFactory,不是一种模式):
简单工厂可以概括为一句话:通过向工厂的产品创建方法中传入不同的参数,工厂返回相应的产品实例。
仔细观察上面的代码及注释,可以看出简单工厂的特点是:
- 包含有抽象产品(Car类)、具体产品(BMW类, Benz类)和工厂(CarFactory类);
- 工厂的构造函数对外不可见,通过一个静态的产品创建方法来创建产品;
- 调用者通过向产品创建方法中传入不同的参数,来得到对应的产品实例。
但是,思考如下问题:当我们需要新增一个产品的时候(比如,需要增加Buick车),将需要在工厂的产品创建方法中新增一个判断分支,也就是说需要修改工厂类的源代码。这显然不符合软件工程中最重要的开放关闭原则(OCP,Open-Close Principle;对扩展开放,对修改关闭)。
如何解决这个矛盾?在SimpleFactory中,一个工厂负责了所有产品的创建,当需要新增产品时,需要修改工厂类,这显然难以实现可扩展。由于可扩展大都是由接口来实现的,那么我们就可以抽象出工厂的特性(比如都有产品的创建方法create()),形成接口CarFactory,然后通过具体的工厂(实现了接口)来生产对应的产品,一个工厂只负责一种产品的创建。
这样,当需要新增产品时,我们可以通过三个步骤实现:
- 编写好新增的产品类(Buick车,实现抽象接口Car);
- 创建一个BuickFactory,实现抽象接口CarFactory(即实现其create方法);
- 调用者创建BuickFactory的实例,生产对应的Buick车。
具体代码如下:
由上可知,工厂方法模式具有以下的特点:
- 包含有抽象产品(Car类)、具体产品(如Buick类)、抽象工厂(CarFactory类)、具体工厂(如BuickFactory类);
- 工厂需要实例化,即存在默认构造函数;
- 一个具体工厂只负责一个具体产品的生产。
由此可知,工厂方法模式很好地遵循了开闭原则,实现了程序的可扩展。如果有新的产品需要生产,只需要新建一个具体工厂(实现抽象工厂接口)来负责该产品的创建;由于所有代码都面向接口实现,调用者只需要知道具体工厂的名称即可(如代码中的new BuickFactory();),将具体产品(具体工厂)返回给抽象产品(抽象工厂),不需要修改被调用模块的源代码,调用模块也只需要修改具体工厂的类名,提高了可维护性。
另外,如果将具体工厂名称的信息通过Java反射机制或IOC方式(如Spring)注入到客户端中,这样连调用处的代码也不用修改了,只需要在配置文件中修改一下配置信息就行了。这样,整个程序就实现了源代码完全无修改的可扩展。
- 【设计模式】工厂方法模式学习笔记
- 设计模式学习笔记-工厂方法模式
- 设计模式学习笔记--工厂方法模式
- 设计模式学习笔记-工厂方法模式
- java 设计模式 学习笔记 (2) - 工厂方法模式
- 设计模式之-工厂方法模式(学习分析笔记)
- 设计模式学习笔记(工厂方法模式)
- java设计模式学习笔记(二)--工厂方法模式
- 大话设计模式-工厂方法模式(学习笔记)
- 设计模式学习笔记(三)工厂方法模式
- 设计模式学习笔记(工厂模式)
- 设计模式学习笔记(3)工厂方法
- 设计模式学习笔记——简单工厂模式、工厂方法模式、抽象工厂模式
- 设计模式学习笔记四:工厂方法(Factory Method)
- 设计模式学习笔记——工厂方法模式
- C++设计模式学习笔记五:工厂方法模式
- 设计模式学习笔记——工厂方法模式
- 设计模式学习笔记三:工厂方法模式
- 数据源控件
- 过滤器
- 提升g++的编译速度的第一选择:ccache
- ubuntu 11.10通过rvm安装Ruby 1.9.2, Rails 3
- Ubuntu中Vmware Tools的安装与卸载
- 设计模式学习笔记(工厂方法模式)
- proc oracle 连接释放不了的问题
- JAVA面试题-STRINGBUFFER倒序输出、正则将首字母大写
- 一步一步写算法(之Hanoi塔问题)
- mysql 全文索引,回避like 的低效
- JDBC多线程访问数据库获取结果集的问题
- 设计模式学习笔记(组合模式)
- 痛苦的epoll+线程池实践 1 程序架构
- 【2011年度博客大赛】还请大家多多支持!!