需要有关Creational模式的建议(Builder)

时间:2014-07-04 12:15:46

标签: php design-patterns builder

对于我在Stackoverflow上的第一篇文章,我想询问一些关于我应该使用哪种模式(以及如何正确使用它)的建议。

(不要犹豫,问我精确,英语不是我的母语)

我正在开发的程序是关于组装多个表单信息(有关广告活动的信息),结构应该是:

  • 广告横幅的格式,包含尺寸,格式名称等属性......
  • models(可选)如果存在多种类型的广告产品,包含格式
  • 区(可选),如果广告系列有多个区域(广告区域),包含格式(如果指定则最终是模型)
  • 发布商,重新组合格式(按区/模型,如果指定)

总结一下,我应该有这4种可能的联想:

  • 出版商/格式,
  • 出版商/型号/格式,
  • 出版商/地区/格式,
  • 出版商/地区/型号/格式

由于关联的几种可能性,我的想法引导我走向构建器模式,但我对此并不熟悉,而且我不确定如何实现它。

我的ConcreteBuilders应该是4种可能的关联(比如用于发布者/格式的FormatBuilder或用于发布者/区域/模型/格式的DistrictModeleBuilder),我的产品是格式,模型,区域,发布者吗?

Director类是代表表单还是表单属于客户端?

提前感谢您的启示!

2 个答案:

答案 0 :(得分:0)

我不认为你在谈论Builder模式。 Builder模式用于处理接受许多可选参数的函数。您可能正在考虑工厂模式。

但对我来说,听起来你想要应用一个设计模式。在盲目地应用别人的解决方案之前,我会认真思考问题是什么。

编辑:好的,我想我误会了。如果您确定这些是唯一可能的组合,您可以为每个组合创建子类。但它听起来像Builder是最灵活的解决方案。构建器应该是将相应组件添加到窗体的方法,例如:

public class Form {
  ...
  public Form addModel() {
    this.models.push(new Model());
    return this;
  }
}

我不知道您的产品是格式,型号,区域和出版商是什么意思。这听起来不像我的产品。我不知道导演或客户是什么,你没有在其他地方提到过。

答案 1 :(得分:0)

我最终决定实现另一种构建器模式(在此处找到:http://www.javacodegeeks.com/2013/01/the-builder-pattern-in-practice.html):使用内部类作为构建器以保持有效状态。

我提醒您,装配顺序是:发布商 - >区 - >型号 - >格式(区域和模型可选)

因为我的英语不太好,所以我更喜欢直接发布代码:

class Publisher{
// ATTRIBUTES
private $name;
private $districts;
private $models;
private $formats;

// GETTERS
...

// METHODES
private function __construct($builder) {
    $this->name = $builder->name;
    $this->districts = $builder->districts;
    $this->models = $builder->models;
    $this->formats = $builder->formats;
}


// BUILDER
public static class PublisherBuilder {
    private $name;
    private $districts; // catchment area
    private $models; // can be things like different car models
    private $formats;

    public function __construct($pName) {
        $this->name = $pName;
        $this->districts = array();
        $this->models = array();
        $this->formats = array();
    }

    public function setDistricts($pDistricts) { // the param is JSON-formatted      
        // If no Model declared by the user in the form
        // Loop over districts
            array_push($this->districts, new District.DistrictBuilder("name of the current district").setFormats("data about formats contained in the current district").build());

        // If several Models
        // Loop over districts
            array_push($this->districts, new District.DistrictBuilder("name of the current district").setModels("data about models contained in the current district").build());

        return $this;
    }

    public function setModels($pModels) {   // the param is JSON-formatted
        // Loop over models
            array_push($this->models, new Model.ModelBuilder("name of the current model").setFormats("data about formats contained in the current model").build());

        return $this;
    }

    public function setFormats($pFormats) { // the param is JSON-formatted
        // Loop over formats
            array_push($this->formats, new Format("data about the current format"));

        return $this;
    }

    public function build() {
        return new Publisher($this);
    }
} // end of inner class PublisherBuilder

} //发布商类的结尾

当然,District和Model类具有相同的结构,并且具有自己的构建器内部类(Format类是"普通"类)。

客户端只需要在表单中的数据中循环发布者并调用Publisher.PublisherBuilder("有关当前发布者的数据)。

使用此解决方案,似乎在保持Builder模式的灵活性的同时消除了一些困难。

不要对此实施做出任何(建设性的)评论:)