固体原则:接口与抽象类

本文关键字:抽象类 接口 原则 | 更新日期: 2023-09-27 17:56:56

我有一个特定的边缘情况,我不确定是使用接口还是抽象类。最初,我的设计使用了一个抽象类,其中方法protected internal abstract void实现。

这很有用,因为我希望这些方法可以从程序集内部调用,但只能通过程序集外部的继承使用。

遇到的问题是,并非所有抽象类的衍生物都需要实现该功能,所以基本上我最终得到了空的方法主体。

这就是我使用接口

的想法,这意味着我可以通过接口实现所需的功能,但这意味着方法需要是公共的,如上所述,我只希望方法通过继承可用。

使用抽象类的示例:

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

所以我想知道什么才是更好的。两者都提供了我想要的功能,但似乎我不能同时拥有两者。

我是否

只是忍受第三方可能实现的空方法主体,没有意识到它们不应该实现,或者,我是否只实现所需的功能,但冒着通过实例化公开功能的风险?

固体原则:接口与抽象类

提到固体,你缺少的是接口隔离原则,你应该使用两个接口,一个用于内部消费者(标记为内部的方法),另一个用于外部消费者。

所以我不会选择抽象类或接口,而是选择两个(或更多)接口。

我可能已经找到了一个似乎效果很好的解决方案,但我希望社区就这是否遵守或违反 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) 中覆盖它