`

对象的创建延迟到子类--工厂方法模式

阅读更多

上次对简单工厂模式的使用进行了总结,讲解过程中使用了在网上商城买东西的例子。大家也许注意到了所有商品的实例化都是在一个工厂类ProductFactory中完成,如果商城有数十万个商品,都在一个工厂类中实现肯定是不现实的。这时最容易想到的方式,是对商品进行分类,不同的类型采用不同的“工厂”创建,这就是产生了工厂方法模式。“商城”只需要定义好接口,具体的工厂实现交给具体的商家实现即可。

 

工厂方法模式

 

工厂方法模式定义了一个创建对象的接口(抽象类),但由子类决定要实例化的类是哪一个(目标对象),工厂方法让类把实例化推迟到了子类。这里其实有三种角色:抽象的创建接口、具体的创建工厂类、目标对象(对应还有一个目标基类),具体的创建工厂类继承自抽象接口类,其作用是根据不同的条件创建不对的目标对象。这就是所谓的把创建对象的决定权交给子类,从而实现完全基于接口编程,而不必在意具体的实现(相对于简单工厂模式)。下面来看下工厂方法模式的类图:



 

 

这里的ProductFactoryAProductFactoryB分布都可以创建两类对象,也可以只创建一类对象。AbsClient里公共的业务方法,以及抽象的工程方法由于创建具体的目标对象,ProductFactoryAProductFactoryB实现这个方法。

 

该模式的核心是把公共的业务方法提取到AbsClient基类中(参考上一章中的Client类的orderProduct方法),在依赖具体目标对象的地方使用Iproduct接口代替,具体创建这些对象的工作交给AbsClient的子类去实现;同时为了方便扩展,AbsClient的子类根据业务需要可以有多个,这些子类都是具体的工厂类,每个工厂类可以创建同一类Product。比如这里ProductFactoryA可以创建Product1Product2ProductFactoryB可以创建Product3Product4。可以把每个工厂类看做是一个商家的工厂,“网上商城”AbsClient 要增加自己的商品品类,可以接入不同的商家入驻即可(实现新的工厂类,创建新的商品类),原有已存在的代码无需任何改动。

 

这里不再使用商城的列子,感兴趣的朋友可以自己实现。下面以实际项目中一个例子进行讲解。

 

模式示例

 

这里以笔者真实项目中的场景为例:该项目是一个页面的在线编辑系统,页面编辑好后会有发布动作,该动作会触发数据保存(saveData方法)、发起页面渲染请求(sendRender方法)、向MQ发送消息(sendMq方法)。如果只有一类页面该流程实现起来很简单,但现在有4个不同业务类型对应的页面:pc活动页、pc店铺页、m活动页、m店铺页,后续还有可能增加别的业务类型对应的页面。这里其实就可以采用工程方法模式,来创建不同的业务对象进行处理。首先来看下类图,对应上面的类图,只是类名上有改动:

 



 

 

首先来看抽象基类AbsPublish

 
public abstract class AbsPublish {
 
    private BusinessService businessService;
 
    /**
     * 页面发布方法
     */
    public void publish(String type,Integer id){
        businessService = createBusiness(type);
 
        //step1 保存页面配置数据
        businessService.saveData(id);
 
        //step2 发起渲染请求
        businessService.sendRender(id);
 
        //step3 把该活动信息发布到“已发布消息队列”
        businessService.sendMq(id);
 
        //其他公共操作
        printLog(type,id);
    }
 
    private void printLog(String type,Integer id){
        System.out.println("类型:"+type+"编号:"+id+"发布完成");
    }
 
    protected abstract  BusinessService createBusiness(String type);
}
 

 

publish方法是就是页面发布的通用流程,分别会触发数据保存(saveData方法)、发起页面渲染请求(sendRender方法)、向MQ发送消息(sendMq方法)。这三个方法在不同的业务类型对应的实现不同,但这里不用管具体的实现。具体的实现交给createBusiness(String type)方法去创建,该方法收抽象方法,交给子类实现。

 

ActPublishShopPublishAbsPublish两个子类,主要方作用就是实现createBusiness方法,创建具体的业务对象。

public class ActPublish extends AbsPublish {
    @Override
    protected BusinessService createBusiness(String type) {
        BusinessService businessService = null;
        if("mAct".equals(type)){
            businessService = new MActBusinessImpl();
        }else if ("pcAct".equals(type)){
            businessService = new PcActBusinessImpl();
        }
        return businessService;
    }
}
 

 

 

public class ShopPublish extends AbsPublish {
    @Override
    protected BusinessService createBusiness(String type) {
        BusinessService businessService = null;
        if("mShop".equals(type)){
            businessService = new MShopBusinessImpl();
        }else if ("pcShop".equals(type)){
            businessService = new MShopBusinessImpl();
        }
        return businessService;
    }
}

 

接下来再来看下业务基类和业务实现类

public interface BusinessService {
 
    /**
     * 保存数据库
     */
    void saveData(Integer id);
 
    /**
     * 发起页面渲染请求
     */
    void sendRender(Integer id);
 
    /**
     * 向mq(消息队列)发送页面发布消息
     */
    void sendMq(Integer id);
}

 

 

MActBusinessImplMShopBusinessImplPcActBusinessImplPcShopBusinessImpl是具体的业务实现类,这里只列出MActBusinessImpl实现代码,实现具体业务逻辑已省略,可以自行实现:

public class PcShopBusinessImpl implements BusinessService {
    public void saveData(Integer id) {
        System.out.println("pc店铺:配置数据入库");
    }
 
    public void sendRender(Integer id) {
        System.out.println("pc店铺:发起页面渲染请求");
    }
 
    public void sendMq(Integer id) {
        System.out.println("pc店铺:把该活动信息推送到 已发布pc店铺mq(消息队列)");
    }
}
 

 

 

最后创建main方法测试,模拟发布编号为12345m活动页:

public class Main {
    public static void main(String[] args) {
        AbsPublish mAct = new ActPublish();
        mAct.publish("mAct",12345);
    }
}

 

运行main方法:

M活动:配置数据入库
M活动:发起页面渲染请求
M活动:把该活动信息推送到 已发布M活动mq(消息队列)
类型:mAct编号:12345发布完成

如果要新增一个业务逻辑,新增一个工厂类和具体的业务实现类即可。

 

小结

 

 

使用工厂方法模式,可以把具体的实现延迟到子类中进行,满足了 oo设计原则中的针对接口编程和不针对实现,以及开闭原则(对修改关闭,都扩展开放)。缺点,就是会创建很多的工厂类实现和具体业务类实现,但可以把这部分实现交给第三方,主体业务只负责定义规则(创建接口),实现业务解耦。

 

出处:

http://moon-walker.iteye.com/blog/2397069

  • 大小: 11.8 KB
  • 大小: 13.5 KB
0
0
分享到:
评论

相关推荐

    C#编程模式之工厂方法模式+抽象工厂模式

    本资源主要介绍工厂方法模式和抽象工厂模式。二者都与工厂相关,,但是其... 工厂方法模式:它将对象的创建延迟到子类中进行。由子类决定具体实例化哪个类。通过切换具体工厂的子类,来改变单个实例(也可说产品)。

    C++设计模式原理与实战视频课

    2-5 工厂模式的定义场景与实现——子类延迟实现父类功能的软件结构 2-6 工厂模式的实用工程技术——IOC容器与工厂模式的应用 2-7 抽象工厂的定义、场景与实现——相互关联关系的对象 2-8 抽象工厂的实用工程技术——...

    工厂方法模式.zip

    工厂方法使一个类的实例化延迟到子类。 (3)工厂方法降低了客户程序与产品对象的耦合,工厂方法模式是简单工厂模式的进一步抽象和推广,由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,但缺点是每增加一个...

    设计模式-工厂模式C++实现

    用c++实现的工厂模式示例代码,工厂模式不仅封装了创造对象的接口,而且将对象的创建延迟到子类的实例化,具体的实例化为子类提供。

    Factory Method Pattern.rar【GoF的工厂方法模式(C#源码)】

    在工厂方法模式中,父类负责定义创建对象的公共接口,而子类则负责生成具体的对象,这样做的目的是将类的实例化操作延迟到子类中完成,即由子类来决定究竟应该实例化(创建)哪一个类。 理解: 我们知道兵工厂可以...

    Python设计模式-工厂模式

    工厂方法模式:定义一个创建对象接口,让子类来决定创建哪个类的实例,工厂方法使一个类的实例化延迟到到其子类中 抽象工厂模式:提供一些列相关或相互依赖的对象接口,而指定他们的具体类 from abc import ABCMeta,...

    实例讲解Python设计模式编程之工厂方法模式的使用

    工厂方法模式是简单工厂模式的进一步抽象和推广,它不仅保持了简单工厂模式能够向客户隐藏类的实例化过程这一优点,而且还通过多态性克服了工厂类过于复杂且...工厂方法模式的实质是将对象的创建延迟到其子类实现,即由

    单例模式与工厂模式.docx

    工厂方法使一个类 的实例化延迟到其子类。) Product 为抽象产品类负责定义产品的共性,实现对事物最抽象的定义; Creator 为抽象创建类,也就是抽象工厂,具体如何创建产品类是由具体的实现工 厂 ConcreteCreator...

    Android设计模式系列之工厂方法模式

    今天以ThreadFactory举例说明一下简单工厂模式和工厂方法模式。 工厂方法模式,Factory Method,简单的方式,不简单的应用。 1.意图 定义一个用于创建对象的接口,让子类决定实例化哪个类。工厂方式模式使一个类的...

    C# 设计模式系列教程-工厂方法模式

    工厂方法使一个类的实例化延迟到子类。 2. 模式中的角色  2.1 抽象工厂(Creator):这个抽象类(或接口)声明一个创建对象的工厂方法,用来返回一个Product类型的对象。  2.2 具体工厂(ConcreteCreator):重定义...

    浅析Python 简单工厂模式和工厂方法模式的优缺点

    前言 在《设计模式》一书中工厂模式提到了: 工厂方法模式(Factory Method) 抽象工厂模式 (Abstract Factory) 但是在实际过程中还有一种工厂...Factory Method 使一个类的实例化延迟到其子类。 别名 虚构造器(V

    设计模式 创建型模式 Abstract Factory模式(抽象工厂)

    2 将具体化类的工作延迟到了类中 3 创建创建一组相关对象或者说是一组相互依赖的对象 一般情况下,我们为了提高内聚和松耦合,经常会使用多态来处理一些问题。抽象出一些类的公共接口作为抽象基类或者接口。这 ...

    Android源码学习之工厂方法模式应用及优势介绍

    工厂方法模式定义: Define an ...工厂方法使一个类的实例化延迟到其子类。常用的工厂方法模式结构:  如上图所示(截取自《Head First Design Patterns》一书),主要包括四个部分: 抽象产品类Product负责定

    第5讲 工厂模式(简单工厂、抽象工厂)

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

    Java设计模式.docx

    工厂模式:工厂模式是一种创建型模式,它定义了一个用于创建对象的接口,让子类决定实例化哪个类。 单例模式:单例模式是一种创建型模式,它保证一个类只有一个实例,并提供了全局访问点。 适配器模式:适配器模式是...

    23种设计模式入门到精通详解.txt

    模板模式:定义一个算法结构,而将一些步骤延迟到子类实现。 解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器。 策略模式:定义一系列算法,把他们封装起来,并且使它们可以相互替换。 状态...

    设计模式(九)之工厂模式.zip

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

    设计模式 创建型模式 Complex Factory模式(复杂工厂)

    2 将具体化类的工作延迟到了类中 一般情况下,我们为了提高内聚和松耦合,经常会使用多态来处理一些问题。抽象出一些类的公共接口作为抽象基类或者接口。这样的话,我们将会面临一个挑战。在每次使用子类的时候,...

    详解设计模式中的工厂方法模式在Python程序中的运用

    在工厂方法模式中,父类负责定义创建对象的公共接口,而子类则负责生成具体的对象,这样做的目的是将类的实例化操作延迟到子类中完成,即由子类来决定究竟应该实体化哪一个类。 在简单工厂模式中,一个工厂类处于对...

    asp.net 简单工厂模式和工厂方法模式之论述

    而工厂方法模式定义了一个用于创建对象的借口,让子类决定实例化哪一个类,工厂方法是一个类的实例化延迟到其子类。其实多做一些联系不难发现:工厂方法模式实现时,客户端需要决定实例化那个工厂来实现运算类,选择...

Global site tag (gtag.js) - Google Analytics