简体   繁体   English

Liskov替代原理和冗余方法

[英]Liskov Substitution Principle and Redundant Methods

I have an interface called IRepository. 我有一个称为IRepository的接口。 This interface defines a set of generic methods such as: 该接口定义了一组通用方法,例如:

 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();

I then have a class which implements this interface. 然后,我有一个实现此接口的类。 This class actually uses Entity Framework to implement these methods. 此类实际上使用Entity Framework来实现这些方法。 However the method update is redundant as the Entity Framework tracks changes made to entities retrieved so I just get the entity I want, update it then call SaveChanges. 但是,由于实体框架跟踪对检索到的实体所做的更改,因此方法更新是多余的,因此我只获取所需的实体,对其进行更新,然后调用SaveChanges。 However in the future I may want to replace this concrete implementation of IRepository with something else. 但是在将来,我可能想用其他方法代替此IRepository的具体实现。 Which probably won't track changes like Entity framework does. 可能不会像实体框架那样跟踪更改。 So I'm thinking I want to leave the update method in the interface, but in my concrete implementation of this interface just leave the method in but doing nothing. 所以我在想将update方法保留在接口中,但是在我对该接口的具体实现中,只是将方法保留在其中但什么也不做。 eg 例如

public void Update<T>(T obj) where T : class
{
}

This seems to fit with the Liskov Substitution Principle, I can replace the implementation of the interface with something else. 这似乎符合Liskov替代原则,我可以用其他方法代替接口的实现。 It's just that somethings might not need to actually implement all the methods defined on the interface. 只是可能不一定需要实际实现接口上定义的所有方法。

Is this a good approach. 这是一个好方法。 I was thinking this was okay maybe even mark the method as obsolete in the implementation of IRepository stating why it is obsolete in this implementation. 我当时认为还可以,甚至在IRepository的实现中将该方法标记为过时,说明为什么在此实现中过时了。

It just seems a bit odd having an update method which does nothing and having this called all over the application even though it doesn't actually do anything. 拥有一个不执行任何操作的update方法,并在整个应用程序中调用此方法似乎有点奇怪,即使它实际上并未执行任何操作。 But then if we changed the implemenation of IRepository, to an implmentation that does need an update method then we can substitute this in with no code changes required. 但是,如果我们将IRepository的实现更改为确实需要更新方法的实现,则可以用它代替不需要任何代码更改。

IMHO, having a method on a an interface that is not implemented in most situations tells me that the scope of the interface is too wide. 恕我直言,在大多数情况下都没有实现的接口方法告诉我接口的范围太宽。

You could remove the update method from the base repository interface and add it alone to an IUpdatableRepository that inherits from the base interface. 您可以从基本存储库界面中删除更新方法,并将其单独添加到从基本接口继承的IUpdatableRepository中。 You concrete classes that need to update can then implement the IUpdatableRepository interface instead. 然后,需要更新的具体类可以实现IUpdatableRepository接口。

This may not be exactly what you're looking for, but you get the point... 这可能不完全是您想要的,但是您明白了……

If I understand you correctly, you have a single implementation which you've wrapped in an interface. 如果我对您的理解正确,那么您将在接口中包装一个实现。 LSP isn't the only thing to worry about in design: I would argue that KISS and YAGNI are more fundamental, whereas LSP is only a way of keeping things simple and predictable in an object oriented design. LSP并不是设计中唯一需要担心的事情:我认为KISSYAGNI是更基础的,而LSP只是使事情在面向对象设计中保持简单和可预测的一种方式。 Trying to design for any conceivable future change in your system will actually tend to make your system harder to change due to increased complexity. 试图设计为系统中的任何可能的未来变化将真正往往使你的系统更难由于增加了复杂性改变。 Are you reasonably likely to replace your repository with an alternate implementation which needs the Update method? 您是否有可能用需要Update方法的替代实现替换您的存储库? Then by all means, retain it. 然后一定要保留它。 If it's only a possibility, strip it out right now (and, possibly, consider using EF directly). 如果仅是一种可能性,请立即将其删除(并且可能考虑直接使用EF)。

After all, "You can solve every problem by adding another layer of abstraction, except too many layers of abstraction." 毕竟,“除了过多的抽象层之外,您都可以通过添加另一抽象层来解决所有问题。”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM