• 设计模式学习-工厂方法模式


      在上文(设计模式学习-简单工厂模式)的模拟场景中,我们用简单工厂模式实现了VISA和MASTERARD卡的刷卡处理,系统成功上线并运行良好,突然有一天老大跑来说,我们的系统需要升级,提供对一般银联卡的支持。怎么办?有需求总是要改的,苦B的程序员伤不起啊....

      怎么改?增加一个银联卡处理类?然后在工厂类的静态方法里增加Case处理?前几天刚读了面向对象的核心设计原则-“开放封闭原则”,这样改下去不是完全违背了这个设计原则?
     

      开放封闭原则(OCP,Open Closed Principle)是所有面向对象原则的核心。软件设计本身所追求的目标就是封装变化、降低耦合,而开放封闭原则正是对这一目标的最直接体现。其他的设计原则,很多时候是为实现这一目标服务的,例如以Liskov替换原则实现最佳的、正确的继承层次,就能保证不会违反开放封闭原则。开放封闭原则,其核心的思想是:软件实体应该是可扩展,而不可修改的。也就是说,对扩展是开放的,而对修改是封闭的


    于是,我决定重构之前的简单工厂模式实现的方法,首先我们找出变化点,增加银联卡处理类是不可避免,这属于扩展,对工厂类增加CASE条件的处理,这里属于修改原业务,属于修改,OCP告诉我们,对修改应该是关闭的。

      OK,顺利找到变化点,由于我们不知道将来需要实例化出什么对象,所以将产品工厂抽象出来,让对象的实例化在子类实现:

    View Code 
        abstract class HandleFactory
        {
            public abstract BankCardHandle CreateBankCardHandle();

      接着,我们实现生成VISA及MASTERARD刷卡对象的实际工厂:

    View Code 
        class VisaHandleFactory : HandleFactory 
        {
            public override BankCardHandle CreateBankCardHandle()
            {
                return new VisaHandle();
            }
        }

        class MasterCardHandleFactory : HandleFactory
        {
            public override BankCardHandle CreateBankCardHandle()
            {
                return new MasterCardHandle();
            }
      BankCardHandle、VisaHandle、MasterCardHandle类见上一篇(设计模式学习-简单工厂模式)。

      不知不觉,我们用工厂方法模式重构了我们的系统,下面我们看看工厂方法模式的介绍。

    模式概述:

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


    其中的类或对象之间的关系为:

    • 产品角色(Product)
      定义产品的相关接口。

    • 真实的的产品角色(ConcreteProduct)
      实现接口Product。

    • 工厂角色(Factory)
      声明工厂方法(FactoryMethod),返回一个产品(Product)。

    • 真实的工厂(ConcreteFactory)
      实现FactoryMethod工厂方法,由客户调用,返回一个Product实例。

      经过上面我们用工厂方法模式重构刷卡系统后,老大提出的增加一个银联卡的处理就比较好办了,先增加一个银联卡处理类,同时增加一个生产银联卡处理类的工厂类:

    View Code 
        class UnionPayCardHandle : BankCardHandle
        {
            public override void HandleProcess()
            {
                Console.WriteLine("银联卡处理中");
            }
        }

        class UnionPayCardHandleFactory : HandleFactory
        {
            public override BankCardHandle CreateBankCardHandle()
            {
                return new UnionPayCardHandle();
            }

    客户端调用代码如下:
    View Code 
                HandleFactory hd = new UnionPayCardHandleFactory();
                BankCardHandle bk = hd.CreateBankCardHandle();

    我们以后增加卡处理方式,只需要增加相应的卡处理类和生成卡处理类的工厂,然后修改一下客户端代码就好了,如果连客户端代码都不想修改,在客户端获取配置文件,用反射处理就OK了。
  • 相关阅读:
    经典滤波器设计
    算法学习专栏简介
    算法学习专栏简介
    压缩感知及实验分析
    压缩感知及实验分析
    《数学之美》之谈谈搜索引擎反作弊与权威性问题
    《数学之美》之谈谈搜索引擎反作弊与权威性问题
    查找searching
    查找searching
    《数学之美》之谈谈密码学
  • 原文地址:https://www.cnblogs.com/kdalan/p/2531395.html
Copyright © 2020-2023  润新知