在重写隐式getter时,Grails域类的行为出乎意料



考虑以下grails域类:

Test.groovy

package test
class Test {    
    Integer month
    Integer year
    String performancePeriod = ""
    static constraints = {      
        month(range:01..12, nullable:true)
        year(range:2010..2020, nullable:false)
        performancePeriod(nullable:true)        
    }
    String getPerformancePeriod() {
        if(month) {
            "${month?.toString().padLeft(2,'0')}.${year?.toString()}"
        }
        else {
            getYearStringFormat()
        }
    }
    String getPerformancePeriodDate(){
        return new GregorianCalendar(year, month, 1).time
    }
    String getJahrStringFormat() {
        year ? year.toString() : ""
    }
    String getMonatZweiStellig() {
        month? month.toString().padLeft(2,'0') : ""
    }   
}

它是遗留代码。我知道这个设计很糟糕,因为表示逻辑绑定到域对象。我所说的表示逻辑指的是属性performancePeriod,它的唯一目的是提供一个表示年份和日期的String格式。

现在,生成控制器并构建视图。如果在不设置performancePeriod的情况下创建新的Test记录,则将使用方法getPerformancePeriod中给出的逻辑隐式设置该属性。

我不能理解这种行为。我知道设计一开始就很糟糕,尤其是因为功能依赖性{year, month} -> performancePeriod,但performancePeriod什么时候保存到数据库?为什么在我决定设置一个值之前,我不能决定将其设为null?

为什么在我决定设置一个值之前,我不能决定将其设为null?

你可以。当持久性引擎持久化对象时,它必须询问对象以检索特定属性的值。当引擎要求performancePeriod属性的值时,您永远不会返回null。无论你告诉持久化引擎performancePeriod属性的值是多少,它都会持久化。你在域类中混淆了关注点,你所描述的有问题的行为就是其结果。

你的课堂写作方式很独特,原因有几个。performancePeriod字段从未用于任何用途。我不能从你的问题中确定,但可能部分混乱是你没有区分字段的定义和属性的定义。

最新更新