我最近一直在与一个研究小组一起研究设计模式,并且已经认识到构建器模式对于创建由许多(可能是可选的)部分组成的复杂对象非常有用.
但是,建造者做得太多了吗?假设我们有一个具有许多不同对象组合的类,是否有另一种模式可能更适合它而不是制作数十种不同的构建器?是否可以通过不制作完全特定的构建器来减少所需的构建器数量?
我的研究小组和我不断回来的例子是汽车制造商,例如在汽车公司的网站上.任何汽车公司都有几十辆汽车,每辆汽车都有许多不同的功能,颜色,附加功能等.我理解它的方式,你的构建器应该特定于你正在制作的对象,所以在这个例子中应用构建器模式将产生数百个看起来像"RedSUVWithSunroofBuilder","BlueSUVWithSunroofBuilder","RedSUVBuilder"等的构建器.
是否有任何理由使用构建器模式,我无法传递其中一些值以减少我需要创建的构建器数量?例如,不是使用RedSUVWithSunroofBuilder或BlueSUVWithSunroofBuilder,它仍然适合构建模式来执行SUVWithSunroofBuilder("Red")和SUVWithSunroofBuilder("Blue"),还是更适合不同的模式?
我正在尝试使用Builder为我正在处理的项目构建一个xml文档.xml有一个非常严格的结构,所以我不能改变它.我遇到的问题是这个.我正在尝试将子项添加到节点中子项"linking-phrase-list"
的名称必须是"linking-phrase".所以为了做到这一点,我会打电话:
test = Builder.new do |xml|
xml.map {
xml.send(:"linking-phrase-list") {
xml.linking-phrase("label" => "edge1", "id" => "idedge1")
}
}
end
Run Code Online (Sandbox Code Playgroud)
当然,ruby将此解释为(xml.linking)-phrase()完全不符合我的要求.所以我需要知道是否有某种方法我可以说服ruby是一个函数调用而不是两个?那或告诉nokogiri我的意思是当我不使用该功能时.
我正在尝试将Ruby 1.8应用程序升级到1.9并在此处遇到一些障碍.在Ruby 1.8.7中,我可以将一个块传递给Builder 3.0.0并按预期调用它:
1.8.7 :003 > @builder = Builder::XmlMarkup.new
1.8.7 :004 > block = lambda { puts "foo" }
1.8.7 :005 > @builder.tag(&block)
foo
Run Code Online (Sandbox Code Playgroud)
但在1.9中,我收到此错误:
1.9.3p0 :002 > @builder = Builder::XmlMarkup.new
1.9.3p0 :003 > block = lambda { puts "foo" }
1.9.3p0 :004 > @builder.content(&block)
ArgumentError: wrong number of arguments (1 for 0)
from (irb):3:in `block in irb_binding'
from /Users/dev/.bundle/ruby/1.9.1/gems/builder-3.0.0/lib/builder/xmlbase.rb:155:in `call'
...
Run Code Online (Sandbox Code Playgroud)
并重写为一个stabby lambda(这只是语法糖,对吗?)没有帮助:
1.9.3p0 :006 > block = -> { puts "foo" }
1.9.3p0 :007 > @builder.content(&block)
ArgumentError: …Run Code Online (Sandbox Code Playgroud) 我必须使用Recursive Descendent Parser Builder构建表达式.
这是我的语法:
----RULES----
<cond> ? <termb> [OR <termb>]*
<termb>?<factb>[AND <factb>]*
<factb>?<expr> RELOP <expr> | NOT <factb> | OPAR <cond> CPAR
<expr> ? [PLUS | MINUS] <term> [(PLUS <term>) | (MINUS <term>)]*
<term> ? <termp> [(MULT <termp>) | (DIV <termp>) | (REM <termp>)]*
<termp> ? <fact> [POWER <fact>]*
<fact> ? ID | NUM | OPAR1 <expr> CPAR1
----TERMINALS----
ID ? ("A" | ... | "Z" | "a" | ...| "z") [("A"| ... | "Z" | "a" | ...| …Run Code Online (Sandbox Code Playgroud) 在研究构建器模式时,标准模式如下:
new SandwichBuilder().salami().pastrami().cat().build();
Run Code Online (Sandbox Code Playgroud)
哪里.salami(), .pastrami(), and .cat()的回报SandwichBuilders,并.build()返回Sandwich.
相反,它被认为是不好的风格,使用以下约定?
new Sandwich().salami().pastrami().cat();
Run Code Online (Sandbox Code Playgroud)
在哪里直接.salami(), .pastrami(), and .cat()返回Sandwich,前面看似不必要的并发症?
我正在尝试实现构建器模式以生成Apache XmlBeans对象.
我为我的所有类生成了构建器,它继承自:
public abstract class Builder<T extends XmlObject> {
protected T xmlObject;
@SuppressWarnings("unchecked")
public T build() {
return (T) xmlObject.copy();
}
}
Run Code Online (Sandbox Code Playgroud)
然后我创建了几个这样的构建器(Time2Save继承自XmlObject):
public class Time2SaveBuilder extends Builder<Time2Save> {
public Time2SaveBuilder(int amount, String unit) {
xmlObject = Time2Save.Factory.newInstance();
xmlObject.setUnit(unit);
xmlObject.setValue(amount);
}
}
Run Code Online (Sandbox Code Playgroud)
它工作得很好.但我遇到的问题是我不喜欢在每个构建器中实例化xmlObject的重复,如果可能的话,我宁愿在抽象的Builder类中进行.所以我尝试将此构造函数添加到Builder类:
@SuppressWarnings("unchecked")
public Builder() {
xmlObject = (T) T.Factory.newInstance();
}
Run Code Online (Sandbox Code Playgroud)
并留下这样的实现:
public class Time2SaveBuilder extends Builder<Time2Save> {
public Time2SaveBuilder(int amount, String unit) {
xmlObject.setUnit(unit);
xmlObject.setValue(amount);
}
}
Run Code Online (Sandbox Code Playgroud)
问题是我收到以下错误:
Exception in thread "main" java.lang.ClassCastException:
org.apache.xmlbeans.impl.values.XmlAnyTypeImpl cannot be cast …Run Code Online (Sandbox Code Playgroud) 我想将另一种格式的对象转换为protobuf,知道protobuf的描述符.对常规字段甚至嵌套字段都很容易.但是,我遇到了重复领域的问题.
message Foo {
optional MsgA a = 1;
repeated MsgB b = 2;
}
Run Code Online (Sandbox Code Playgroud)
对于"MsgA a",代码bld.getFieldBuilder(field)有效:
Foo.Builder bld = Foo.newBuilder();
Descriptors.Descriptor msgDesc = Foo.getDescriptor();
List<Descriptors.FieldDescriptor> fields = msgDesc.getFields();
for (Descriptors.FieldDescriptor field : fields) {
Message.Builder subBld = bld.getFieldBuilder(field);
// set foreign value xyz using subBld
// subBld.setFleld(subfield1, xyz);
}
Run Code Online (Sandbox Code Playgroud)
但对于"MsgB b",相同的代码抛出"UnsupportedOperationException:getFieldBuilder()在非Message类型上调用."
我理解重复字段是一个列表,我可以分别设置每个字段.但是,我如何首先获得建筑商?是否有一种干净简单的方法来做类似的事情?
感谢您的任何意见.
如果我使用构建器模式来配置新对象,我可能有两个类Game和HockeyGame(如下所示).当我想创建一个新的时HockeyGame,我得到它的构建器并开始调用方法来根据需要配置对象.
我遇到的问题显示在main函数中.一旦我从超类中调用一个方法,它就作为一个intance返回Game.Builder,我不能再调用子类中的任何方法.
处理这个问题的最佳方法是什么?
Main.java
class Main {
public static void main(String[] args){
HockeyGame hg = new HockeyGame.Builder()
.setScore(5)
.setTimeLimit(3600)
//--------------------------------------------------------------------
.setIceTemperature(-5) // Error! Cannot call setIceTempurature() on
// an instance of Game.Builder
//--------------------------------------------------------------------
.build();
}
}
Run Code Online (Sandbox Code Playgroud)
Game.java
public class Game{
int score;
int timeLimit;
public Game(int score, int timeLimit) {
this.score = score;
this.timeLimit = timeLimit;
}
public static class Builder {
int score;
int timeLimit;
public Builder setScore(int score) {
this.score …Run Code Online (Sandbox Code Playgroud) 我正在使用ListView.buildler将Widget分层为垂直滚动。这种方法的唯一问题是,当滚动到达我内容的结尾时。它会自动回到顶部。目前我有这个:
new ListView.builder(
scrollDirection: Axis.vertical,
key: new Key(randomString(20)),
reverse: false,
primary: true,
itemBuilder: (BuildContext context, int index) {
return new Column(
children: <Widget>[
new Padding(
padding: _bookPadding,
child: new Container(
width: 106.0,
height: 162.0,
child: new FadeInImage(
placeholder: new AssetImage('assets/loading.gif'),
image: this.book.cover)
),
),
const Divider(),
new Padding(
padding: _bookPadding,
child: new Text(
this.book.bookName,
style: getTextStyle())),
const Divider(),
new Padding(
padding: _bookPadding,
child: new Text(
'By ' + this.book.author,
style: getTextStyle(), ),
),
....
Run Code Online (Sandbox Code Playgroud)
到达终点时,是否可以将ListView.builder设置为no-wrap?
我有扩展抽象类的类,我不想把它@Builder放在所有子类之上.
有没有办法@Builder为抽象类实现Lombok ?