Java 模型对象设计
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16458092/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java Model Objects design
提问by Johan S
So I've been reading some Effective Java! And one of the most inspiring sections of the book is the Immutable Object/Builder section where Bloch writes about the "Builder" - class instead of just POJOs.
所以我一直在阅读一些Effective Java!本书中最鼓舞人心的部分之一是不可变对象/构建器部分,Bloch 在这里写了“构建器”——类,而不仅仅是 POJO。
NOTE: I am talking about model objects here: like for instance an Articleor a Car.
注意:我在这里谈论模型对象:例如Article或Car。
This is how I wrote these objects before:
这是我之前编写这些对象的方式:
public class Car {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
Now as you see this design is deficient in a number of ways, it requires mutability and you have to construct the object with first the constructor then setting the name.
现在,正如您所看到的,这种设计在许多方面都存在缺陷,它需要可变性,您必须首先使用构造函数然后设置名称来构造对象。
Now of course you can make the name
field final and use it as an argument in the constructor but then if you have a large object wrapping for instance a number of SQL - Tables then you will have an ugly constructor like this:
当然,现在您可以将name
字段设为 final 并将其用作构造函数中的参数,但是如果您有一个大对象包装例如许多 SQL - 表,那么您将有一个丑陋的构造函数,如下所示:
public Car(int horsepowers, String name, String brand, int yearManufactured,
User owner, List<User> previousOwners) {
//Set the values
}
This becomes unreadable when creating the object, and this is just six fields!
这在创建对象时变得不可读,而且这只是六个字段!
So, Bloch suggests the following (with immutability)
因此,Bloch 提出以下建议(具有不变性)
public class Car {
public static class Builder {
private String name;
public Builder setName(String name) {
this.name = name;
return this;
}
public Car build() {
reeturn new Car(this);
}
}
private final String name;
private Car(Builder builder) {
name = builder.name;
}
public String getName() {
return name;
}
}
//Construction example
Car car = new Car.Builder().setName("Speedy").build();
Now this gives us immutability! And if you have some objects that arent primitive or immutable just copy them in the Builder
's setters and copy them again in the Car
's getters.
现在这给了我们不变性!如果您有一些不是原始对象或不可变的对象,只需将它们复制到Builder
's setter 中,然后在Car
'getter 中再次复制它们。
But it's very wordy and I've been using constructor arguments if the class is small enough. If a class needs a mutable field I just make that field mutable, if the class has enough properties (> 4 something).
但它非常冗长,如果类足够小,我一直在使用构造函数参数。如果一个类需要一个可变字段,如果该类具有足够的属性(> 4 个),我只需将该字段设置为可变字段。
Another problem is when working with android and the class has for example a Bitmap
, then you have to return the actual bitmap and not copy it because that is rather performance - expensive.
另一个问题是当使用 android 并且该类具有例如 a 时Bitmap
,您必须返回实际位图而不是复制它,因为这相当性能 - 昂贵。
I've seen tons of questions like this but I can't seem to find a good answer on this question: is there any standardon these designs and how are their design? What are the benefits/defeceits?
我见过很多这样的问题,但我似乎无法找到这个问题的好答案:这些设计是否有任何标准以及它们的设计如何?有什么好处/缺点?
Thanks in advance!
提前致谢!
EDIT:
编辑:
The question is:
问题是:
What is the bestway to construct an object model that should be immutable and with A) a small number of fields and B) a large number of fields? How to handle the Bitmap
issue mentioned above and similar issues? Making certain fields mutable?
构造一个应该是不可变的对象模型的最佳方法是什么,并且具有 A)少量字段和 B)大量字段?如何处理上述Bitmap
问题及类似问题?使某些字段可变?
Sorry for being vague.
抱歉我含糊其辞。
采纳答案by Adam Arold
The Design Patternsbook is the alpha and the omega of design patterns currently. It is not new however but it seems that it passed the test of time.
Design Patterns一书是当前设计模式的 alpha 和 omega。然而,它并不新鲜,但似乎已经通过了时间的考验。
You can read detailed real life examples of each design pattern, how do they relate to each other, how and when to use them and a thorough explanation for each. The Builder pattern is included of course.
您可以阅读每种设计模式的详细现实生活示例,它们如何相互关联,如何以及何时使用它们以及对每种设计模式的详尽解释。Builder 模式当然也包括在内。
As to answer your question I can present my views although they are of course not authoritative.
至于回答你的问题,我可以发表一下我的观点,当然这些观点并不具有权威性。
I think that if you have a small number of fields you can go with using the constructor. If you take checkstylefor example it fires a warning over 7 parameters.
我认为,如果您有少量字段,则可以使用构造函数。如果以checkstyle为例,它会发出超过 7 个参数的警告。
If you know for sure however that you will refactor that class soon or you will have to extend it I think the Builder pattern is better since it is easier to refactor. Refactoring constructors is never fun.
然而,如果你确定你很快就会重构那个类,或者你将不得不扩展它,我认为 Builder 模式更好,因为它更容易重构。重构构造函数从来都不是一件有趣的事情。
If you are over 7 parameters I think the Builder is far better. I've been using it in the current project I'm working on extensively.
如果您超过 7 个参数,我认为 Builder 会好得多。我一直在我正在广泛开展的当前项目中使用它。
Please note that by using the Builder pattern you don't say that "Okay, I'm an immutable object builder". You say that "Okay, I'm building parameterized objects". It is therefore not a problem that you have a set of mutable fields in your class. If you however name your class like ImmutableFooDTO
and later you add mutable fields it leads to confusion.
请注意,通过使用构建器模式,您不会说“好吧,我是一个不可变的对象构建器”。你说“好吧,我正在构建参数化对象”。因此,您的类中有一组可变字段不是问题。但是,如果您将类命名为 like ImmutableFooDTO
,然后添加可变字段,则会导致混淆。
So if there is a set of fields which must not be mutable then mark them final and use a constructor/builder and provide setters for the mutable ones.
因此,如果有一组不得可变的字段,则将它们标记为 final 并使用构造函数/构建器并为可变字段提供 setter。
回答by Scott Shipp
I am inputting this as an "answer" so I have the space to explain, but this is really just a comment on the thread started by Adam Aroid.
我将此作为“答案”输入,所以我有空间进行解释,但这实际上只是对 Adam Aroid 发起的线程的评论。
Johan, first of all I assume you are talking about Item 2 in Effective Java.
Johan,首先我假设您正在谈论 Effective Java 中的第 2 项。
Note that what is presented there is a form of the Builder pattern Adam Aroid mentioned. Josh Bloch mentions this directly right before he shows the code for this in Effective Java: "It is a form of the Builder pattern [Gamma95, p. 97]." (That is on page 13.) He later mentions a way to use another pattern (from same book): "A builder whose parameters have been set makes a fine Abstract factory [Gamma95, p. 87].
请注意,所呈现的内容是 Adam Aroid 提到的 Builder 模式的一种形式。Josh Bloch 在 Effective Java 中展示代码之前直接提到了这一点:“这是构建器模式的一种形式 [Gamma95,第 97 页]。” (那是在第 13 页。)他后来提到了使用另一种模式的方法(来自同一本书):“参数已设置的构建器制作了一个很好的抽象工厂 [Gamma95,第 87 页]。
Johan, the question you asked is too broad for the space here. I think the best answer is Adam Aroid's answer. This is something that takes some study and then applying that study to gain some experience. The discussions in the Design Patterns book facilitate that greatly. I'll be voting Adam's answer up.
约翰,你问的问题对于这里的空间来说太宽泛了。我认为最好的答案是 Adam Aroid 的答案。这需要一些研究,然后应用该研究来获得一些经验。《设计模式》一书中的讨论极大地促进了这一点。我会投票支持亚当的答案。
回答by devd
Try with this code:
尝试使用此代码:
public static boolean isEmailValid(String email) {
boolean isValid = false;
String expression = "^[\w\.-]+@([\w\-]+\.)+[A-Z]{2,4}$";
CharSequence inputStr = email;
Pattern pattern = Pattern.compile(expression, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(inputStr);
if (matcher.matches()) {
isValid = true;
}
return isValid;
}