在我们的 C# MVC 应用程序中,我们有很多接口(interface)与实现它们的对象一对一映射。即:基本上,对于创建的每个对象,都执行了“提取接口(interface)”操作。
Moq 使用这些接口(interface)为我们的单元测试生成模拟对象。但那是唯一一次重新使用接口(interface)。
我们系统中没有具体对象实现多个接口(interface)。
谁能告诉我这是否会在以后造成问题?如果是这样,它们会是什么?
我在想,我们的应用程序有很多重复,例如在这两个接口(interface)中(编辑:在我们的服务层中)唯一不同的是方法名称和它们采用的参数类型,但是从语义上讲,他们对发送消息的存储库做同样的事情:
interface ICustomer
{
void AddCustomer(Customer toAdd);
void UpdateCustomer(Customer toUpdate);
Customer GetById(int customerId);
}
interface IEmployee
{
void AddEmployee(Employee toBeAdded);
void UpdateEmployee(Employee toUpdate);
Employee GetById(int employeeId);
}
这就是我认为重用抽象原则应该发挥作用的地方,即将代码转换成如下形式:
public interface IEmployee: IAdd<Employee>, IUpdate<Employee>, IFinder<Employee>
这与存储库模式无关——这是关于任何层中的接口(interface),这些接口(interface)看起来像是在语义上共享相同的行为。是否值得为这些操作派生通用接口(interface)并使“子接口(interface)”从它们继承?
至少它会保持方法的签名一致。但这还能给我带来什么其他好处呢? (抛开里氏替换原则)
现在,方法的名称和返回类型无处不在。
我阅读了 Mark Seemann 的关于重用抽象原则的博客,但坦率地说,我并不理解它。也许我只是愚蠢 :) 我还阅读了 Fowler 对 Header Interfaces 的定义。
最佳答案
鉴于此:
interface ICustomer{
void AddCustomer(Customer toAdd);
void UpdateCustomer(Customer toUpdate);
Customer GetById(int customerId);
}
interface IEmployee
{
void AddEmployee(Employee toBeAdded);
void UpdateEmployee(Employee toUpdate);
Employee GetById(int employeeId);
}
我可能会像这样重新设计它:
interface IRepository<T>
{
void Add(T toAdd);
void Update(T toUpdate);
T GetById(int id);
}
然而,这很可能仍然违反了 Interface Segregation Principle , 更不用说因为它也违反了 Command-Query Responsibility Segregation 模式(不是架构)它也不能既不协变也不逆变。
因此,我的下一步可能是将它们拆分为 Role Interfaces :
interface IAdder<T>
{
void Add(T toAdd);
}
interface IUpdater<T>
{
void Update(T toAdd);
}
interface IReader<T>
{
T GetById(int id);
}
此外,您可能会注意到 IAdder<T>
和 IUpdater<T>
在结构上是相同的(它们只是在语义上不同),所以为什么不把它们合二为一:
interface ICommand<T>
{
void Execute(T item);
}
为了保持一致,您可以重命名 IReader<T>
还有:
interface IQuery<T>
{
T GetById(int id);
}
本质上,您可以将一切缩减为这两个接口(interface),但对于某些人来说,这可能过于抽象,并且携带的语义信息太少。
但是,我认为不可能提供更好的答案,因为前提是有缺陷的。最初的问题是界面应该如何设计,但客户端却遥遥无期。作为APPP channel 11 告诉我们,“客户端 [...] 拥有抽象接口(interface)” - 换句话说,客户端根据需要定义接口(interface)。不应从具体类中提取接口(interface)。
关于这个主题的进一步学习 Material ,这里有几个我的 Pluralsight 类(class):
关于c# - C#中的重用抽象原则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30078347/