(工厂方法模式)Factory Method

Factory Method是创建模式中比较重要的一种设计模式,其主要思想是使一个类的实例化延迟到其子类。

使用场景

典型的应用场景如:在某个系统开发的较早阶段,有某些类的实例化过程,实例化方式可能还不是很确定,或者实际实例化的对象(可能是需要对象的某个子类中的一个)不确定,或者比较容易变化。此时,应用本模式,可以将这种复杂情形隔离开,即将这类不确定的对象的实例化过程延迟到子类。

模式结构

该模式的典型实现方法就是将调用类定义为一个虚类,在调用类定义一个专门用于构造不确定的对象实例的虚函数,再将实际的对象实例化代码留到调用类的子类来实现。如果,被构造的对象比较复杂的话,同时可以将这个对象定义为可以继承、甚至虚类,再在不同的调用类的子类中按需返回被构造类的子类。

将Factory Method的结构绘出如下:

 

1. Product: 需要创建的产品的抽象类。

2. ConcreteProduct: Product的子类,一系列具体的产品。

3. AbstractOperator: 抽象创建器接口,声明返回Product类型对象的FactoryMethod。

4. ConcreteOpeator: 具体的创建器,重写AbstractOperator中的FactoryMethod,返回ConcreteProduct类型的实例.

FactoryMethod中的AbstractOperator中拥有一个抽象的factoryMethod()方法,它负责生成一个IProduct类型的物件,由于目前还不知道将如何实现这个类型,所以将之推迟至子类别中实现,在AbstractOperator中先实现IProduct操作介面沟通的部份,只要介面统一了,利用多型操作即可完成各种不同的IProduct类型之物件操作。也就是说,对AbstractOperator来说,其操作的IProduct是可以抽换的。

情景展现

考虑一个状况,您所经营的工厂正在生产一个新的电视机产品,现在有一个问题发生了,您的电视机产品所有的组件都可以自行生产,像是操作面版、电源、摇控装置等等,但荧幕却必须依赖另一个厂商或子厂商供应,这时您怎么办?您不能将生产进度停下了,相反的您必须确定一些事情,您知道有关于荧幕控制的所有介面,您可以将这些对介面的操作沟通先实现,等到荧幕到了,直接将荧幕与您的半成品组合起来,一个完整的成品即可出厂。
   
Factory Method模式在一个抽象类中留下某个创建元件的抽象方法没有实作,其它与元件操作相关联的方法都先依赖于元件所定义的介面,而不是依赖于元件的实现, 当您的成品中有一个或多个元件无法确定时,您先确定与这些元件的操作介面,然后用元件的抽象操作介面先完成其它的工作,元件的实作(实现)则推迟至实现元件介面的子类完成,一旦元件加入,即可完成您的成品。

再举一个例子,假设您要完成一个文件编辑器,您希望这个编辑器可以适用于所有类型的档案编辑,例如RTF、DOC、TXT等等,尽管这些文件有着不同的格式,您先确定的是这些文件必然具备的一些操作介面,例如储存、开启、关闭等等,您用一个IDocument类型来进行操作,这么一来这个框架就无需考虑实际的储存、开启等细节是如何进行的。
以 UML 类别图来表现以下的概念:

AbstractEditor是个抽象类,其中的createDocument()方法是个抽象方法,因为框架不知道您将实现一个什么类型的文件,这个抽象方法将推迟至继承AbstractEditor的子类中实现。

这个架构可用以下简单的示意程式来作示范,当中实现了一个RTFDocument,虽然在AbstractEditor中并不知道我们会套用这个RTFDocument,但您可以看到,透过多型操作,您的框架可以进行对文件的相关操作。

  • AbstractEditor.java

public abstract class AbstractEditor {
   
private IDocument document;

//抽象创建器接口,声明返回IDocument类型对象的Factory Method

   public abstract IDocument createDocument();

  

   public void newDocument() {
        document = createDocument();
        document.open();
    }
    public void saveDocument() {
        if(document != null)
            document.save();
    }

    public void closeDocument() {
        if(document != null)
            document.close();
    }
}

 

  • IDocument.java

/*需要创建的文档的抽象类*/

public interface IDocument {
   
public void open();
    public void save();
    public void close();
}

 

  • RTFEditor.java

/*具体的创建器,重写AbstractOperator AbstractEditor中的FactoryMethod【createDocument()*/

public class RTFEditor extendsAbstractEditor {
   
public IDocument createDocument() {
        return new RTFDocument();
    }
}                

  • RTFDocument.java

/*具体的产品:具体文档类型*/

public class RTFDocument implementsIDocument {
   
public RTFDocument() {
        System.out.println("建立RTF文件");
   
}

    public void open() {
        System.out.println("开启文件");
   
}

    public void save() {
        System.out.println("储存文件");
   
}

    public void close() {
        System.out.println("关闭文件");
   
}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值