2014-09-12 21 views
8

Tôi gặp sự cố khi tổ chức mã của mình khi tôi muốn cập nhật đối tượng miền không đơn giản. Vấn đề là phân chia trách nhiệm cho bộ điều khiển và lớp dịch vụ.Grails - việc sử dụng lớp dịch vụ

Rõ ràng hơn, giả sử rằng chúng tôi có một khách hàng lớp miền phụ thuộc vào các lớp miền khác như Địa chỉ và vân vân.

Trong chế độ xem, có một gsp để chỉnh sửa một số thuộc tính Khách hàng bao gồm một số thuộc tính lồng nhau như đường phố trên Địa chỉ.

Khi tôi muốn cập nhật các trường này, tôi gọi phương thức cập nhật trên Bộ điều khiển (trong trường hợp này là ClientController).

Tôi thích tính năng đến từ lỗi của lớp miền khi được xác thực. Giống như nếu tôi trong Bộ điều khiển viết

Client client = Client.get(params.id) 
client.properties = params 
client.validate() 

Nếu bây giờ khách hàng có lỗi, rất dễ hiển thị chúng trong chế độ xem chỉnh sửa.

Nhưng, tôi nghĩ rằng việc cập nhật, lưu và nhận khách hàng từ cơ sở dữ liệu (Client.get (theId)) nên được xử lý bởi lớp dịch vụ. Trong trường hợp của tôi, tôi phải cập nhật hoặc tạo các đối tượng miền khác (như Địa chỉ) trước khi cập nhật Ứng dụng khách.

Vì vậy, một trong các câu hỏi của tôi là giao diện API trông như thế nào đối với lớp dịch vụ?

public ... updateClient(…) 

Trong tài liệu, họ có ví dụ nhỏ về cập nhật tuổi của một người. Vì vậy, API của họ bao gồm id của người và độ tuổi mới. Nhưng, trong trường hợp của tôi, tôi có khoảng mười params từ xem và họ chỉ là một tập hợp con của tất cả các thuộc tính của một khách hàng và tôi không biết cái nào trong số này đã thay đổi.

  1. Tôi muốn có một Khách hàng trong bộ điều khiển mà tôi có thể xác thực và gửi lại chế độ xem chỉnh sửa nếu có lỗi xác thực.
  2. Tôi muốn xử lý các tương tác và giao dịch cơ sở dữ liệu từ lớp dịch vụ.

Làm cách nào để kết hợp chúng? Các lớp khác nhau có trách nhiệm gì về cập nhật? API của lớp dịch vụ trông như thế nào về cập nhật?

Nếu có triển khai tham chiếu tốt ở đâu đó, tôi rất sẵn lòng nghiên cứu nó. Nhiều lần, các lớp dịch vụ là tiếc là hoàn toàn hoặc bỏ qua một phần.

+1

+1 câu hỏi hay. – David

Trả lời

5

Phần còn thiếu của câu đố này là command objects. Các lớp này đại diện cho hợp đồng cho API của bạn vào các dịch vụ của bạn và cung cấp cho bạn khả năng có một lớp cụ thể cho các chế độ xem của bạn và để xác thực. Hãy xem một ví dụ.

Cho một lớp lĩnh vực Client mà như một Address và một số Phone trường lớp dịch vụ của bạn có thể trông như thế này:

... 
class ClientService { 
    def updateClient(ClientUpdateCommand cmd) { 
    .. 
    } 
} 
... 

Trong khi ClientUpdateCommand trông giống như sau:

@grails.validation.Validateable 
class ClientUpdateCommand { 
    Long id 
    String name 
    List<PhoneUpdateCommand> phoneNumbers = [] 
    AddressUpdateCommand address = new AddressUpdateCommand() 
    ... 
    static constraints { 
    id(nullable: false) 
    name(nullable: false, blank: false, size:1..50) 
    ... 
    } 
    ... 
} 

Bạn sẽ lưu ý rằng đối tượng lệnh này bao gồm các đối tượng lệnh khác và có các ràng buộc để xác nhận hợp lệ. Có vẻ như bạn đang sao chép các lớp miền của bạn ở đây, nhưng tôi thấy rằng ứng dụng của bạn phức tạp hơn thì sự khác biệt sẽ xuất hiện giữa các lớp miền và các đối tượng lệnh của bạn.

Tiếp theo là việc sử dụng đối tượng lệnh trong bộ điều khiển và chế độ xem của bạn. Một phương pháp điều khiển có thể trông giống như thế này:

Class ClientController { 
    ... 
    def clientService 
    ... 
    def edit(ClientUpdateCommand cmd) { 
    ... 
    cmd = clientService.load(cmd.id) 
    Map model = [client: cmd] 
    render(view: 'edit', model: model) 
    } 
    def update(ClientUpdateCommand cmd) { 
    Map model = [client: cmd] 
    if (cmd.hasErrors() { 
     render(view: 'edit', model: model] 
     return 
    } else { 
     clientService.update(cmd) 
     ... 
    } 
    ... 
    } 
} 

tôi đã để lại rất nhiều ra của bộ điều khiển như tôi không muốn mang bạn với các chi tiết mà thấy làm thế nào một đối tượng lệnh thay thế chẳng hạn tên miền. Trong một số cách, nó hoạt động nhiều hơn một chút nhưng nó di chuyển bạn hoàn toàn khỏi thao tác các lớp miền và các đại biểu đến dịch vụ mà bạn đã tạo ra. Bạn cũng sẽ nhận thấy rằng đối tượng lệnh thay thế cá thể lớp miền cho mô hình của bạn cho các khung nhìn của bạn. Tôi sẽ không bận tâm cho bạn bất kỳ ví dụ nào về GSP vì chúng thực sự không thay đổi nhiều khi sử dụng các đối tượng lệnh như thế này.

Tôi chắc rằng có thể có toàn bộ các chương sách được viết về chủ đề này, nhưng hy vọng điều này cho bạn một số thông tin chi tiết và bạn có thể thấy câu trả lời cho (các) câu hỏi của bạn là: Đối tượng lệnh.

+2

+1 vị trí bật. Việc thực hiện tốt không đề cập đến các lớp miền cũng có thể được sử dụng như các đối tượng lệnh. Mặc dù đó là một khả năng, Sử dụng đối tượng lệnh tách mối quan tâm đó. – dmahapatro

Các vấn đề liên quan