码迷,mamicode.com
首页 > 其他好文 > 详细

工厂方法模式

时间:2016-07-10 18:44:54      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:

1. 模式定义

问题描述:

通常在导出数据上会有一些约定的格式,比如导出成文本格式,数据库备份形式,Excel格式,Xml格式。
对于实现数据导出的业务功能对象,它需要创建ExportFileApi的具体实现对象,但是它知道ExportFileApi接口,而不知道其具体的实现,那该怎么办?

工厂方法模式的定义:

定义一个用于创建对象的接口,让子类决定去实例化哪一个类,Factory Method使一个类的实现化延迟到其子类。

2. UML图

技术分享
Product:定义工厂方法所创建的对象的接口,也就是实现需要使用的对象的接口
ConcreteProduct:Product的实现对象
Creator:声明工厂方法,工厂方法通常会返回一个Product类的实例对象,而且多是抽象方法
ConcreteCreator:覆盖实现Creator定义的工厂方法,返回具体的Product实例

具体代码:

/**
 * 导出的文件对象的接口
 */
public interface ExportFileApi {
    /**
     * 导出内容成为文件
     * @param data 示意:需要保存的数据
     * @return 是否导出成功
     */
    public boolean export(String data);
}

/**
 * 导出成数据库备份文件形式的对象
 */
public class ExportDB implements ExportFileApi{
    public boolean export(String data) {
        //简单示意一下,这里需要操作数据库和文件
        System.out.println("导出数据"+data+"到数据库备份文件");
        return true;
    }
}

/**
 * 导出成文本文件格式的对象
 */
public class ExportTxtFile implements ExportFileApi{
    public boolean export(String data) {
        //简单示意一下,这里需要操作文件
        System.out.println("导出数据"+data+"到文本文件");
        return true;
    }
}

/**
 * 实现导出数据的业务功能对象
 */
public abstract class ExportOperate {
    /**
     * 导出文件
     * @param data 需要保存的数据
     * @return 是否成功导出文件
     */
    public boolean export(String data){
        //使用工厂方法
        ExportFileApi api = factoryMethod();
        return api.export(data);
    }
    /**
     * 工厂方法,创建导出的文件对象的接口对象
     * @return 导出的文件对象的接口对象
     */
    protected abstract ExportFileApi factoryMethod();
}

/**
 * 具体的创建器实现对象,实现创建导出成数据库备份文件形式的对象
 */
public class ExportDBOperate extends ExportOperate{
    protected ExportFileApi factoryMethod() {
        //创建导出成数据库备份文件形式的对象
        return new ExportDB();
    }
}

/**
 * 具体的创建器实现对象,实现创建导出成文本文件格式的对象
 */
public class ExportTxtFileOperate extends ExportOperate{

    protected ExportFileApi factoryMethod() {
        //创建导出成文本文件格式的对象
        return new ExportTxtFile();
    }

}

public class Client {
    public static void main(String[] args) {
        //创建需要使用的Creator对象
        ExportOperate operate = new ExportDBOperate();
        //调用输出数据的功能方法
        operate.export("测试数据");
    }
}

3.研磨设计模式

工厂方法模式的功能主要是父类在不知道具体实现的情况下,完成自身的功能调用,而具体的实现让子类去做。

工厂方法的本质:延迟到子类去选择实现,有更好的维护性和可扩展性

一般不会把工厂方法暴露给客户端

IOC和DI

IOC Inversion Of Control 控制反转
DI Dependency Injection 依赖注入
依赖注入和控制反转是同一件事情的不同描述
依赖注入:从应用程序的角度描述,应用程序依赖容器创建并注入它所需要的外部资源;
控制反转:从容器的角度描述,容器控制应用程序,由容器反向地向程序注入其所需要的外部资源。
1. 参与者有谁:一个是某个Java对象,另一个是IOC/DI的容器,还有一个是某个对象的外部资源
2. 谁依赖于谁:某个Java对象依赖于IOC/DI的容器
3. 为什么需要依赖:对象需要IOC/DI容器来提供对象需要的外部资源
4. 谁注入谁:IOC/DI容器注入某个外部资源
5. 到底注入什么:注入某个对象所需的外部资源
6. 谁控制谁:IOC/DI的容器控制对象
7. 控制什么:控制对象实例的创建

参数化工厂方法值的是:通过给工厂方法传递参数,让工厂方法根据参数的不同创建不同的产品对象。

/**
 * 实现导出数据的业务功能对象
 */
public class ExportOperate {
    /**
     * 导出文件
     * @param type 用户选择的导出类型
     * @param data 需要保存的数据
     * @return 是否成功导出文件
     */
    public boolean export(int type,String data){
        //使用工厂方法
        ExportFileApi api = factoryMethod(type);
        return api.export(data);
    }
    /**
     * 工厂方法,创建导出的文件对象的接口对象
     * @param type 用户选择的导出类型
     * @return 导出的文件对象的接口对象
     */
    protected ExportFileApi factoryMethod(int type){
        ExportFileApi api = null;
        //根据类型来选择究竟要创建哪一种导出文件对象
        if(type==1){
            api = new ExportTxtFile();
        }else if(type==2){
            api = new ExportDB();
        }
        return api;
    }
}


public class Client {
    public static void main(String[] args) {
//      //创建需要使用的Creator对象
//      ExportOperate operate = new ExportOperate();
//      //调用输出数据的功能方法,传入选择到处类型的参数
//      operate.export(1,"测试数据");

        //创建需要使用的Creator对象
        ExportOperate operate = new ExportOperate2();
        //下面变换传入的参数来测试参数化工厂方法
        operate.export(1,"Test1");
        operate.export(2,"Test2");
        operate.export(3,"Test3");
    }
}


//扩展非常容易
/**
 * 扩展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; 
    }
}

工厂方法模式

标签:

原文地址:http://blog.csdn.net/jiangxishidayuan/article/details/51865574

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!