设计模式 之 工厂方法模式解析

1、工厂方法模式的定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类,Factory Method使一个类的实例化延迟到其子类。

2、案例分析
在这里插入图片描述
Product: 定义工厂方法所创建的对象的接口,也就是实际需要使用的对象的接口。
ConcreteProduct:具体的Product接口的实现对象。
Creator:创建器,声明工厂方法,工厂方法通常会返回一个Product类型的实例对象,且多是抽象方法。也可在Creator里面提供工厂方法的默认实现,让工厂方法返回一个缺省的Product类型的实例对象。
ConcreteCreator:具体的创建器对象,覆盖实现Creator定义的工厂方法,返回具体的Product实例。

(1)需求:实现一个导出数据的应用框架,来让客户选择数据的导出方式,并真正执行数据导出,导出数据成:文本格式、数据库备份形式、Excel格 式、Xml格式等等
Product:导出的文件对象接口ExportFileApi
Creator:导出数 据的业务功能对象
在这里插入图片描述

//导出的文件对象接口ExportFileApi
public interface ExportFileApi {
    //可以定义Product的属性和方法 
    public boolean export(String data);
}

//为了简化,只实现导出文本文件格式和数据库备份文件两种
//导出成文本文件格式的对象
public class ExportTxtFile implements ExportFileApi{ 
    public boolean export(String data) {
        //简单示意一下,这里需要操作文件 
        System.out.println("导出数据"+data+"到文本文件"); 
        return true;
    } 
}
// 导出成数据库备份文件形式的对象
public class ExportDB implements ExportFileApi{ 
    public boolean export(String data) {
        //简单示意一下,这里需要操作数据库和文件 
        System.out.println("导出数据"+data+"到数据库备份文件"); 
        return true;
    } 
}
// 实现导出数据的业务功能对象 
public abstract class ExportOperate { 
    public boolean export(String data){ 
        //使用工厂方法
        ExportFileApi api = factoryMethod(); 
        return api.export(data);
    } 
    //工厂方法,创建导出的文件对象的接口对象
    protected abstract ExportFileApi factoryMethod(); 
}

public class ExportTxtFileOperate extends ExportOperate{ 
    protected ExportFileApi factoryMethod() {
        //创建导出成文本文件格式的对象
        return new ExportTxtFile(); 
    }
}
public class ExportDBOperate extends ExportOperate{ 
    protected ExportFileApi factoryMethod() {
        //创建导出成数据库备份文件形式的对象
        return new ExportDB(); 
    }
}

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

(2)功能:让父类在不知道具体实现的情况下,完成自身功能调用,而具体的实现延迟到子类来实现。
(3)特征
工厂方法的实现中,通常父类(Creator)会是一个抽象类,里面包含创建所需对象的抽象方法,这些抽象方法就是工厂方法。
子类在实现这些抽象方法的时候,通常并不是真的由子类来实现具体的功能,而是在子类的方法里面做选择,选择具体的产品实现对象。
父类(Creator)中通常有实现公共功能的方法,不管子类选择了何种具体的产品实现,这些方法的功能总是能正确执行。
(4)使用
工厂方法的实现中,可能需要参数,以便决定到底选用哪一种具体的实现。也就是说通过在抽象方法里面传递参数,在子类实现的时候根据参数进行选择,看看究竟应该创建哪一个具体的实现对象。
工厂方法一般不提供给Creator外部使用,如上例中的 factoryMethod 方法

3、扩展
(1)依赖注入和控制反转是同一概念吗?
答:依赖注入和控制反转是对同一件事情的不同描述,依赖注入是从应用程序的角度在描述,可以把依赖注入描述完整点:应用程序依赖容器创建并注入它所需要的外部资源;而控制反转是从容器的角度在描述,描述完整点:容器控制应用程序,由容器反向的向应用程序注入应用程序所需要的外部资源。
(2)IOC/DI的作用?
答:有效的分离了对象和它所需要的外部资源,使得他们松散耦合,有利于功能复用 (3)工厂方法模式和IoC/DI有什么关系呢?
答:工厂方法模式和 IoC/DI 的思想是相似的,都是“主动变被动”,进行了“主从换位”,从而获得了更灵活的程序结构。
(4)工厂方法和简单工厂的区别
答:工厂方法模式的本质是延迟到子类选择实现,工厂类中使用工厂方法的地方是依赖于抽象而不是具体的实现;简单工厂模式是直接在工厂类里进行“选择实现”,从某个角度来看的话,可以认为简单工厂就是工厂方法模式的一种特例。
(5)工厂方法模式体现了什么设计原则?
答:工厂方法模式很好的体现了“依赖倒置原则”,依赖倒置原则告诉我们“要依赖抽象,不要依赖于具体类”,简单点说就是:不能让高层组件依赖于低层组件,而且不管高层组件还是低层组件,都应该依赖于抽象。

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

尾注

  • 上述的总结与思考是基于对《研磨设计模式》这本书的精读与演绎
  • 更多及时干货,请关注微信公众号:JAVA万维猿圈
    在这里插入图片描述
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值