2011-10-21 36 views
6

Tôi có một lớp học thực sự đáng lo ngại với hai phương pháp bắt đầu hoặc dừng một số dịch vụ khi các dịch vụ đó có sẵn. Một cái gì đó như sau (họ không phải là if-elses, chỉ cần nếu):Một mẫu thiết kế để tránh nhiều ifs

void startServices() { 
if (service1 == true) { 
    start1(); 
} 
if (service2 == true) { 
    start2(); 
} if (serviceN == true) { 
    startN(); 
} 
} 


void stopServices() { 
if (service1 == true) { 
    stop1(); 
} 
if (service2 == true) { 
    stop2(); 
} 
if (serviceN == true) { 
    stopN(); 
} 

} 

Bạn có đề xuất cho tôi bất kỳ mẫu thiết kế nào để làm cho nó đẹp hơn không?

Cảm ơn!

+0

Tôi sẽ không trả lời điều này vì câu trả lời hiện có là tốt, nhưng tôi chỉ muốn chỉ ra rằng '== true' có phần dư thừa trong bất kỳ' if() 'nào. –

Trả lời

4

Phụ thuộc; phản ứng đầu tiên của tôi là lưu trữ các dịch vụ trong một băm hoặc mảng. Mỗi dịch vụ thực hiện một giao diện với các phương thức start và stop. Bắt đầu hoặc dừng dịch vụ sau đó chỉ yêu cầu một khóa hoặc chỉ mục dịch vụ.

Nó vẫn còn hơi giòn, có lẽ, nhưng không biết nhiều hơn Tôi không chắc chắn cách "domainify" ut để nó trông giống như những gì bạn đang làm.

4

Bạn có thể sử dụng mẫu Chiến lược.

Ý tưởng là bạn nên biết bạn sẽ sử dụng chiến lược nào khi bạn khởi tạo lớp học của mình (hoặc bạn có thể thay đổi thành công tự động). Vì vậy, bạn có thể vượt qua trong chiến lược đó khi khởi tạo (và tùy chọn thay thế nó sau này).

public interface IStartupStrategy 
{ 
    void Start(); 
} 

public interface IStopStrategy 
{ 
    void Stop(); 
} 

public class MyClass 
{ 
    private readonly IEnumerable<IStartupStrategy> startupStrategies; 
    private readonly IEnumerable<IStopStrategy> stopStrategies; 

    public MyClass(IEnumerable<IStartupStrategy> startup, IEnumerable<IStopStrategy> stop) 
    { 
     this.startupStrategies = startup; 
     this.stopStrategies = stop; 
    } 

    public void Start() 
    { 
     foreach(var strategy in this.startupStrategies) 
     { 
      strategy.Start(); 
     } 
    } 

    public void Stop() 
    { 
     foreach(var strategy in this.stopStrategies) 
     { 
      strategy.Stop(); 
     } 
    } 
} 
+0

Điều này cho tôi ấn tượng rằng mô hình Chiến lược đã được áp dụng một cách mù quáng cho vấn đề này. Tôi không nghĩ rằng việc đặt tên có ý nghĩa quá nhiều; có nhiều chiến lược khởi động? Một cho mỗi dịch vụ? – Guven

+1

Thật vậy. Tôi đã cố gắng trình bày rõ ràng về mô hình, nhưng khi làm như vậy tôi đã chia nhỏ những gì * nên * đã là một "IService" thành nhiều chiến lược bắt đầu và dừng lại. Lý tưởng nhất là bạn sẽ sử dụng giao diện "IService" sẽ có các phương thức khởi động và dừng. Sau đó, dịch vụ đó có thể quyết định xem nó có muốn triển khai hoặc bắt đầu hoặc dừng hay không. Các dịch vụ sẽ được chuyển giao dựa trên những dịch vụ có sẵn, và lớp gọi sẽ quyết định * khi nào * các dịch vụ đó nên được bắt đầu hoặc dừng lại. Nó vẫn là mô hình chiến lược, nhưng chiến lược sẽ có nhiều phương pháp. –

+0

Tôi chỉ đọc lại những gì tôi đã viết trong bình luận trước. Nếu mô hình chiến lược về cơ bản đi qua trong một số thuật toán được thực hiện mà lớp gọi không cung cấp ... sẽ đảo ngược kiểm soát như một toàn thể có thể được coi là một mô hình chiến lược? Chỉ là một ý nghĩ. –

2

Sử dụng đối tượng, nơi bạn có danh sách Dịch vụ mà bạn có thể lặp lại bằng cách tắt phương pháp được thừa kế().

public interface Service { 
    void start(); 
    void stop(); 
} 

public class TestService implements Service { 
    @Override 
    void start() { 
    } 

    @Override 
    void stop() { 
    } 
} 

Mỗi dịch vụ cũng có thể lưu trữ trạng thái của nó để chỉ tắt chúng nếu chúng bật.

0

Báo cáo chuyển đổi ít gây nhầm lẫn. Nếu được sử dụng cùng với mã enums trở nên rất dễ đọc.

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