Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 构建器模式:为什么导演要构建对象?_Oop_Design Patterns_Ooad_Builder Pattern - Fatal编程技术网

Oop 构建器模式:为什么导演要构建对象?

Oop 构建器模式:为什么导演要构建对象?,oop,design-patterns,ooad,builder-pattern,Oop,Design Patterns,Ooad,Builder Pattern,我正在学习英语 在上面的链接(Java示例)中,我注意到构建器提供了构造多个组件的接口。在调用它们的同时,我们还调用getProduct() 我不明白的是,为什么导演需要一个接一个地调用所有这些组件构造方法,并最终得到结果 /** "Director" */ class Waiter { private PizzaBuilder pizzaBuilder; public void setPizzaBuilder(PizzaBuilder pb) { pizzaBuilde

我正在学习英语

在上面的链接(Java示例)中,我注意到构建器提供了构造多个组件的接口。在调用它们的同时,我们还调用getProduct()

我不明白的是,为什么导演需要一个接一个地调用所有这些组件构造方法,并最终得到结果

     /** "Director" */
 class Waiter {
    private PizzaBuilder pizzaBuilder;


public void setPizzaBuilder(PizzaBuilder pb) { pizzaBuilder = pb; }
public Pizza getPizza() { return pizzaBuilder.getPizza(); }

public void constructPizza() {
   pizzaBuilder.createNewPizzaProduct(); 
   pizzaBuilder.buildDough(); // construct component 1
   pizzaBuilder.buildSauce(); // construct component 2
   pizzaBuilder.buildTopping();  // construct component 3
}
}

为什么我们不在ConcreteBuilder类it self中而不是在Director中包含用于构造组件1、2、3的代码,并实际上消除Director层呢

我理解上述方法可能会将构建器模式转变为其他模式,但我不明白为什么主管会一步一步地完成这项工作。有什么好处?如果有多个控制器,就会有重复的代码,对吗?我可能不理解执行生成器模式背后的动机

更新:在创建更大的复杂对象时,生成器模式是否侧重于提供可自定义的组件选择?否则,到目前为止,我不认为引入一个额外的层,Director有什么意义


即使是这样,通过动态定制组件来实现同样的功能,Decorator模式也可能是一个更好的主意。在某个地方,我忽略了建筑商背后的要点(

我认为您误解了构建器模式。您是说构建不同组件的过程可以合并到一个方法中,这是事实,但不是此对象创建设计模式的关键。请再次查看此代码:

class Waiter {
    private PizzaBuilder pizzaBuilder;

    public void setPizzaBuilder(PizzaBuilder pb) { pizzaBuilder = pb; }
    public Pizza getPizza() { return pizzaBuilder.getPizza(); }

    public void constructPizza() {
        pizzaBuilder.createNewPizzaProduct();
        pizzaBuilder.buildDough();
        pizzaBuilder.buildSauce();
        pizzaBuilder.buildTopping();
    }
}
请注意,
服务员
只与
比萨制作者
一起工作,他不知道这是
比萨制作者
还是
夏威夷比萨制作者
,这是此模式的目标。在另一段代码中:

class BuilderExample {
    public static void main(String[] args) {
        Waiter waiter = new Waiter();
        PizzaBuilder hawaiianPizzaBuilder = new HawaiianPizzaBuilder();
        PizzaBuilder spicyPizzaBuilder = new SpicyPizzaBuilder();

        waiter.setPizzaBuilder( hawaiianPizzaBuilder );
        waiter.constructPizza();

        Pizza pizza = waiter.getPizza();

        waiter.setPizzaBuilder( spicyPizzaBuilder );
        waiter.constructPizza();

        Pizza anotherPizza = waiter.getPizza();
    }
}

你可以看到它是如何工作的。一个
服务员
被创建并首先传递给一个
HawaiianPizzaBuilder
,然后是一个
SpicyPizzaBuilder
,同样的
服务员
的例子,你可以构建一个比萨饼,并向他索要,他会提供正确的比萨饼。希望我已经解释过自己,并且这个评论对你有所帮助祝你好运

Director类的目的是封装用于创建对象的算法,即将构造逻辑的代码与实际构成对象的部分的代码分开。如果没有Director类,您的Builder类将更庞大,模块化程度更低,因此更难维护,可重用性也更低

你所指的是相当简单的。对于复杂的对象,构造机制通常要复杂得多,并且主管不一定按照定义的顺序逐个调用生成器方法。例如,考虑<代码>蛋糕类:它可能有部分<代码>巧克力层>代码>代码> > CurMeleS/<代码>和<代码> Strawberry < /代码>。构建器将按此特定顺序定义用于构建这三个部分的三个方法,但是Director类中的
constructCake()
方法可能如下所示:

public void constructCake() {
   CakeBuilder.createNewCakeProduct(); 
   CakeBuilder.buildChocolateLayer(); 
   CakeBuilder.buildCreamLayer(); 
   CakeBuilder.buildChocolateLayer(); // 2nd call of the same Builder method
   int totalStrawberries = 3 + new Random().nextInt(2);
   for (int i = 1; i <= totalStrawberries; i++) 
      CakeBuilder.buildStrawberry(); // put some strawberries on top
   // Please don't try this recipe at home! 
}
public-void-constructCake(){
createNewCakeProduct();
CakeBuilder.buildChocolateLayer();
CakeBuilder.buildCreamLayer();
CakeBuilder.buildChocolateLayer();//同一个生成器方法的第二次调用
int totalStrawberries=3+new Random().nextInt(2);

对于(inti=1;i我对构建器模式的解释:让我们假设我们有一个对象(产品),并且对象构造需要许多参数或组件(其他对象),现在更糟糕的是,可能不需要所有这些参数,因此这将导致我们要么创建具有不同参数的多个构造函数,要么在唯一的构造函数中引入许多逻辑语句,以选择该构造函数并拒绝该对象,而更糟的是,这些组件可能需要在ord中构建呃(按照特定的顺序)或者对它们进行一些业务规则检查,所有这些归结起来都是一个与参数(组件)紧密耦合且难以维护的复杂构造函数。解决方案是将此逻辑移动到一个具体的构建器中,这样我们就可以通过调用
ConcreteBuilder.BuildComponent1()获得我们的对象,ConcreteBuilder.BuildComponent2(),…,ConcreteBuilder.GetMeMyObject()
但这将使客户机代码与构建过程紧密结合,每个客户机现在都完全了解构建我们钟爱的对象所需的所有步骤,因此构建过程中的任何更改都将迫使我们修改所有客户机代码,为了解决这一问题,构建器模式引入了封装的控制器执行这些步骤,现在所有客户端都在控制器上调用Build()方法来构建对象。总而言之,控制器在那里,因此客户端代码不知道或与创建我们喜爱的对象所需的步骤紧密耦合,现在为什么这些
BuildComponent1(),BuildComponent2()
方法是用来解决构建器模式存在的问题的,我在一开始就提到了:我们现在可以在组件构建过程中强制执行顺序,我们还可以在这些方法中强制执行每个具体构建器特有的业务逻辑,我们甚至可以选择离开实现对于某些混凝土建筑商来说,这是一个空白,因为这仅仅是我们的最终目标(产品)不需要那个组件,我们现在已经将这个复杂的构建过程封装起来,远离了我们所钟爱的对象,他做得最好,而不必担心如何自己构建它。

导演不构建对象,建设者构建对象,它被称为产品。导演的存在有一个原因:因此e类对构造对象所需的步骤一无所知。所有这些都是关于平坦化i