在java中使用逻辑的setter

时间:2014-03-25 13:30:59

标签: java oop setter getter-setter

考虑使用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,因此也想知道它的实用性/效率。

5 个答案:

答案 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?