考虑使用Java中的Message对象来存储一些文本。
public class Message {
private String text;
private boolean containsDigit;
public Message() {
//constructor
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public boolean isContainsDigit() {
return containsDigit;
}
}
这是一个持久对象。
我在构造函数中设置数据没有问题,但可以在创建对象后设置Message的文本字段,并且在设置文本后,containsDigit字段也应该可以查询。 显而易见的方法是在setter中:
public void setText(String text) {
// presume existence of method to check for digit
if(text.containsDigit())
this.containsDigit = true;
this.text = text;
}
但是,由于在setter方法中有逻辑,这是否导致任何“最佳实践”警报响起?
有人会建议替代实施吗?
修改
我应该补充一点,containsDigit
字段是必需的,因为该对象是持久的,因此可以随后查询containsDigit
字段。
此外,在使用Spring / Hibernate引擎的应用程序中,在重新读取/写入对象时不断调用此setter,因此也想知道它的实用性/效率。
答案 0 :(得分:5)
你的情况是使用setter和getter的原因。如果您不允许在setter中使用逻辑,那么您也可以直接访问这些字段!
答案 1 :(得分:2)
这可能不是最好的做法,但有时候生活比最佳做法更强。
可能更好的方法是删除字段 containsDigit
并将添加到setter的逻辑移动到isContainsDigit()
:
public class Message {
private final static Pattern d = Pattern.compile("\\d");
private String text;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public boolean isContainsDigit() {
return text == null ? false : d.matcher(text).find();
}
}
答案 2 :(得分:1)
实施方法public boolean isContainsDigit()
,如下所示:
public boolean isContainsDigit() {
return getText().containsDigit();
}
这样您就不必同时保持它们同步,同时必须一次又一次地重新评估它们。另一方面,如果您不需要执行此操作,请不要对性能进行性能优化。方法setText()和isContainsDigit()属于竞争条件,如果它们由两个线程同时访问。如果你想解决这个问题,也许你必须同步它们。
答案 3 :(得分:0)
我可以说这已经足够了#34;但是,如果你想完全遵循面向对象的设计,你将实现类似事件onTextChange
的东西,只要设置更改文本就会触发。另一方面,您将为将更新containsDigit
字段的此事件实现处理程序。对于您的简单示例,这实际上是不必要的,但如果您希望将来在setText()
中添加新逻辑,则可以考虑这一点。
答案 4 :(得分:0)
@dre - 真是太奇怪了。除了争论某种设计的优雅或纯洁之外,Saint所链接的两个链接都没有大大区别于你的问题。如果你有一个“setter”那么整个点就是能够用一些逻辑来包围变量的设置,这个逻辑确保变量被正确设置,同时考虑到在需要时提供给类中其他属性的依赖性。如果“setter”将是“纯粹的”,那么摆脱它们并将变量公之于众。罗伯特·马丁的书“清洁代码”中可能确实有一些内容明确地说明了occam剃刀的原理或简约原则。也许这个链接有助于:http://effectivesoftwaredesign.com/2013/08/05/simplicity-in-software-design-kiss-yagni-and-occams-razor/。最后应该注意的是,根本没有建议将属性公开,因为返回并将属性从公共私有化是一场噩梦。我重申 - 首先选择让你的类不可变,所有成员属性都是私有的。如果该类用户尖叫,请他们证明为什么他们需要改变它。一旦他们的理由被考虑在内,创建一个setter,不要公开变量。这应该作为一套设计规则。 Hibernate或JPA应与此设计决策无关。
要创建具有许多参数不可变的类,请使用构建器模式 - When would you use the Builder Pattern?