SOLID 原则:接口与抽象 类
SOLID Principles : interfaces vs. abstract classes
我有一个特殊的边缘情况,我不确定是使用接口还是抽象 class。最初我的设计使用抽象 class,其中方法实现为 protected internal abstract void
。
这很有用,因为我希望这些方法可以从我的程序集中调用,但只能通过我的程序集外部的继承来使用。
我遇到的问题是,并非抽象 class 的所有衍生物都需要实现该功能,所以基本上我最终得到的是空方法体。
这是我想到使用接口的地方,这意味着我可以通过接口实现所需的功能,但这意味着方法需要 public,并且如上所述,我只希望方法通过继承可用。
使用抽象的例子class:
abstract class Dependency
{
protected internal abstract void DoThis();
protected internal abstract void DoThat();
}
sealed class DerivedDependency : Dependency
{
protected override void DoThis()
{
// implementation...
}
protected override void DoThat()
{
// not required...
}
}
使用接口的示例:
abstract class Dependency
{
// whilst this is now empty, it is still required to provide a type hierarchy!
}
interface IDoThis
{
void DoThis();
}
interface IDoThat
{
void DoThat();
}
sealed class DerivedDependency : Dependency, IDoThis
{
public virtual void DoThis()
{
// I only need this functionality. I don't need to DoThat();
}
}
所以我想知道真正更好的是什么。两者都提供了我想要的功能,但我似乎不能两者兼得。
我是否只是忍受了第 3 方可能实现的空方法体,却没有意识到它们并不意味着要实现,或者,我是否只实现了所需的功能,但冒着通过实例化暴露功能的风险?
提到solid,你缺少的是接口隔离原则,你应该使用两个接口,一个用于内部消费者(标记为内部的方法),另一个用于外部消费者。
所以我不会选择抽象 class 也不会选择接口,而是选择两个(或更多)接口。
我可能找到了一个看起来效果不错的解决方案,但我希望社区能就此是否遵守或违反 SOLID 原则发表意见:
interface IDoThis
{
void DoThis();
}
class Dependency : IDoThis
{
protected internal virtual void DoThis()
{
// impl.
}
void IDoThis.DoThis()
{
this.DoThis();
}
}
IDoThis idt = new Dependency();
idt.DoThis() // calls into the protected method.
这允许我通过接口 (ISP) 分离功能,在程序集中公开访问它,并在外部程序集中覆盖它 (OCP)
我有一个特殊的边缘情况,我不确定是使用接口还是抽象 class。最初我的设计使用抽象 class,其中方法实现为 protected internal abstract void
。
这很有用,因为我希望这些方法可以从我的程序集中调用,但只能通过我的程序集外部的继承来使用。
我遇到的问题是,并非抽象 class 的所有衍生物都需要实现该功能,所以基本上我最终得到的是空方法体。
这是我想到使用接口的地方,这意味着我可以通过接口实现所需的功能,但这意味着方法需要 public,并且如上所述,我只希望方法通过继承可用。
使用抽象的例子class:
abstract class Dependency
{
protected internal abstract void DoThis();
protected internal abstract void DoThat();
}
sealed class DerivedDependency : Dependency
{
protected override void DoThis()
{
// implementation...
}
protected override void DoThat()
{
// not required...
}
}
使用接口的示例:
abstract class Dependency
{
// whilst this is now empty, it is still required to provide a type hierarchy!
}
interface IDoThis
{
void DoThis();
}
interface IDoThat
{
void DoThat();
}
sealed class DerivedDependency : Dependency, IDoThis
{
public virtual void DoThis()
{
// I only need this functionality. I don't need to DoThat();
}
}
所以我想知道真正更好的是什么。两者都提供了我想要的功能,但我似乎不能两者兼得。
我是否只是忍受了第 3 方可能实现的空方法体,却没有意识到它们并不意味着要实现,或者,我是否只实现了所需的功能,但冒着通过实例化暴露功能的风险?
提到solid,你缺少的是接口隔离原则,你应该使用两个接口,一个用于内部消费者(标记为内部的方法),另一个用于外部消费者。
所以我不会选择抽象 class 也不会选择接口,而是选择两个(或更多)接口。
我可能找到了一个看起来效果不错的解决方案,但我希望社区能就此是否遵守或违反 SOLID 原则发表意见:
interface IDoThis
{
void DoThis();
}
class Dependency : IDoThis
{
protected internal virtual void DoThis()
{
// impl.
}
void IDoThis.DoThis()
{
this.DoThis();
}
}
IDoThis idt = new Dependency();
idt.DoThis() // calls into the protected method.
这允许我通过接口 (ISP) 分离功能,在程序集中公开访问它,并在外部程序集中覆盖它 (OCP)