`

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

阅读更多

上次对简单工厂模式的使用进行了总结,讲解过程中使用了在网上商城买东西的例子。大家也许注意到了所有商品的实例化都是在一个工厂类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++编程中,工厂方法模式广泛应用于各种软件设计中,因为它能有效地解耦...

    设计模式UML图--工厂模式

    - 定义:工厂方法模式将对象的创建延迟到子类,父类定义了创建对象的接口,但由各个子类决定实例化哪个类。这样,每个子类都可以决定其创建的产品类型。 - UML图表示:工厂方法模式的UML图包括一个抽象工厂类,一...

    c#设计模式-工厂模式

    工厂方法模式将对象的创建过程进一步抽象,将具体的对象创建延迟到子类中。工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。这样,工厂方法让类的实例化推迟到子类。在C#中,可以通过...

    工厂方法模式和抽象工厂模式的区别

    它将对象的创建延迟到子类中进行,使得代码更加模块化,易于维护和扩展。工厂方法模式通常只有一个方法,这个方法负责创建一个特定的产品。在实际应用中,如果需要创建的对象具有共同的接口或基类,但具体类型是由...

    java设计模式--工厂模式

    2. **工厂方法模式**:将具体产品的实例化延迟到子类中进行,工厂接口定义了创建对象的协议,但不直接实例化对象,而是由每个子类自己决定实例化哪个具体产品。这种方式增强了系统的灵活性,易于扩展新的产品。 3. ...

    Java 工厂模式 抽象工厂 工厂方法模式

    **工厂方法模式**:这是一种更为灵活的工厂模式变体,它将对象的创建延迟到子类中进行。在工厂方法模式中,父类定义了一个创建对象的接口,但由子类来决定要实例化的具体类。这种方式使得系统更具可扩展性,当需要...

    4月23 -- 工厂方法模式、简单工厂模式

    工厂方法模式的核心优势是,它将对象的创建延迟到子类中,因此在添加新产品时,只需添加新的子类即可,无需修改现有的代码。 工厂方法模式让系统更加灵活和可扩展,因为它支持在运行时创建多个具体类的实例。这意味...

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

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

    设计模式之工厂方法、简单工厂、抽象工厂

    工厂方法将一个类的实例化延迟到其子类。这种方式提供了一种封装对象创建的方式,使得客户端代码不必知道具体创建的是哪个类的对象,提高了代码的灵活性和可扩展性。 2. **简单工厂(Simple Factory)**: 简单...

    java工厂方法模式

    同时,工厂方法模式也可以避免简单工厂模式的缺点,即当有新产品要加入到系统中时,必须对工厂类进行修改,以加入必要的处理逻辑。 工厂方法模式适合在如下场合中运用: * 当无法得知必须创建的对象属于哪个类的...

    设计模式之工厂方法模式

    工厂方法模式提供了一种封装对象创建过程的方法,使得具体的创建过程延迟到子类中进行,从而实现了类的抽象化与具体实现的分离,提高了代码的可扩展性和可维护性。 ### 标题解析: “设计模式之工厂方法模式”表明...

    工厂方法模式[C#]

    在C#中,我们可以利用这种模式来抽象产品的创建过程,将具体的实例化操作延迟到子类中进行,从而实现代码的解耦和扩展性。 1. **模式定义** 工厂方法模式定义了一个创建对象的接口,但让实现这个接口的类来决定...

    工厂方法和抽象工厂——Factory Method & Abstract Factory

    工厂方法模式是一种将对象的创建过程延迟到子类中实现的策略。它定义了一个创建对象的接口,但让子类决定实例化哪一个类。在工厂方法模式中,工厂角色(Factory)不再直接创建产品,而是由具体工厂(Concrete ...

    简单工厂模式和工厂方法模式

    与简单工厂模式不同,工厂方法模式将对象的创建延迟到了子类,使得系统更易于扩展。 #### 1. 角色分析 - **抽象工厂类**:定义一个创建对象的接口,让子类决定实例化哪一个类。抽象工厂本身不直接实例化对象,而是...

    软件设计之工厂方法模式,源代码

    在工厂方法模式中,我们定义了一个用于创建对象的接口,但让子类决定实例化哪一个类。该模式将实例化推迟到子类。 工厂方法模式包含四个主要角色: 1. **抽象产品(Product)**:定义了产品的接口。 2. **具体产品...

    用工厂方法模式重构简易计算器 源代码+实验报告

    总结,本项目通过工厂方法模式重构简易计算器,展示了这种模式在处理多类型对象创建问题时的灵活性和可扩展性。这种方法使得代码结构清晰,易于维护,同时也为添加新功能提供了便利。对于学习设计模式和实践面向对象...

    工厂方法模式和抽象工厂模式

    这样,工厂方法将实例化对象的过程延迟到了子类,实现了对具体类的解耦。在Java或其他面向对象语言中,通常表现为一个抽象类或接口定义了一个工厂方法,而各个具体的子类重写这个方法来创建对应的实例。这种模式的一...

    工厂方法模式代码示例

    工厂方法模式是一种面向对象的设计模式,属于创建型模式,它提供了一种创建对象的最佳方式。在工厂方法模式中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为模式。 工厂方法模式的核心思想是...

    设计模式 工厂方法模式

    工厂方法模式定义了一个创建对象的接口,但让子类决定实例化哪一个类。工厂方法让类的实例化推迟到子类中进行,实现了对责任的分割,降低了系统的耦合度。 2. **角色与结构**: - **产品接口(Product)**:定义了...

Global site tag (gtag.js) - Google Analytics