Tôi đã phạm tội có mối quan hệ 1-1 giữa giao diện của tôi và các lớp cụ thể khi sử dụng tiêm phụ thuộc. Khi tôi cần thêm một phương thức vào một giao diện, tôi sẽ phá vỡ tất cả các lớp thực hiện giao diện.Tiêm phụ thuộc với giao diện hoặc lớp học
Đây là một ví dụ đơn giản, nhưng giả sử rằng tôi cần phải tiêm một ILogger
vào một trong các lớp học của tôi.
public interface ILogger
{
void Info(string message);
}
public class Logger : ILogger
{
public void Info(string message) { }
}
Có mối quan hệ 1-1 tương tự như mùi này. Vì tôi chỉ có một triển khai duy nhất, có bất kỳ vấn đề nào có khả năng xảy ra nếu tôi tạo một lớp và đánh dấu phương thức Info
là ảo để ghi đè trong các thử nghiệm của tôi thay vì phải tạo giao diện cho một lớp đơn lẻ không?
public class Logger
{
public virtual void Info(string message)
{
// Log to file
}
}
Nếu tôi cần thực hiện khác, tôi có thể ghi đè lên Info
phương pháp:
public class SqlLogger : Logger
{
public override void Info(string message)
{
// Log to SQL
}
}
Nếu mỗi người trong số các lớp này có các thuộc tính hoặc các phương pháp cụ thể mà sẽ tạo ra một sự trừu tượng rò rỉ, tôi có thể trích xuất ra khỏi cơ sở lớp học:
public class Logger
{
public virtual void Info(string message)
{
throw new NotImplementedException();
}
}
public class SqlLogger : Logger
{
public override void Info(string message) { }
}
public class FileLogger : Logger
{
public override void Info(string message) { }
}
Lý do tôi không đánh dấu lớp cơ sở là trừu tượng là vì nếu tôi muốn thêm phương pháp khác, tôi sẽ không phá vỡ exis ting triển khai. Ví dụ: nếu số FileLogger
của tôi cần phương thức Debug
, tôi có thể cập nhật lớp cơ sở Logger
mà không vi phạm SqlLogger
hiện tại.
public class Logger
{
public virtual void Info(string message)
{
throw new NotImplementedException();
}
public virtual void Debug(string message)
{
throw new NotImplementedException();
}
}
public class SqlLogger : Logger
{
public override void Info(string message) { }
}
public class FileLogger : Logger
{
public override void Info(string message) { }
public override void Debug(string message) { }
}
Một lần nữa, đây là ví dụ đơn giản, nhưng khi nào tôi nên sử dụng giao diện?
_ Lý do tại sao tôi không đánh dấu lớp cơ sở là trừu tượng là vì nếu tôi muốn thêm phương thức khác_ Hm, lớp trừu tượng có thể chứa triển khai. Bạn có thể thêm phương thức Debug vào lớp Logger trừu tượng của bạn. –
Việc phá vỡ các triển khai hiện tại chỉ là vấn đề nếu bạn đang viết một thư viện có thể tái sử dụng. Bạn có phải? Hay bạn chỉ đơn giản là viết một dòng ứng dụng kinh doanh? – Steven
Đó không phải là phạm vi của câu hỏi, nhưng thừa kế được đánh giá cao. Một 'SqlLogger' chỉ là một' Logger' cụ thể với một 'SqlLogPersistenceStrategy'. Thành phần tốt hơn nhiều so với thừa kế trong hầu hết các trường hợp. Cũng cho vấn đề của bạn, những gì về các ISP? 'ILogInfo',' ILogError', vv – plalx