• PHP设计模式—工厂模式之工厂方法模式


    定义:

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

    代码实例:

    这里还是接着上篇简单工厂模式的那个例子,改成工厂方法模式。

    1、创建一个抽象类 ApptEncoder

    /**
     * 抽象类
     * Class ApptEncoder
     */
    abstract class ApptEncoder
    {
        abstract public function encode();
    }

    2、创建 BloggsCal 格式处理类

    /**
     * BloggsCal 格式处理类
     * Class BloggsApptEncoder
     */
    class BloggsApptEncoder extends ApptEncoder
    {
        public function encode()
        {
            // TODO: Implement encode() method.
            return "Appointment data encoded in BloggsCal format
    ";
        }
    }

    3、创建 MegaCal 格式处理类

    /**
     * MegaCal 格式处理类
     * Class MegaApptEncoder
     */
    class MegaApptEncoder extends ApptEncoder
    {
        public function encode()
        {
            // TODO: Implement encode() method.
            return "Appointment data encoded in MegaCal format
    ";
        }
    }

    4、创建工厂抽象类 CommsManager

    /**
     * 工厂抽象类
     * Class CommsManager
     */
    abstract class CommsManager
    {
        abstract public function getHeaderText();
        abstract public function getApptEncoder();
        abstract public function getFooterText();
    }

    5、创建 BloggsCal 工厂类

    /**
     * BloggsCal 工厂类
     * Class BloggsCommsManager
     */
    class BloggsCommsManager extends CommsManager
    {
        public function getHeaderText()
        {
            // TODO: Implement getHeaderText() method.
            return "BloggsCal header
    ";
        }
    
        public function getApptEncoder()
        {
            // TODO: Implement getApptEncoder() method.
            return new BloggsApptEncoder();
        }
    
        public function getFooterText()
        {
            // TODO: Implement getFooterText() method.
            return "BloggsCal footer
    ";
        }
    }

    6、创建 MegaCal 工厂类

    /**
     * MegaCal 工厂类
     * Class MegaCommsManager
     */
    class MegaCommsManager extends CommsManager
    {
        public function getHeaderText()
        {
            // TODO: Implement getHeaderText() method.
            return "MegaCal header
    ";
        }
    
        public function getApptEncoder()
        {
            // TODO: Implement getApptEncoder() method.
            return new MegaApptEncoder();
        }
    
        public function getFooterText()
        {
            // TODO: Implement getFooterText() method.
            return "MegaCal footer
    ";
        }
    }

    7、调用:

    // 如果要换成 MegaCal 格式处理,直接换成 $mar = new MegaCommsManager() 就可以了
    $mgr = new BloggsCommsManager();
    print $mgr->getHeaderText();
    print $mgr->getApptEncoder()->encode();
    print $mgr->getFooterText();

    8、结果:

    BloggsCal header
    Appointment data encoded in BloggsCal format
    BloggsCal footer

     

    总结:

    1、使用工厂方法模式,如果需要新增一种格式处理,就不需要修改原有的工厂类了,只需要为这些抽象类实现新的子类即可。这样整个工厂和产品体系其实都没有修改的变化,而只是扩展的变化,这就符合了“开放-封闭原则”。
    2、工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现,选择判断的问题还是存在的,也就是说,工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行。你想要加功能,本来修改工厂类,而现在是修改客户端。
    3、工厂方法模式的缺点是由于每加一个产品,就需要加一个产品工厂的类,增加了额外的开发量。

  • 相关阅读:
    中南大学ACM12月月赛第二场热身赛解题报告
    中南大学ACM12月月赛第二场热身赛在本周日(2011年11月20日)举行
    IPv4 and IPv6
    Java and IPV6
    IPv6 and Java
    poj3385
    poj3390
    poj3226
    poj3767
    poj3497
  • 原文地址:https://www.cnblogs.com/woods1815/p/12546032.html
Copyright © 2020-2023  润新知