5

Tôi thường thấy một mẫu được sử dụng trong các trường hợp mà chúng tôi có mã tra cứu cần được thực thi trước khi chúng tôi có quyền truy cập vào một đối tượng. Khi sử dụng mẫu này, thường bắt đầu bằng từ with.Có tên cho mẫu này với bao đóng không?

Ví dụ, chúng tôi có hồ sơ khách hàng mà cần phải được lấy ra từ một cơ sở dữ liệu trước khi chúng ta có thể sử dụng chúng:

def withCustomer (id, closure) { 
    def customer = getCustomer(id) 
    closure(customer) 
} 

withCustomer(12345) { customer -> 
    println "Found customer $customer.name" 
} 

Groovy làm cho không có sự khác biệt như vậy giữa đóng cửa hoặc các chức năng ẩn danh. Có lẽ, tôi có thể hỏi nếu có một tên cho mẫu này với các chức năng ẩn danh.

Trả lời

4

Đây là mẫu Chiến lược. Việc đóng cửa giữ một số hành vi được chuyển vào hàm như một đối số, để hàm có thể chấp nhận các hành vi khác nhau. Xem Peter Norvig trình bày Design Patterns in Dynamic Languages:

Chiến lược là một biến có giá trị là một chức năng (Ví dụ: với chức năng hạng nhất, mô hình là vô hình)

+0

Bạn nghĩ gì về câu trả lời [@mgryszko] (http://stackoverflow.com/a/10093625/462015) –

+0

@Arturo: tôi đã nghĩ về phương thức mẫu nhất thiết liên quan đến thừa kế, nơi mà chiến lược là một thay thế cho nó, chứ không phải một hình thức của nó. http://tech.puredanger.com/2007/07/03/pattern-hate-template/ –

+0

Bạn nghĩ gì về [câu trả lời của riêng tôi] (http://stackoverflow.com/a/10306434/462015)? –

2

Trong Groovy Closures - Formal Definition, nó chỉ được gọi là "Chuyển các đóng cửa thành phương pháp".

Groovy có trường hợp đặc biệt để xác định bao đóng là đối số phương pháp để làm cho cú pháp đóng cửa dễ đọc hơn. Cụ thể, nếu đối số cuối cùng của một phương thức thuộc loại Closure, bạn có thể gọi phương thức với một khối đóng kín bên ngoài dấu ngoặc đơn. Ví dụ, nếu một lớp học có một phương pháp:

class SomeCollection { 
    public void each (Closure c) 
} 

Sau đó, bạn có thể gọi each() với một định nghĩa đóng cửa bên ngoài ngoặc:

SomeCollection stuff = new SomeCollection(); 
stuff.each() { println it } 

Cú pháp truyền thống cũng có sẵn, và cũng có thể lưu ý rằng trong Groovy bạn có thể tách biệt dấu ngoặc đơn trong nhiều trường hợp, do đó, hai biến thể này cũng hợp pháp:

SomeCollection stuff = new SomeCollection(); 

stuff.each { println it }  // Look ma, no parens 
stuff.each ({ println it }) // Strictly traditional 

Quy tắc tương tự áp dụng ngay cả khi phương pháp có các đối số khác. Hạn chế duy nhất là lập luận Đóng cửa phải làm người rốt:

class SomeCollection { 
    public void inject (x, Closure c) 
} 

stuff.inject(0) { count, item -> count + item }  // Groovy 
stuff.inject(0, { count, item -> count + item }) // Traditional 

Đó có thể không liên quan đến "Câu hỏi Groovy", nhưng ví dụ như trong Scala, điều này "hình thức" là một trường hợp đặc biệt của function currying:

scala> def fun[A, B](a: A)(b: B) = {true} 
fun: [A, B](a: A)(b: B)Boolean 

scala> fun(1){2} 
res59: Boolean = true 
+0

Cảm ơn cho câu trả lời, nhưng bạn đừng hỏi câu hỏi của tôi. Tôi hỏi tên của mô hình này, không phải là việc sử dụng các bao đóng. –

+0

đây không phải là một mẫu, mà là một dạng cú pháp, và tên cho dạng cú pháp này trong Groovy là "** Chuyển các đóng đối với các phương thức **". Nếu bạn muốn gần gũi hơn với từ "pattern", một ví dụ trong Scala là "** function currying **" (mặc dù có nhiều thứ bạn có thể làm với hàm curry của Scala hơn dạng cú pháp này, nhưng nó chỉ xảy ra với là một trong những trường hợp đặc biệt). – tolitius

1

Nó phụ thuộc vào ngữ cảnh. Nó có thể là một mẫu Chiến lược (xem câu trả lời của Nathan Hughes). Nó có thể là một mẫu Phương thức mẫu.

Ví dụ của Arturo có vẻ là một Phương thức mẫu. Bạn xác định các bước thuật toán phổ biến (nhận được một khách hàng trong trường hợp này) và các tùy chỉnh (được thông qua như là một đóng).

+0

Bạn nghĩ gì về [câu trả lời của riêng tôi] (http://stackoverflow.com/a/10306434/462015)? –

1

Cuối cùng, tôi nghĩ rằng mẫu này được gọi là Mẫu vay.

Mẫu cho vay, đảm bảo rằng tài nguyên được định đoạt một cách xác định khi nó nằm ngoài phạm vi.

Bạn có thể thấy một số thông tin về mô hình này ở đây: