2013-07-10 42 views
6

Sự kế thừa từ một lớp với các phương thức không được sử dụng có vi phạm nguyên tắc phân tách giao diện không?Nguyên tắc phân tách quyền thừa kế và giao diện

Ví dụ:

abstract class Base 
{ 
    public void Receive(int n) 
    { 
     // . . . (some important work) 

     OnMsg(n.ToString()); 
    } 

    protected abstract void OnMsg(string msg); 
} 

class Concrete : Base 
{ 
    protected override void OnMsg(string msg) 
    { 
     Console.WriteLine("Msg: " + msg); 
    } 
} 

Concrete phụ thuộc vào phương pháp Base.Receive(int n), nhưng nó không bao giờ sử dụng nó.

UPD

Definition tôi sử dụng:

ISP khẳng định rằng không có khách hàng nên buộc phải phụ thuộc vào phương pháp nó không sử dụng.

+0

Tôi không chắc chắn rằng trong ví dụ này không sử dụng nó, OnMsg sẽ được gọi như thế nào nếu Nhận là không được sử dụng? – BlackICE

+0

Trong trường hợp của tôi, cách duy nhất để gọi 'OnMsg' là từ' Nhận'. Tôi cần thừa kế này để dự án dữ liệu đến ('int n') tới giao diện' Concrete' sử dụng 'chuỗi msg'. Trong ví dụ thực tế, có một số công việc phức tạp hơn là 'ToString()' – astef

+0

@astef: Như Paulo đã chỉ ra, bạn đang sử dụng 'mẫu thiết kế mẫu' ở đây :) –

Trả lời

7

Tôi nghĩ bạn hiểu sai nguyên tắc phân biệt giao diện nói gì. Trong trường hợp của bạn, bạn tốt và không "buộc" bất kỳ việc triển khai nào. Trong thực tế bạn đang áp dụng các Template method design pattern

Nếu bạn đã có một giả thuyết

interface ICommunicateInt 
{ 
    int Receive(); 
    void Send(int n); 
} 

để thực hiện nó, lớp Base của bạn sẽ buộc phải thực hiện một phương pháp Send rằng nó không cần. Vì vậy, các ISP cho thấy rằng nó là tốt hơn để có:

interface ISendInt 
{ 
    void Send(int n); 
} 

interface IReceiveInt 
{ 
    int Receive(); 
} 

nên lớp học của bạn có thể chọn để thực hiện một hoặc cả hai. Ngoài ra các phương thức trong các lớp khác cần một lớp học có thể gửi Int, có thể yêu cầu một số

void Test(ISendInt snd) 
// void Test(ICommunicateInt snd) // Test would "force" snd to depend on 
            // a method that it does not use 
0

Tôi không thấy rằng Concrete "phụ thuộc" khi Base.Receive() theo cách tôi sẽ sử dụng thuật ngữ. Bê tông cần thay đổi như thế nào nếu Nhận được sửa đổi? Tôi sẽ tranh luận, không hề. Giả sử chúng ta đã thay thế Receive() bằng một phương thức của một tên khác hoặc với một chữ ký khác, Concrete sẽ không biết. Concrete có gọi Receive() không? Vì vậy, tôi thấy không phụ thuộc vào Nhận() ở đây.

Sự phụ thuộc với chữ ký OnMsg(), Bê tông tham gia vào mối quan hệ rất đặc biệt với Base, hoàn thành hợp đồng OnMsg(). Nhưng theo một ý nghĩa khác, bê tông phụ thuộc rất nhiều vào Base.Receive(), đó là giao diện của nó với thế giới bên ngoài - mà không có phương pháp đó, không ai có thể truy cập vào capabilties của Concrete. Theo nghĩa này, Concrete "sử dụng" Base.Receive() ở mức rất cơ bản.

+0

Tôi hiểu bạn. Nhưng câu trả lời là gì? Có phải cách xấu để chiếu dữ liệu đến chưa biết đến một giao diện đích không? – astef

+0

Không, nó không phải là xấu, đó là một mô hình cơ bản quan trọng. – djna

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