【面向对象的PHP】之模式:抽象工厂方法

抽象工厂方法模式

在工厂方法模式中,咱们经过中间件的方式,造成了如下格式的分离:segmentfault

使用者
  ↓
建立者
  ↓
具体产品设计模式

问题

这样,咱们不管怎样修正具体产品,都不会影响使用者。如今,咱们能够作出来一群小工厂,他们有各自的产品,但造成了模式层面的重复,那么咱们如何化解这种重复呢?优化

在本篇,将经过抽象工厂方法模式——抽象 - 工厂方法 - 模式,来完成对小公司的整合,最初设计(母公司 - 子公司):编码

抽象 建立者-产品 的UML

接下来,咱们要经过抽象类解决多个业务并行的问题。spa

如今,咱们要写一个PIM的数据格式解码器 - Personal Information Manage,会产生预定(Appt)、待办事宜(Ttd)、联系人(Contact)三种数据格式。设计

咱们就能够设计出下列UML:code

具体 抽象工厂方法模型的UML

经过CommsManager抽象类,咱们能够生成具体的全部子公司(子类)。orm

但事实上,这也必定程度的显示了为何有些公司作很差某些行业,一旦他哪怕是间接介入子公司,也会影响子公司的血统(这个想法我最先接触于吴军先生的《浪潮之巅》)。面向对象设计模式

实现

abstract class CommsManager {
    abstract function getHeaderText();
    abstract function getApptEncoder();
    abstract function getTtdEncoder();
    abstract function getConteactEncoder();
    abstract function getFootText();
}

class BloggsCommsManager extends CommsManager {
    function getHeaderText()
    {
        return "BloggsCal header\n";
    }

    function getApptEncoder()
    {
        return new BloggsApptEncoder();
    }

    function getTtdEncoder()
    {
        return new BloggsTtdEncoder();
    }

    function getConteactEncoder()
    {
        return new BloggsConteactEncoder();
    }

    function getFootText()
    {
        return "BloggsCal footer\n";
    }
}

在这里,咱们用了工厂模式(目录在最后)。设计模式之间常常这样协做,一个模式的建立,能够成为另外一个模式的一部分中间件

这方面的想法就是源于模式自己:他是通过无数次同条件下,实践得出的最优解——将来若是有更好的条件,这个最优解就仍然有优化的空间 / 或者没有存在的。

结果

模式的意义:

  1. 完全的将 业务需求 与 实现细节 分割,如今,咱们能够随意的改动编码格式,而不用担忧业务层产生BUG;

  2. 经过强制整合,全部Blogger格式的内容,都经过Blogger建立者类来实现,不会出错;

  3. 固然,添加新产品则是使人苦恼的,为了建立新产品的具体实现,咱们必须修改抽象建立者、和他的每个具体实现。

PHP目前尚未强制规定 方法的返回类型,这产生了一些额外的灵活性。(强制规定返回类型,通常为JAVA之类的 强类型-面向对象-语言)

abstract class CommsManager {
    const APPT    = 1;
    const TTD     = 2;
    const CONTACT = 3;
    abstract function getHeaderText();
    abstract function mark( $flag_int );
    abstract function getFootText();
}

class BloggsCommsManager extends CommsManager {
    function getHeaderText()
    {
        return "BloggsCal header\n";
    }

    function mark( $flag_int )
    {
        switch ($flag_int) {
            case self::APPT:
                return new BloggsApptEncoder();
            case self::TTD:
                return new BloggsTtdEncoder();
            case self::CONTACT:
                return new BloggsConteactEncoder();
        }
    }

    function getFootText()
    {
        return "BloggsCal footer\n";
    }
}

类的接口变得更加紧凑,但也有必定的代价,咱们放弃了详细的数据格式方法,而是将其中心化了,客户没法确认是否实现了须要的具体产品。
因此,也要慎用~

当你的项目中,产品愈来愈多,建立者的数量也随之臃肿,下一篇将介绍抽象工厂方法的变体:原型模式,这种模式能够减小必须建立的类。

面向对象设计模式 - 目录

相关文章
相关标签/搜索