【发布时间】:2013-07-31 09:01:23
【问题描述】:
我有一个名为 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 的这个具体实现。这可能不会像实体框架那样跟踪变化。所以我想我想把更新方法留在接口中,但是在我这个接口的具体实现中,只是把方法留在里面,但什么也不做。例如
public void Update<T>(T obj) where T : class
{
}
这似乎符合 Liskov 替换原则,我可以将接口的实现替换为其他东西。只是有些东西可能不需要真正实现接口上定义的所有方法。
这是一个好方法吗?我在想这没关系,甚至可能在 IRepository 的实现中将该方法标记为已过时,说明为什么它在此实现中已过时。
拥有一个什么都不做的更新方法并在整个应用程序中调用它似乎有点奇怪,即使它实际上并没有做任何事情。但是,如果我们将 IRepository 的实现更改为确实需要更新方法的实现,那么我们可以将其替换为不需要更改代码。
【问题讨论】:
-
这与问题有点正交,但是通过抽象出抽象(EF 已经是),您几乎会自动失去很多随之而来的功能(缓存,第一和第二如果您介绍一个级别,更改跟踪等)...
-
读起来很有趣,它准确地描述了我想出的界面。我想像这样的接口确实会做出错误的保证。如果我替换实现,并非所有查询都能正常工作。
-
Patryk 我同意我正在抽象出一个抽象,但我想将所有对 EF 的依赖项保留在一个地方,这样它就更加解耦了。这样,如果我从 EF 进行更改,我只需要更改一个类,而不是需要数据库访问的任何地方。我仍然受益于变更跟踪等,因为实际实施是 EF?如果我不对此进行抽象,我会将 EF 特定的代码分散在应用程序中吗?
标签: c# design-patterns solid-principles liskov-substitution-principle