标签: builder-pattern

生成器模式多个varargs

我正在阅读Joshua Bloch的"Effective Java",在第2项中,他提到了在构造函数中处理几个参数时使用Builder模式的优点.一切都很好,直到我看到传统构造函数和这个模式之间的多个var-args差异.所以,我有一些疑问:

  1. 构建器模式如何允许多个var-args?
  2. 为什么传统的构造函数只允许一个var-arg?(可能是因为如果存在多个var-args会导致歧义,当两者的定义数据类型相同时,但我不确定这是否是正确的原因.)

我在代码中没有使用var-args,但是我知道它们的用途.我仍然无法理解上述陈述背后的原因.任何帮助,将不胜感激.

java variadic-functions builder-pattern effective-java

4
推荐指数
1
解决办法
537
查看次数

通过在编译时进行验证来改进构建器模式

我最近开始在我的一个项目中使用 Builder 模式,并且尝试在我的 Builder 类上添加某种验证。我假设我们无法在编译时执行此操作,因此这就是我在运行时执行此验证的原因。但也许我错了,这就是我试图看看是否可以在编译时做到这一点。

传统建造者模式

public final class RequestKey {

    private final Long userid;
    private final String deviceid;
    private final String flowid;
    private final int clientid;
    private final long timeout;
    private final boolean abcFlag;
    private final boolean defFlag;
    private final Map<String, String> baseMap;

    private RequestKey(Builder builder) {
        this.userid = builder.userid;
        this.deviceid = builder.deviceid;
        this.flowid = builder.flowid;
        this.clientid = builder.clientid;
        this.abcFlag = builder.abcFlag;
        this.defFlag = builder.defFlag;
        this.baseMap = builder.baseMap.build();
        this.timeout = builder.timeout;
    }

    public static class Builder {
        protected final …
Run Code Online (Sandbox Code Playgroud)

java design-patterns builder builder-pattern

4
推荐指数
1
解决办法
2703
查看次数

lombok - 多个镜头中的@Builder模式

我用@Builder龙目岛的项目,所以我认为有这样的例子:

@Builder
public class Client {

    private @Getter @Setter Integer id;
    private @Getter @Setter String name;

}
Run Code Online (Sandbox Code Playgroud)

这相当于:

public class Client {

    private @Getter @Setter Integer id;
    private @Getter @Setter String name;

    public static class Builder {

        private Integer id;
        private String name;

        private Builder() {
        }

        public Builder id(final Integer value) {
            this.id = value;
            return this;
        }

        public Builder name(final String value) {
            this.name = value;
            return this;
        }

        public Client build() {
            return …
Run Code Online (Sandbox Code Playgroud)

java builder-pattern lombok

4
推荐指数
2
解决办法
1271
查看次数

建造者模式可能做得太多了吗?

我最近一直在与一个研究小组一起研究设计模式,并且已经认识到构建器模式对于创建由许多(可能是可选的)部分组成的复杂对象非常有用.

但是,建造者做得太多了吗?假设我们有一个具有许多不同对象组合的类,是否有另一种模式可能更适合它而不是制作数十种不同的构建器?是否可以通过不制作完全特定的构建器来减少所需的构建器数量?

我的研究小组和我不断回来的例子是汽车制造商,例如在汽车公司的网站上.任何汽车公司都有几十辆汽车,每辆汽车都有许多不同的功能,颜色,附加功能等.我理解它的方式,你的构建器应该特定于你正在制作的对象,所以在这个例子中应用构建器模式将产生数百个看起来像"RedSUVWithSunroofBuilder","BlueSUVWithSunroofBuilder","RedSUVBuilder"等的构建器.

是否有任何理由使用构建器模式,我无法传递其中一些值以减少我需要创建的构建器数量?例如,不是使用RedSUVWithSunroofBuilder或BlueSUVWithSunroofBuilder,它仍然适合构建模式来执行SUVWithSunroofBuilder("Red")和SUVWithSunroofBuilder("Blue"),还是更适合不同的模式?

java design-patterns class-design builder builder-pattern

3
推荐指数
2
解决办法
2741
查看次数

在C++中使用构建器模式时,是否建议setter返回对构建器对象的引用?

我正在考虑在C++单元测试中使用构建器模式,以简化正在测试的代码的输入数据的创建.

在Java中,常见的习惯用法似乎是让构建器类的setter返回(引用)构建器对象本身,以便可以将多个setter链接在一行中.E. g.构建器类可以像这样定义:

// class builder 
public class Builder
{
  private Part1 part1;
  private Part2 part2;
  public Builder withPart1(Part1 p1);
  public Builder withPart2(Part2 p2);
};
Run Code Online (Sandbox Code Playgroud)

然后像这样使用:

Builder b;
Part1 p1;
Part2 p2;
b.withPart1(p1).withPart2(p2);
Run Code Online (Sandbox Code Playgroud)

通过让setter返回对构建器对象的引用,可以在C++中实现相同的效果.但是,我无法在网上找到任何这方面的例子.这种"链接"是C++中的常见做法吗?如果不是,为什么不呢?

c++ builder-pattern

3
推荐指数
1
解决办法
2277
查看次数

哪种设计模式可用于铁路票价计算?

我正在开发一种类似于铁路票务的解决方案.

背景:泰米尔纳德邦有18个火车站.乘客需要一张票.对于最多5站的旅程,票价是10卢比.在5个车站之后,每5个车站将收取5卢比的额外费用.对于完整的拉伸旅程,即从第1站到最后一站,票价是卢比.20.

例如

Input 1 : StationFrom - Guindy, StationTo - Kadambakkam
Output 1 : Print ticket. i.e. StationFrom : Guindy, StationTo : Kadambakkam, Total Stops : 3, Total Fare : 10

Input 2 : StationFrom - Guindy , StationTo - Chennai Fort
Output 2 : Print ticket. i.e. StationFrom : Guindy, StationTo : Chennai Fort, Total Stops : 8, Total Fare :15
Run Code Online (Sandbox Code Playgroud)

将来,可以添加更多关于票价计算的业务规则.

问题是,哪些设计模式在票价计算中是正确的选择?

oop design-patterns decorator strategy-pattern builder-pattern

3
推荐指数
1
解决办法
1121
查看次数

除了构造函数重载java之外的最佳实践/设计模式

我有一个具有多个构造函数的类。每个代表不同的用例。

public class ABC {
  public ABC(int x) {
  ...
  }
  public ABC(ArrayList<String> Stringarray) {
  ...
  }
  ..many more constructors..
}
Run Code Online (Sandbox Code Playgroud)

到目前为止,构造函数重载是干净的解决方案,直到我遇到了来自 java 编译器的相同擦除问题。例如,我想添加另一个最终具有相同擦除的构造函数,所以我只是选择包含一个默认参数来解决现在的问题,如下所示:

public ABC(ArrayList<String> stringArray) {
  …
}
public ABC(ArrayList<Integer> integerArray, boolean… sameErasureFlag) {
  …
}
Run Code Online (Sandbox Code Playgroud)

但是我有一种强烈的感觉,对于这个用例来说,有这么多构造函数可能不是一个好的设计模式。也许有一个更好的解决方案或最佳实践设计模式用于这种场景。我正在查找构建器模式,但不确定这是否正确/更好。有什么建议吗?

java design-patterns architectural-patterns constructor-overloading builder-pattern

3
推荐指数
1
解决办法
153
查看次数

单元测试与Moq的Builder模式

我正在使用构建器模式为控制器生成视图模型,当我尝试对控制器进行单元测试时,我发现自己无法这样做.Moq抱怨道.

不确定这是Moq限制还是我自己的限制和无知.

这就是我的控制器的样子:

public class OutletController : Controller
{
    private readonly IOutletViewModelBuilder _builder;

    public OutletController(IOutletViewModelBuilder builder)
    {
        this._builder = builder;
    }


    public ActionResult Edit(int id)
    {
        OutletViewModel viewModel = this._builder.WithOutlet(id).WithCountryList().Build();

        return View(viewModel);
    }
}
Run Code Online (Sandbox Code Playgroud)

我试图模拟IOutletViewModelBuilder对象,但这是我得到的:

[Test]
public void DummyTest()
{
    Mock<IOutletViewModelBuilder> mockBuilder = new Mock<IOutletViewModelBuilder>();
    // (1) // mockBuilder.Setup(m => m.WithOutlet(It.IsAny<int>())).Returns(mockBuilder.Object);
    // (2) //mockBuilder.Setup(m => m.WithOutlet(It.IsAny<int>())).Returns(mockBuilder);

    // (3) // mockBuilder.Setup(m => m.WithOutlet(It.IsAny<int>()).WithCountryList().Build()).Returns(new OutletViewModel());

    OutletController controller = new OutletController(mockBuilder.Object);
    ActionResult result = controller.Edit(1);

    Assert.IsTrue(true);
}
Run Code Online (Sandbox Code Playgroud)

(1)给我以下错误突出显示(mockBuilder.Object)

无法解析方法'返回(ViewModelBuilders.Builders.IOutletViewModelBuilder)',候选人是:

Moq.Language.Flow.IReturnsResult<ViewModelBuilders.Builders.IOutletViewModelBuilder> …
Run Code Online (Sandbox Code Playgroud)

asp.net-mvc unit-testing moq builder-pattern

2
推荐指数
1
解决办法
3017
查看次数

Java建造者样式 - 抽象建造者

首先,我对Java相对较新,所以我可能要求的是微不足道的,但我在这里或其他地方找不到答案.

为简单起见,我们假设我有以下类层次结构:

class Shape {
    protected Shape(double x, double y) {...}
}

class Circle extends Shape {
    public Circle(double radius) {...}
}

class Rectangle extends Shape {
    public Rectangle(double edge) {...}
}
Run Code Online (Sandbox Code Playgroud)

我想为每个形状使用构建器模式.所以我为每一个添加了Builders:

class Shape {
    protected static abstract class BuilderBase<T extends BuilderBase<T, S>, S extends Shape> {
        public T setLocation(double x, double y) {
            // ...
            return (T)this; // ? - is there a way to avoid this casting?
        }

        public abstract S build();
    }

    protected Shape(/*...*/) {/*...*/}
} …
Run Code Online (Sandbox Code Playgroud)

java oop polymorphism builder-pattern

2
推荐指数
1
解决办法
976
查看次数

Android - 使用Builder Pattern创建片段?

我总是使用newInstance()模式创建片段并将我的参数传递给片段.这适用于一个或两个参数.我现在正在创建一个包含大约10个参数的片段,并且所有这些参数都是可选的.

我正在考虑使用Builder模式,类似于AlertDialog的工作方式.但是,我不确定实现它的最佳方法是什么,或者它是否是一个好主意.

这是我在思考的一个例子,但有更多的变量.

public class MyFragment extends Fragment {
    private String name;

    private static class Builder {
        private String name;

        public Builder setName(String name) {
            this.name = name;
            return this;
        }

        public MyFragment build() {
            return new MyFragment(this);
        }
    }

    // NOT ALLOWED
    public MyFragment(Builder builder) {
        name = builder.name;
    }
    // Rest of the fragment...
}
Run Code Online (Sandbox Code Playgroud)

这个问题是片段必须有一个默认的构造函数,所以这不起作用.

有没有"正确"的方法来实现这一目标?

android builder-pattern android-fragments

2
推荐指数
1
解决办法
3308
查看次数