我正在阅读Joshua Bloch的"Effective Java",在第2项中,他提到了在构造函数中处理几个参数时使用Builder模式的优点.一切都很好,直到我看到传统构造函数和这个模式之间的多个var-args差异.所以,我有一些疑问:
我在代码中没有使用var-args,但是我知道它们的用途.我仍然无法理解上述陈述背后的原因.任何帮助,将不胜感激.
我最近开始在我的一个项目中使用 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) 我用@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) 我最近一直在与一个研究小组一起研究设计模式,并且已经认识到构建器模式对于创建由许多(可能是可选的)部分组成的复杂对象非常有用.
但是,建造者做得太多了吗?假设我们有一个具有许多不同对象组合的类,是否有另一种模式可能更适合它而不是制作数十种不同的构建器?是否可以通过不制作完全特定的构建器来减少所需的构建器数量?
我的研究小组和我不断回来的例子是汽车制造商,例如在汽车公司的网站上.任何汽车公司都有几十辆汽车,每辆汽车都有许多不同的功能,颜色,附加功能等.我理解它的方式,你的构建器应该特定于你正在制作的对象,所以在这个例子中应用构建器模式将产生数百个看起来像"RedSUVWithSunroofBuilder","BlueSUVWithSunroofBuilder","RedSUVBuilder"等的构建器.
是否有任何理由使用构建器模式,我无法传递其中一些值以减少我需要创建的构建器数量?例如,不是使用RedSUVWithSunroofBuilder或BlueSUVWithSunroofBuilder,它仍然适合构建模式来执行SUVWithSunroofBuilder("Red")和SUVWithSunroofBuilder("Blue"),还是更适合不同的模式?
我正在考虑在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++中的常见做法吗?如果不是,为什么不呢?
我正在开发一种类似于铁路票务的解决方案.
背景:泰米尔纳德邦有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
我有一个具有多个构造函数的类。每个代表不同的用例。
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
我正在使用构建器模式为控制器生成视图模型,当我尝试对控制器进行单元测试时,我发现自己无法这样做.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) 首先,我对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) 我总是使用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)
这个问题是片段必须有一个默认的构造函数,所以这不起作用.
有没有"正确"的方法来实现这一目标?
builder-pattern ×10
java ×6
builder ×2
oop ×2
android ×1
asp.net-mvc ×1
c++ ×1
class-design ×1
decorator ×1
lombok ×1
moq ×1
polymorphism ×1
unit-testing ×1