时间: 2020-09-4|tag: 40次围观|0 条评论

 

定义:

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

 

代码实例:

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

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\n";    }}

3、创建 MegaCal 格式处理类

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

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\n";    }    public function getApptEncoder()    {        // TODO: Implement getApptEncoder() method.        return new BloggsApptEncoder();    }    public function getFooterText()    {        // TODO: Implement getFooterText() method.        return "BloggsCal footer\n";    }}

6、创建 MegaCal 工厂类

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

7、调用:

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

8、结果:

BloggsCal headerAppointment data encoded in BloggsCal formatBloggsCal footer

 

总结:

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

 

文章转载于:https://www.cnblogs.com/woods1815/p/12546032.html

原著是一个有趣的人,若有侵权,请通知删除

本博客所有文章如无特别注明均为原创。
复制或转载请以超链接形式注明转自起风了,原文地址《PHP设计模式—工厂模式之工厂方法模式
   

还没有人抢沙发呢~