建造者模式中的逻辑

6

最近我遇到了一个引起我的兴趣的建造者模式。

所以,我有一个EntityBuilder来构建一个名为Entity的实体,但它不会返回实体。以下是该方法的签名:

public void build();

相反,在build()方法内部,它将新创建的对象Entity传递给一个CacheImplementation实例进行存储。

注意:在构建器的构造函数中注入了CacheImpl

public void build(){
    //create new entity
    cacheImplementation.add(entity);
}

这是否听起来像是最佳实践?

稍后编辑 0

public interface EntityBuilder {

    void setProperty0(PropertyObject propertyObject0);
    void setProperty1(PropertyObject propertyObject1);
    void setProperty2(PropertyObject propertyObject2);
    //...

    void build();
}

public class EntityBuilderImpl implements EntityBuilder {
    
    PropertyObject propertyObject0;
    PropertyObject propertyObject1;
    PropertyObject propertyObject2;
    //...

    // setters for all properties
    @Override
    public void build(){
        //create new entity
        cacheImplementation.add(entity);
    }
}

生成器的使用方式如下:
public class EntityProcessor{
  private EntityBuilderFactory entityBuilderFactory;//initialized in constructor

  void process(EntityDetails entityDetails){
       EntityBuilder entityBuilder = this.entityBuilderFactory.getNewEntitytBuilder();
       //..
       // entityBuilder.set all properties from entityDetails
       entityBuilder.build();
  }
}

注意: cacheImpl实例仅将实体存储在一个List<>中,每N秒访问一次。
3个回答

3
这是最佳实践吗?
传统的builder模式不会在任何地方存储所创建的对象,它只是简单地返回它。
我可以想象一种变体,其中builder还具有实例控制的角色,以避免创建重复对象,并管理不可变对象的存储。
决定不返回实例可能是为了清楚地表明该方法具有副作用。如果该方法返回对象,则可能会误导认为它是没有副作用的传统构建器,而这里并非如此。
无论如何,所有这些都只是推测,因为我们没有看到使用这个东西的代码的其余部分以及它的实现和用法。我们没有足够的上下文来真正判断。
发明新模式没有错,但可以做得好或坏。

传统设计模式的变体听起来不错。我添加了一小段代码以展示我的意思。这足以判断吗? - VladLucian
不,还不够。更有趣的部分将是使用构建器和缓存。顺便说一下,将列表作为缓存听起来很奇怪。我期望的是一个映射表。 - janos
这不是一个列表,而是一个在N秒后被清空的集合,每次处理开始时都会被清空。我已经编辑了建造者的使用方式。 - VladLucian
还远远不够。实际上,我在想这里是否真的有建造者模式,或者你只是因为类名包含“builder”这个词而这样称呼它。例如,在接口中有设置属性的void方法,但是建造者模式通常具有流畅接口,其中setter返回构建器本身,允许链接。 - janos
你是对的。命名可能会让我误解。每个所谓的“Builder”接口都只有void方法,它们不返回builder本身。build方法只是调用实体的构造函数来创建实体。 - VladLucian

0

我在JCodeModel类中看到了类似的void build()方法。正如您所看到的,它由于其管理的资源而抛出IOException异常:

public void build(File destDir,
                  PrintStream status)
           throws IOException

你基本上是要求它为你执行操作,如果没有错误出现,你就可以继续工作流程。

@Vlad,如果您删除“谢谢”的评论会更好。对于有帮助的答案,网站政策是投票支持它们。让我们保持干净。我稍后也会删除此评论。 - ekostadinov

0
通常情况下,构建器是按以下方式使用的: 某些类将使用构建器来创建类。简单明了。

enter image description here


现在你有了额外的复杂性 - 缓存。您可以将缓存放置在Builder内部或处理器内部的更高级别。

将缓存管理放入构建器中的影响是什么:

  • 构建器不再具有单一职责。
  • 它的工作方式与您最初预期的不同
  • 您无法创建对象而不将其放入缓存中

如果将缓存管理放入单独的类中,则不会出现这些问题。


我认为这不是一个可怕的解决方案,但它肯定会降低您代码的可维护性。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接