Java 工厂方法模式5(二)

2014-11-24 03:22:03 · 作者: · 浏览: 1

}

然后扩展ExportOperate类,来加入新的实现,示例代码如下:

/**

* 扩展ExportOperate对象,加入可以导出XML文件

*/

public class ExportOperate2 extends ExportOperate{

/**

* 覆盖父类的工厂方法,创建导出的文件对象的接口对象

* @param type 用户选择的导出类型

* @return 导出的文件对象的接口对象

*/

protected ExportFileApi factoryMethod(int type){

ExportFileApi api = null;

//可以全部覆盖,也可以选择自己感兴趣的覆盖,

//这里只想添加自己新的实现,其它的不管

if(type==3){

api = new ExportXml();

}else{

//其它的还是让父类来实现

api = super.factoryMethod(type);

}

return api;

}

}

看看此时的客户端,也非常简单,只是在变换传入的参数,示例代码如下:

public class Client {

public static void main(String[] args) {

//创建需要使用的Creator对象

ExportOperate operate = new ExportOperate2();

//下面变换传入的参数来测试参数化工厂方法

operate.export(1,"Test1");

operate.export(2,"Test2");

operate.export(3,"Test3");

}

}

对应的测试结果如下:

导出数据Test1到文本文件

导出数据Test2到数据库备份文件

导出数据Test3到XML文件

通过上面的示例,好好体会一下参数化工厂方法的实现和带来的好处。

3.5 工厂方法模式的优缺点

  • 可以在不知具体实现的情况下编程
    工厂方法模式可以让你在实现功能的时候,如果需要某个产品对象,只需要使用产品的接口即可,而无需关心具体的实现。选择具体实现的任务延迟到子类去完成。
  • 更容易扩展对象的新版本
    工厂方法给子类提供了一个挂钩,使得扩展新的对象版本变得非常容易。比如上面示例的参数化工厂方法实现中,扩展一个新的导出Xml文件格式的实现,已有的代码都不会改变,只要新加入一个子类来提供新的工厂方法实现,然后在客户端使用这个新的子类即可。
    另外这里提到的挂钩,就是我们经常说的钩子方法(hook),这个会在后面讲模板方法模式的时候详细点说明。
  • 连接平行的类层次
    工厂方法除了创造产品对象外,在连接平行的类层次上也大显身手。这个在前面已经详细讲述了。
  • 具体产品对象和工厂方法的耦合性
    在工厂方法模式里面,工厂方法是需要创建产品对象的,也就是需要选择具体的产品对象,并创建它们的实例,因此具体产品对象和工厂方法是耦合的。

    3.6 思考工厂方法模式

    1:工厂方法模式的本质
    工厂方法模式的本质:延迟到子类来选择实现。
    仔细体会前面的示例,你会发现,工厂方法模式中的工厂方法,在真正实现的时候,一般是先选择具体使用哪一个具体的产品实现对象,然后创建这个具体产品对象的示例,然后就可以返回去了。也就是说,工厂方法本身并不会去实现产品接口,具体的产品实现是已经写好了的,工厂方法只要去选择实现就好了。
    有些朋友可能会说,这不是跟简单工厂一样吗?
    确实从本质上讲,它们是非常类似的,具体实现上都是在“选择实现”。但是也存在不同点,简单工厂是直接在工厂类里面进行“选择实现”;而工厂方法会把这个工作延迟到子类来实现,工厂类里面使用工厂方法的地方是依赖于抽象而不是具体的实现,从而使得系统更加灵活,具有更好的可维护性和可扩展性。
    其实如果把工厂模式中的Creator退化一下,只提供工厂方法,而且这些工厂方法还都提供默认的实现,那不就变成了简单工厂了吗?比如把刚才示范参数化工厂方法的例子代码拿过来再简化一下,你就能看出来,写得跟简单工厂是差不多的,示例代码如下:

     v 8 笺 俸郗 y组件依赖于低层组件,而且不管高层组件还是低层组件,都应该依赖于抽象。
    比如前面的示例,实现客户端请求操作的ExportOperate就是高层组件;而具体实现数据导出的对象就是低层组件,比如ExportTxtFile、ExportDB;而ExportFileApi接口就相当于是那个抽象。
    对于ExportOperate来说,它不关心具体的实现方式,它只是“面向接口编程”;对于具体的实现来说,它只关心自己“如何实现接口”所要求的功能。
    那么倒置的是什么呢?倒置的是这个接口的“所有权”。事实上,ExportFileApi接口中定义的功能,都是由高层组件ExportOperate来提出的要求,也就是说接口中的功能,是高层组件需要的功能。但是高层组件只是提出要求,并不关心如何实现,而低层组件,就是来真正实现高层组件所要求的接口功能的。因此看起来,低层实现的接口的所有权并不在底层组件手中,而是倒置到高层组件去了。

    3:何时选用工厂方法模式
    建议在如下情况中,选用工厂方法模式:

    • 如果一个类需要创建某个接口的对象,但是又不知道具体的实现,这种情况可以选用工厂方法模式,把创建对象的工作延迟到子类去实现
    • 如果一个类本身就希望,由它的子类来创建所需的对象的时候,应该使用工厂方法模式

      3.7 相关模式

      • 工厂方法模式和抽象工厂模式
        这两个模式可以组合使用,具体的放到抽象工厂模式中去讲。
      • 工厂方法模式和模板方法模式
        这两个模式外观类似,都是有一个抽象类,然后由子类来提供一些实现,但是工厂方法模式的子类专注的是创建产品对象,而模板方法模式的子类专注的是为固定的算法骨架提供某些步骤的实现。
        这两个模式可以组合使用,通常在模板方法模式里面,使用工厂方法来创建模板方法需要的对象。

        工厂方法模式结束,谢谢观看!

        私塾在线学习网原创内容 跟着cc学设计系列 之 研磨设计模式

        原创内容,转载请注明出处