利斯科夫替代原理与冗余方法
本文关键字:冗余 方法 | 更新日期: 2023-09-27 18:25:41
我有一个名为IRepository的接口。该接口定义了一组通用方法,例如:
IQueryable<T> Get<T>() where T : class;
void Add<T>(T obj) where T : class;
void Update<T>(T obj) where T : class;
void SaveChanges();
然后我有一个实现这个接口的类。这个类实际上使用实体框架来实现这些方法。然而,方法更新是多余的,因为实体框架跟踪对检索到的实体所做的更改,所以我只得到我想要的实体,更新它,然后调用SaveChanges。然而,在未来,我可能想用其他东西来取代IRepository的这种具体实现。它可能不会像实体框架那样跟踪更改。所以我想我想把update方法留在接口中,但在我这个接口的具体实现中,只把方法留在里面,什么都不做。例如
public void Update<T>(T obj) where T : class
{
}
这似乎符合Liskov替换原则,我可以用其他东西替换接口的实现。只是有些东西可能不需要实际实现接口上定义的所有方法。
这是一个好方法吗。我认为这是可以的,甚至可能在IRepository的实现中将该方法标记为过时,说明为什么它在该实现中过时。
有一个更新方法什么都不做,并且在整个应用程序中调用这个方法,即使它实际上什么都没做,这似乎有点奇怪。但是,如果我们将IRepository的实现更改为确实需要更新方法的实现,那么我们可以在不需要代码更改的情况下替换它。
IMHO,在大多数情况下都没有实现的接口上有一个方法,这告诉我接口的范围太宽了。
您可以从基本存储库接口中删除更新方法,并将其单独添加到从基本接口继承的IUpdateableRepository中。然后,需要更新的具体类可以实现IUpdateableRepository接口。
这可能不是你想要的,但你明白了。。。
如果我理解正确,您有一个封装在接口中的实现。LSP并不是设计中唯一需要担心的事情:我认为KISS和YAGNI是更基本的,而LSP只是在面向对象的设计中保持简单和可预测的一种方式。试图为设计系统中任何可能的未来更改,实际上会使您的系统因复杂性增加而更难更改。您是否有理由用需要Update方法的替代实现来替换您的存储库?然后,无论如何,保留它。如果这只是一种可能性,现在就把它去掉(可能的话,考虑直接使用EF)。
毕竟,"你可以通过添加另一层抽象来解决每一个问题,除了太多的抽象层。"