2015-04-16 15 views
7

Tôi biết các phiên bản đầu tiên của Grails đã sử dụng phạm vi nguyên mẫu cho bộ điều khiển vì tất cả các hành động đều bị đóng tại thời điểm đó.Tại sao Grails đề xuất phạm vi singleton cho các bộ điều khiển với các hành động làm phương pháp?

Tôi biết rằng tài liệu phiên bản hiện tại đề xuất các bộ điều khiển phạm vi đơn cho bộ điều khiển sử dụng các phương thức làm tác vụ.

Từ bài đăng sau đây có vẻ như các phương pháp và phạm vi đơn giản hơn hoặc được khuyến nghị, nhưng không rõ lý do tại sao.
ttp://grails.1312388.n4.nabble.com/Default-scope-for-controllers-doc-td4657986.html

Chúng tôi có một dự án lớn sử dụng bộ điều khiển kiểu mẫu thử nghiệm với các hành động làm phương pháp. Việc thay đổi phạm vi điều khiển được đề xuất bao gồm rủi ro và kiểm tra lại, và loại bỏ bất kỳ trạng thái thân thiện không phải là singleton nào khỏi các bộ điều khiển hiện có.

Tôi muốn biết tại sao Grails đề xuất phạm vi singleton cho phương pháp làm bộ điều khiển tác vụ? Có phải chỉ vì đó là phổ biến hơn và tương tự như Spring MVC và tránh nhầm lẫn hoặc có cơ hội cải thiện hiệu suất hay không? Tôi phải làm gì nếu tôi chuyển sang bộ điều khiển singleton? Chi phí nếu tôi không thực hiện chuyển đổi là gì?

+1

Đây là cuộc thảo luận phù hợp hơn cho https://groups.google.com/forum/#!forum/grails-dev-discuss. Câu trả lời ngắn gọn là bạn không cần phải tạo một cá thể bộ điều khiển mới cho mỗi yêu cầu duy nhất trừ khi bạn đang làm những việc tối ưu phụ khác. Bộ điều khiển Singleton gần như luôn là điều đúng đắn. Để thảo luận, hãy đăng lên danh sách gửi thư. Tôi để lại này như một bình luận, không phải là một câu trả lời, bởi vì đây không thực sự là một câu hỏi hay cho StackOverflow. –

+0

Jeff, cảm ơn nhận xét của bạn và câu trả lời ngắn. Tôi đã đăng trên thảo luận như bạn đã đề xuất. Ngạc nhiên khi bạn cảm thấy câu hỏi StackOverflow không tốt, nó có vẻ phù hợp với tôi cho rằng tài liệu đề xuất thay đổi nhưng không có lý do thay đổi và thiếu câu trả lời chắc chắn cho câu hỏi đó ở nơi khác trên Internet mà tôi có thể để tìm. – DAC

+0

"Ngạc nhiên khi bạn cảm thấy câu hỏi StackOverflow không tốt" - Một phần lý do mà nó không phải là một câu hỏi SO tốt là nó hỏi 4 câu hỏi riêng biệt. Họ là những câu hỏi liên quan nhưng riêng biệt. Các tác động xung quanh điều này là không tầm thường và đối với hầu hết mọi người sẽ yêu cầu một cuộc thảo luận để thực sự làm cho nó được sắp xếp hết. Tôi thấy rằng bạn đã chấp nhận câu trả lời mà Burt đã cho nên tôi rất vui vì bạn có những gì bạn cần. –

Trả lời

20

Tôi chưa làm việc nhiều với Rails, nhưng (ít nhất là trong các phiên bản tôi đã chơi, mọi thứ có thể khác nhau) bộ điều khiển là mô hình, chứa dữ liệu được hiển thị bởi chế độ xem. Trong quá trình xử lý yêu cầu, bạn lưu trữ các giá trị trong các trường thể hiện của bộ điều khiển trước khi thực hiện xử lý để xem các trình kết xuất đồ họa. Vì vậy, nó có ý nghĩa để tạo ra một trường hợp điều khiển mới cho mỗi yêu cầu để chúng khác biệt.

Grails được lấy cảm hứng từ Rails và sử dụng một số quy ước của nó, nổi tiếng nhất là quy ước trên cấu hình. Nhưng khả năng sử dụng bộ điều khiển như mô hình cũng đã được thêm vào như là một tính năng, mặc dù nó không được tài liệu tốt và tôi nghi ngờ nhiều người sử dụng nó. Cách điển hình là một hành động điều khiển hoạt động khi sử dụng GSP để trả lời (trái ngược với chuyển tiếp hoặc chuyển hướng, hoặc kết xuất trực tiếp trong bộ điều khiển, ví dụ: render foo as JSON) để trả về Bản đồ với một hoặc nhiều khóa/giá trị cặp từ hành động, và thường là những từ khóa return được bỏ qua vì nó không bắt buộc trong Groovy:

class MyController { 
    def someAction() { 
     def theUser = ... 
     def theOtherObject = ... 
     [user: theUser, other: theOtherObject] 
    } 
} 

ở đây, bản đồ mô hình có hai mục, một keyed bởi user và khác keyed bởi other, và những người sẽ biến tên được sử dụng trong GSP để truy cập dữ liệu.

Nhưng điều mà hầu hết mọi người không biết là bạn cũng có thể làm điều đó như thế này:

class MyController { 

    def user 
    def other 

    def someAction() { 
     user = ... 
     other = ... 
    } 
} 

Trong trường hợp này một bản đồ mô hình không được trả lại từ hành động, vì vậy Grails sẽ cư trú trong mô hình từ tất cả các thuộc tính của lớp điều khiển, và trong trường hợp này GSP tương tự sẽ làm việc cho cả hai cách tiếp cận vì các tên biến trong phương thức thứ hai giống như các khóa bản đồ trong lần đầu tiên.

Tùy chọn để tạo bộ điều khiển được thêm vào 2.0 (kỹ thuật 1.4 trước khi được đổi tên thành 2.0, xem this JIRA issue) và chúng tôi cũng thêm hỗ trợ cho các phương thức làm tác vụ. Giả định ban đầu là việc sử dụng các bao đóng sẽ cho phép một số tính năng thú vị, nhưng điều đó không bao giờ xảy ra. Sử dụng các phương thức là tự nhiên hơn vì bạn có thể ghi đè chúng trong các lớp con, không giống như các bao đóng chỉ là các trường phạm vi lớp.

Là một phần của Rework 2.0 chúng tôi loại bỏ rằng tính năng Rails lấy cảm hứng từ trên giả định rằng kể từ khi nó được về cơ bản không có cơ sở, mà tác động đối với số ít những ứng dụng kỳ quặc mà sử dụng tính năng sẽ không đáng kể. Tôi không nhớ ai từng phàn nàn về việc mất tính năng đó.

Mặc dù các lớp điều khiển thường dễ dàng thu gom rác và tạo một cá thể cho mỗi yêu cầu không ảnh hưởng nhiều, hiếm khi cần trạng thái yêu cầu trong bộ điều khiển, vì vậy các trình đơn thường có ý nghĩa hơn. Phạm vi nguyên mẫu mặc định được để lại cho khả năng tương thích ngược nhưng thật dễ dàng để thay đổi mặc định bằng thuộc tính Config.groovy (và tệp được tạo bởi tập lệnh create-app thực hiện điều này).

Mặc dù mỗi yêu cầu đều nhận được yêu cầu và phản hồi mới và nếu phiên được sử dụng thì mỗi người dùng sẽ có riêng, nhưng không phải là trường hợp của bộ điều khiển. Họ trông giống như họ là bởi vì chúng ta có thể truy cập request, response, session, params vv bên trong các hành động, nhưng những người thực sự là những hình thức truy cập tài sản của getRequest(), getResponse(), getSession(), và getParams() phương pháp được trộn vào tất cả các bộ điều khiển trong quá trình biên soạn bởi AST biến đổi. Các phương thức truy cập các đối tượng của chúng không phải là các trường lớp nhưng thông qua ThreadLocals, vì vậy có trạng thái cho mỗi yêu cầu nhưng nó không được lưu trữ trong cá thể bộ điều khiển.

Tôi không nhớ nếu có nhiều cách đánh giá để so sánh bằng cách sử dụng các phương pháp so với đóng cửa, nhưng Lari Hotari có thể đã làm một số. Nếu có sự khác biệt thì nó có lẽ không đáng kể. Bạn có thể kiểm tra điều này trong ứng dụng của riêng bạn bằng cách chuyển đổi chỉ một hoặc một vài bộ điều khiển và thực hiện trước và sau khi kiểm tra. Nếu sự khác biệt về hiệu năng, nhân rộng và bộ nhớ không có ý nghĩa giữa hai cách tiếp cận, bạn có thể sẽ an toàn ở lại với điểm nguyên mẫu và/hoặc đóng cửa. Nếu có một sự khác biệt và bạn không có các trường cá thể trong bộ điều khiển của bạn, thì có lẽ nó sẽ đáng để chuyển đổi sang các trình đơn và phương thức.

Nếu bạn có trường mẫu, chúng có thể được chuyển đổi thành thuộc tính yêu cầu - request.foo = 42 là phím tắt metaclass cho request.setAttribute('foo', 42), vì vậy bạn có thể lưu trữ dữ liệu theo yêu cầu một cách an toàn để thay thế.

+1

Burt, cảm ơn bạn rất nhiều vì đã phản hồi rất chi tiết. Bây giờ tôi cảm thấy như tôi biết toàn bộ câu chuyện. – DAC

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