5

我正在查看github上的示例宠物诊所 grails 应用程序。

它有一个用于创建宠物的服务,称为PetclinicService具有添加宠物的方法:

Pet createPet(String name, Date birthDate, long petTypeId, long ownerId) {
    def pet = new Pet(name: name, birthDate: birthDate, type: PetType.load(petTypeId), owner: Owner.load(ownerId))
    pet.save()
    pet
}

从控制器中使用它,如下所示:

def pet = petclinicService.createPet(params.pet?.name, params.pet?.birthDate,
    (params.pet?.type?.id ?: 0) as Long, (params.pet?.owner?.id ?: 0) as Long)

我很想知道这是否是在 grails 中保存某些东西的最佳方法?使用这种方法,如果我向域中添加另一个字段Pet,例如String color,那么我将不得不触摸三个类 ( Pet, PetController, and PetclinicService) 才能完成更改。

有没有办法可以将整个params对象发送到服务中并让它自动映射到域?

4

3 回答 3

7

我做了这个改变是因为标准是通过params地图,但这有几个原因是不好的。一是它将服务层耦合到 Web 层。这不是严格的耦合,因为它只是一个 Map,但服务应该是可重用和独立的。另一个是地图是一个“魔法”地图,您需要知道键才能使用它。通过使用命名和类型化的方法参数,代码更具可读性和可理解性。

这确实增加了维护负担,因为您指出添加新字段需要更改签名,但理想情况下,此方法将是完成这项工作的一个地方,因此您只需在一个地方进行更改。

随意params在您自己的代码中使用,但由于这个项目是我们的演示项目之一,我希望它尽可能使用最佳实践。

于 2013-02-25T19:03:28.223 回答
2

宠物诊所应用程序使用的模式是一个非常好的最佳实践。

泄漏params到服务层将使您的服务与控制器层更紧密地耦合。例如,在 API 中重用服务会更加困难。此外,如果您的服务方法具有方法参数形式的显式接口,则可以简化测试。

于 2013-02-25T19:03:57.957 回答
1

您可以将整个发送params到服务,只需声明为Map

Class PetclinicService {
  Pet createPet(Map params) {
    def pet = new Pet(params)
    pet.save()
    pet
  }
}
于 2013-02-25T18:57:37.673 回答