在构建器模式下,哪种“产品”可以共享相同的“构建器”和相同的“导演”?

时间:2019-06-09 20:58:14

标签: design-patterns builder

Gamma等人的

Design Patterns描述了Builder模式:

  

意图

     

将复杂对象的构造与其表示分开,这样就可以创建相同的构造过程   不同的表示形式

     

动机

     

enter image description here

     

结构

     

enter image description here

     

实施

     

为什么没有产品的抽象类?通常情况下,生产的产品   混凝土建筑商之间的差异很大,以至于   为不同的产品提供共同的父级课程几乎无济于事。在   在RTF示例中,ASCIIText和TextWidget对象不太可能   有一个通用的接口,也不需要一个。因为客户通常   为导演配置适当的具体构建者,客户端位于   可以知道正在使用哪些Builder具体子类并可以处理的位置   其产品相应。

在哪种Product(例如,动机示例中的ASCIItextTexTextTextWidget)可以共享相同的Builder上有条件吗基类和相同的Director,因为它们不共享公共父类?

1 个答案:

答案 0 :(得分:1)

您的问题是有道理的,但实际上我认为为Product类定义基类是否真正取决于您要实现构建器的方式。

我认为抽象生成器类的默认实现可以在要构建产品的基类上知道,但实际上没有义务。

例如,在引用的示例中,它可以仅将方法返回的String附加到要构建的对象的状态String上。在这种情况下,为什么要定义一个抽象的Product类?我们不需要它。


即使对于用于抽象构建器类中实现的任何方法的更复杂的构建对象,您也可以在抽象构建器类的状态下存储要构建的对象的每个部分,并使用这些部分而无需任何基类来实现。产品类别。

例如,这是一个没有产品基本类的实现

客户:

Builder builder = new ParadiseWorldBuilder();
World world = director.build(builder);

导演:

World build(){    
    builder.buildLands(...); // defined in abstract class for example
    builder.buildPeople(...);
    builder.buildAnimals(...);
    return builder.getWorld();
 }

抽象生成器类:

private List<Land> lands = ...;
List<Land> getLands(){return lands;}

void buildLands(){
    for(....){ 
        lands.add(...);
    }
}

具体生成器类:

World getWorld(){
  return new ParadiseWorld(getLands(), ...); // use the state of the abstract class
}

现在仅是向您展示这是一个选择问题,我将更改示例的实现,并为Product类(此处为World)依赖一个公共基类。

产品基本类的实现

客户:

Builder builder = new ParadiseWorldBuilder();
World world = director.build(builder);

导演:

World build(){    
    builder.buildLands(...); // defined in abstract class for example
    builder.buildPeople(...);
    builder.buildAnimals(...);
    return  builder.getWorld();
 }

抽象生成器类:

protected World world = createEmptyWorld(); // abstract method
void buildLands(){
    for(....){
        world.addLands(...); 
    }
}
World getWorld(){
  return world;
}

抽象产品类别:

public World{
   void addLands(...){
        // ...
   }
}

产品类别:

public ParadiseWorld extends World{
     //...
}

具体生成器类:

World createEmptyWorld(){
   return new ParadiseWorld();
}

在此示例中,IHMO没有Product的基类的方法要好得多。它减少了制造商与产品之间的耦合。此外,这里的层次结构看起来很肤浅,并且在构建器和要为每个内置零件创建的产品之间进行委派看起来很麻烦,并防止了Product类的不变性(这可能是合乎需要的)。