JAVA设计模式三--factorymethod(工厂方法模式)

来源:互联网 发布:良心 手游 知乎 编辑:程序博客网 时间:2024/05/27 10:42
Factory Method,工厂方法:
定义一个用于创建对象的接口,让子类决定实例化哪一个类,
Factory Method使一个类的实例化延迟到了子类


工厂方法模式
  工厂方法(Factory Method)模式  工厂方法的结构[1]简介
  工厂方法(Factory Method)模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。
核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步
抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。
  工厂方法模式是简单工厂模式的衍生,解决了许多简单工厂模式的问题。首先完全实现‘开-闭 原则’,实现了可扩展。
其次更复杂的层次结构,可以应用于产品结果复杂的场合。
  工厂方法模式的对简单工厂模式进行了抽象。有一个抽象的Factory类(可以是抽象类和接口),这个类将不在负责具
体的产品生产,而是只制定一些规范,具体的生产工作由其子类去完成。在这个模式中,工厂类和产品类往往可以依次对应。
即一个抽象工厂对应一个抽象产品,一个具体工厂对应一个具体产品,这个具体的工厂就负责生产对应的产品。
  工厂方法模式(Factory Method pattern)是最典型的模板方法模式(Templete Method pattern)应用。
工厂方法模式角色与结构
  [2]  抽象工厂(Creator)角色:是工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。
  具体工厂(Concrete Creator)角色:这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序
调用以创建产品对象。在上图中有两个这样的角色:BulbCreator与TubeCreator。
  抽象产品(Product)角色:工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。在上图中,这个
角色是Light。
  具体产品(Concrete Product)角色:这个角色实现了抽象产品角色所定义的接口。某具体产品有专门的具体工厂创建,它们之
间往往一一对应。
工厂方法模式的应用
  工厂方法经常用在以下两种情况中:
  第一种情况是对于某个产品,调用者清楚地知道应该使用哪个具体工厂服务,实例化该具体工厂,生产出具体的产品来。Java 
Collection中的iterator() 方法即属于这种情况。
  第二种情况,只是需要一种产品,而不想知道也不需要知道究竟是哪个工厂为生产的,即最终选用哪个具体工厂的决定权在生产
者一方,它们根据当前系统的情况来实例化一个具体的工厂返回给使用者,而这个决策过程这对于使用者来说是透明的。


与抽象工厂模式的区别在于,抽象工厂的工厂产多种产品,而工厂方法模式工厂只产一种产品

这样添加操作对象是,就不需要修改代码,直接创建类就可以了!

如图:



举例说明,拿操作文档为例吧,

先创建文档的超级接口,对文档有打开、保存、恢复和关闭的操作

package design.factorymethod;/** * 文件名称:design.singleton.Singleton.java * 创建人:Fei Wong * 创建时间: 2012-06-20 * 电子邮箱:feiwong8@126.com * 说明:工厂方法模式是简单工厂模式的衍生 * */public interface Document {void open() ;void save() ;void revert() ;void close() ; }

再创建txt文档的操作类:

package design.factorymethod;/** * 文件名称:design.singleton.Singleton.java * 创建人:Fei Wong * 创建时间: 2012-06-20 * 电子邮箱:feiwong8@126.com * 说明:此类是对txt文档进行操作 * */public class TextDocument implements Document {@Overridepublic void close() {System.out.println(  "关闭txt文档" ); }@Overridepublic void open() {System.out.println(  "打开txt文档" ); }@Overridepublic void revert() {System.out.println(  "恢复txt文档" ); }@Overridepublic void save() {System.out.println(  "保存txt文档" ); }}

创建了txt的操作类后,需要穿件工厂对其进行生产,此工厂只产TextDocument对象:

package design.factorymethod;/** * 文件名称:design.singleton.Singleton.java * 创建人:Fei Wong * 创建时间: 2012-06-20 * 电子邮箱:feiwong8@126.com * 说明:此工厂只生产TextDocument,其他的不生产 * */public class TextDocumentFactory {public static TextDocument geTextDocument(){return new TextDocument() ;}}


在创建对doc文档的操作类:

package design.factorymethod;/** * 文件名称:design.singleton.Singleton.java * 创建人:Fei Wong * 创建时间: 2012-06-20 * 电子邮箱:feiwong8@126.com * 说明:此类是对doc文档进行操作 * */public class DocDocument implements Document {@Overridepublic void close() {System.out.println(  "关闭doc文档" ); }@Overridepublic void open() {System.out.println(  "打开doc文档" ); }@Overridepublic void revert() {System.out.println(  "恢复doc文档" ); }@Overridepublic void save() {System.out.println(  "保存doc文档" ); }}

创建对Doc操作类的工厂,此工厂只产DocDocument对象:


package design.factorymethod;/** * 文件名称:design.singleton.Singleton.java * 创建人:Fei Wong * 创建时间: 2012-06-20 * 电子邮箱:feiwong8@126.com * 说明:此工厂只生产DocDocument,其他的不生产 * */public class DocDocumentFactory {public static DocDocument getDocDocument(){return new DocDocument() ; }}

创建main方法进行调用:

package design.factorymethod;/** * 文件名称:design.singleton.Singleton.java * 创建人:Fei Wong * 创建时间: 2012-06-20 * 电子邮箱:feiwong8@126.com * 说明:工厂调用方法 * */public class Main {public static void main(String[] args) {Document document = DocDocumentFactory.getDocDocument() ; document.open() ;document.revert() ;document.save() ;document.close() ;document = TextDocumentFactory.geTextDocument() ;document.open() ;document.revert() ; document.save() ;document.close() ;}}

在这里,我们需要什么资源,就去什么工厂里面获取。这就是与抽象工厂的区别。



原创粉丝点击