6

Tôi muốn tạo một lớp có thể sử dụng một trong bốn thuật toán (và thuật toán sử dụng chỉ được biết trong thời gian chạy). Tôi đã nghĩ rằng mẫu thiết kế Chiến lược có vẻ phù hợp, nhưng vấn đề của tôi là mỗi thuật toán đòi hỏi các tham số hơi khác nhau. Nó sẽ là một thiết kế xấu để sử dụng chiến lược, nhưng vượt qua trong các tham số có liên quan vào constructor ?.Mẫu thiết kế nào phù hợp nhất?

Dưới đây là một ví dụ (vì đơn giản, giả sử chỉ có hai thuật toán có thể) ...

class Foo 
{ 
private: 
    // At run-time the correct algorithm is used, e.g. a = new Algorithm1(1); 
    AlgorithmInterface* a; 

}; 

class AlgorithmInterface 
{ 
public: 
    virtual void DoSomething() = 0; 
}; 

class Algorithm1 : public AlgorithmInterface 
{ 
public: 
    Algorithm1(int i) : value(i) {} 
    virtual void DoSomething(){ // Does something with int value }; 
    int value; 
}; 

class Algorithm2 : public AlgorithmInterface 
{ 
public: 
    Algorithm2(bool b) : value(b) {} 
    virtual void DoSomething(){ // Do something with bool value }; 
    bool value; 
}; 
+5

Thay vì cố gắng phù hợp với mã của bạn thành một số mẫu giả định, chỉ cần thiết kế nó rõ ràng nhất cho bạn (và hy vọng rõ ràng nhất đối với mọi người) và dễ bảo trì nhất. Nói cách khác: các mẫu thiết kế hút. Nếu * bạn * tìm cách thanh lịch để giải quyết vấn đề, hãy sử dụng nó; có hay không vi phạm một số mẫu thiết kế tùy ý là không liên quan. – GManNickG

+0

Ngoài ra, nếu bạn cung cấp cho chúng tôi nhiều hơn một chút (các tham số này được thông qua như thế nào, v.v.), chúng tôi có thể cung cấp cho bạn câu trả lời tốt hơn. Nhưng dường như nó có vẻ như là một giải pháp tốt cho tôi. – GManNickG

Trả lời

7

Đây sẽ là thiết kế hợp lệ vì mẫu Chiến lược yêu cầu một giao diện được xác định và bất kỳ lớp nào triển khai nó là ứng cử viên hợp lệ để chạy mã chiến lược, bất kể nó được xây dựng như thế nào.

2

Tôi nghĩ đó là đúng, nếu bạn có tất cả các thông số bạn cần khi bạn tạo ra các chiến lược mới và những gì bạn làm là rõ ràng cho mọi người đọc mã.

0

Bạn cũng có thể chuyển tham số bằng cách sử dụng một giao diện duy nhất của khối bộ nhớ chứa cặp khóa-giá trị. Bằng cách đó, giao diện là phổ biến giữa bất kỳ thuật toán hiện tại và tương lai. Mỗi lần thực hiện thuật toán sẽ biết cách giải mã các cặp khóa-giá trị thành các tham số của nó.

+1

Sẽ không phải loại này phá vỡ toàn bộ ý tưởng của mô hình chiến lược vì mã gọi chiến lược sẽ cần biết chiến lược nào đang được sử dụng để biết cặp khóa/giá trị nào cần vượt qua? –

+0

Không, điều này sẽ chỉ ảnh hưởng đến việc thực hiện lớp Chiến lược. Thay vì xây dựng các thuật toán với các giao diện duy nhất, nó sẽ là một đồng nhất. Giao diện ứng dụng không nên thay đổi. Có lẽ một chi phí cao để làm điều đó cho một số lượng nhỏ các thuật toán, nhưng nếu số lượng có thể phát triển đến hàng chục hoặc nhiều hơn nó có thể đơn giản hơn để duy trì. –

+0

@Eric, tôi đoán điều đó sẽ phụ thuộc vào việc bạn có mong đợi khách hàng luôn cung cấp các cặp khóa-giá trị giống nhau hay không. Tất nhiên, điều đó sẽ đặt ra câu hỏi tại sao cần phải có các cặp khóa-giá trị. –

2

Bạn đang sử dụng phương pháp này. Vâng, đây là bản chất của mẫu chiến lược ... "Thay đổi thuật toán độc lập với việc triển khai". Bạn có thể chỉ cần cung cấp cho mình một hàm tạo chung để truyền vào các tham số mà bạn cần để khởi tạo lớp của bạn, chẳng hạn như một mảng đối tượng.

Tận hưởng!

1

Mẫu chiến lược hữu ích khi bạn muốn quyết định thời gian chạy sử dụng thuật toán nào.

0

IMHO, bạn đang đối mặt với thử thách khi bạn đang bối rối giữa khía cạnh sáng tạo của thuật toán cụ thể và thuật toán thực tế của thuật toán. Miễn là giao diện 'DoSomething' vẫn giữ nguyên, có thể sử dụng Strategy Pattern. Nó chỉ là việc tạo ra các thuật toán cụ thể khác nhau mà thay đổi trong trường hợp của bạn, mà có thể được xử lý thông qua một mẫu thiết kế Factory Method.

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