请Groovy / Grails代码清理建议!

时间:2010-12-12 03:50:47

标签: grails groovy coding-style

我是Groovy&的新手。 Grails,我觉得事情不一定是丑陋的...所以我怎样才能使这段代码变得更好?

这是一个Grails控制器类,减去一些无趣的位。尽量不要太忙,我的Car只有一个Wheel - 我可以稍后处理: - )

changeWheel是一个Ajax操作。

class MyController {
    ...
    def changeWheel = {
        if(params['wheelId']) {
            def newWheel = Wheel.findById(params['wheelId'])
            if(newWheel) {
                def car = Car.findById(params['carId'])
                car?.setWheel(newWheel)
                if(car?.save()) render 'OK'
            }
        }
    }
}

3 个答案:

答案 0 :(得分:4)

我实际上开始使用Command Objects

试试这个:

class MyController {
    def index = {
    }
    def changeWheel = { CarWheelCommand cmd ->
        if(cmd.wheel && cmd.car) {
            Car car = cmd.car
            car.wheel = cmd.wheel
            render car.save() ? 'OK' : 'ERROR'
        } else {
            render "Please enter a valid Car and wheel id to change"
        }
    }
}
class CarWheelCommand {
    Car car
    Wheel wheel
}

然后在您的视图中使用“car.id”和“wheel.id”代替“carId”和“wheelId

答案 1 :(得分:3)

1)拉

params['wheelId'] 

params['carId']

进入他们自己的defs

2)多个嵌套ifs永远不是最优的。如果没有设置wheelId和carId,你可以通过使用validateParams方法去除最外层的方法并呈现某种响应。或者只是做

if (carId == null || wheelId == null) {
    // params invalid
}

3)假设一切正常,你可以做到

def newWheel = Wheel.findById...
def car = Car.findById...
if (car != null && newWheel != null) {
    car.setWheel(newWheel)
    car.save()
    render 'OK'
} else {
   // either wheel or car is null

}

这摆脱了更多的嵌套结构......

4)最后,为了使代码自我记录,你可以做一些事情,比如将条件测试分配给适当命名的变量。像

这样的东西
def carAndWheelOk = car != null && newWheel != null
if (carAndWheelOk) {
   // do the save
} else {
   // car or wheel not ok
}
对于两次测试来说,这可能有点过分,但你只需要在这里处理一个轮子。如果你正在处理所有4个轮子,这种类型的东西增加了可读性和可维护性。

请注意,此建议适用于任何语言。我不认为你可以用groovy的句法糖做太多,但也许一些时髦的大师可以提供更好的建议。

答案 2 :(得分:2)

您可以执行一些操作,例如将某些代码移动到服务或命令对象。但是,如果不过多地改变结构,我(主观地)认为以下将使代码更容易阅读:

  1. 使用点符号而不是数组索引来引用params值(params.wheelId而不是params ['wheelId'])

  2. 我会反对if减少嵌套,我认为这可以更清楚地说明例外情况。

  3. 例如:

    if(!params.wheelId) {
        sendError(400, "wheelId is required")
        return
    }
    ....
    ....
    if(!newWheel) {
        sendError(404, "wheel ${params.wheelId} was not found.")
        return
    }
    

    现在,如果您不介意更改结构并添加更多代码行......

    更改车轮的行为可能是一个常见的事件,不仅仅是一个控制器动作。在这种情况下,我建议将GORM /数据库逻辑放在Service类中。然后您的控制器只需验证它是否具有正确的参数输入,并将这些输入传递给服务以进行实际轮胎更换。服务方法可以是事务性的,您可能需要在安装新轮胎之前卸下旧轮胎的情况下。

    在服务中,我会抛出例外情况,例如找不到车轮,找不到车,或者更换轮胎时出错。然后您的控制器可以捕获这些并使用正确的HTTP状态代码进行响应。