2009-06-08 27 views
9

Trong Mẫu chiến lược thông thường, chúng tôi thực hiện từng chiến lược như một lớp. Chúng ta không thể biến nó thành một hàm, và chỉ gán tham chiếu đến hàm khi chúng ta khởi tạo một đối tượng và để đối tượng gọi hàm đó?Trong mô hình chiến lược, chúng ta có thể làm cho mỗi chiến lược như một chức năng nhưng không phải là một lớp học?

+0

Vui chơi với Java trong trường hợp đó :) – Joey

+1

tại sao? Java không thể hỗ trợ tham chiếu đến hàm? –

+7

+1 để suy nghĩ phê bình về các mẫu thiết kế. Tôi muốn nói nhiều mẫu thiết kế xuất phát từ gốc rễ của sự bất lực của ngôn ngữ. Vì vậy, trong nhiều trường hợp, các mẫu thiết kế không phải là các mẩu tin. :) – kizzx2

Trả lời

3

Trong trường hợp đơn giản nhất, bạn có thể thay thế mẫu Chiến lược bằng con trỏ hàm. Tuy nhiên, hãy xem xét trường hợp này

class HourlyPayStrategy implements PayStrategy 
{ 
    public int calculate() 
    { 
     int x = doComplexOperation1(); 
     int y = doComplexOperation2(); 

     return x + y; 
    } 

    private int doComplexOperation1() 
    { 
     // ... 
    } 

    private int doComplexOperation2() 
    { 
     // ... 
    } 
} 

Nếu chúng ta chỉ đưa ra một con trỏ hàm đơn giản, mọi thứ bắt đầu nhận được thực sự lông bởi vì bạn không còn có thể cấu trúc điều đó (tốt, ít nhất là không theo một cách tốt đóng gói).

+0

Tôi không đồng ý với điều này. Cho dù bạn tham khảo HourlyPayStrategy hoặc HourlyPayStrategy.calculate không có sự khác biệt về tái cấu trúc hay đóng gói. –

+0

@DavidArno theo ký hiệu của bạn Tôi tin rằng bạn đã quen thuộc với C#, một công việc tốt đẹp thực hiện mở rộng _eta_. Ký hiệu đó hoàn toàn không dễ dàng đạt được bằng nhiều ngôn ngữ: JavaScript, Ruby, Python, Java, OCaml thậm chí (nói từ bộ nhớ nhiều năm tuổi), C++ (câu hỏi: C++ 11 gibe với điều này như thế nào?). – kizzx2

+0

Trong nhiều ngôn ngữ khi người ta mong đợi một _function_ như tham số, nó hoàn toàn khác với mong đợi một _method_, nơi trình biên dịch/thời gian chạy sẽ cần phải mang theo với đối tượng liên quan. Vì vậy, sau đó có, cho C# đối số của bạn có chân. – kizzx2

4

Phụ thuộc vào ngôn ngữ. Trong C#, bạn có thể làm cho nó là một đại biểu. Trong Java, nó sẽ là một lớp vô danh. Trong C++, bạn thực sự có thể làm cho nó trở thành một con trỏ hàm.

2

Chắc chắn, mặc dù bằng cách sử dụng các đối tượng, bạn có thể tận dụng lợi thế của kế thừa theo những cách mà bạn không thể chỉ với các hàm.

1

Trong C# bạn có thể sử dụng các đại biểu có mẫu chiến lược. Hãy xem ví dụ này blog post.

1

Điều gì xảy ra dưới mui xe trong hầu hết các cài đặt C++ là gần như những gì bạn đề xuất. Trình biên dịch thường giải quyết một Strategy.virtualMethod call() như thế này (trong mã giả):

 
    (Strategy.pVtable[indexOfVirtualMethod])() 

Vì vậy, nếu mối quan tâm duy nhất của bạn là một dereferencing hơn về một con trỏ (pVtable) bạn thực sự cần hồ sơ đầu tiên nếu bạn không thể xác định các điểm nóng nghiêm trọng hơn.

Cảm giác của tôi là mã của bạn sẽ khó hiểu hơn và duy trì khi bạn sử dụng con trỏ hàm thay vì đối tượng chiến lược.

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