You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决C#场景下接口隔离原则(ISP)违规问题

解决方案

这是典型的接口职责过载导致的ISP违规问题,不需要让Party感知参会人员的具体类型,只要按能力拆分细粒度接口,配合多态能力分发就能完美解决,核心思路是把「参会资格」和「具体能力」拆成独立的抽象。


第一步:拆分细粒度接口

不要把「到场」和「跳舞」两个不同维度的行为硬塞到同一个IPerson接口里:

  • 所有参会人都必须实现到场逻辑,这是参会的核心资格
  • 跳舞是可选能力,只有具备该能力的人才需要实现
// 所有参会人员的通用接口,仅定义必须的参会行为
public interface IPartyAttendee
{
    void Arrive();
}

// 跳舞能力接口,按需实现,不强制所有参会者具备
public interface IDanceCapable
{
    void Dance();
}

第二步:调整人员类实现

不会跳舞的人员再也不需要被迫写空的Dance方法:

// 会跳舞的人员,同时实现参会接口和跳舞能力接口
public class PersonThatCanDance : IPartyAttendee, IDanceCapable
{
    public void Arrive()
    {
        // 到场相关逻辑
    }

    public void Dance()
    {
        // 跳舞相关逻辑
    }
}

// 不会跳舞的人员,仅实现参会接口即可
public class PersonThatCannotDance : IPartyAttendee
{
    public void Arrive()
    {
        // 到场相关逻辑
    }
}

第三步:调整Party类逻辑

Party只依赖抽象接口,不需要感知任何具体人员类型,在触发对应场景行为时,筛选具备对应能力的对象调用方法即可:

public class Party
{
    private IPartyAttendee person1;
    private IPartyAttendee person2;

    private void StartParty()
    {
        // 所有参会人都需要到场,直接调用通用接口方法
        person1.Arrive();
        person2.Arrive();
    }

    private void StartMusic()
    {
        // 仅调用具备跳舞能力的参会者的Dance方法
        if (person1 is IDanceCapable dancer1) dancer1.Dance();
        if (person2 is IDanceCapable dancer2) dancer2.Dance();
    }
}

如果后续参会人数不固定,也可以直接用列表存储参会者,配合LINQ的OfType方法批量筛选,代码更简洁:

public class Party
{
    private readonly List<IPartyAttendee> _attendees = new();

    public void AddAttendee(IPartyAttendee attendee) => _attendees.Add(attendee);

    private void StartParty()
    {
        foreach (var attendee in _attendees) attendee.Arrive();
    }

    private void StartMusic()
    {
        foreach (var dancer in _attendees.OfType<IDanceCapable>()) dancer.Dance();
    }
}

方案优势

  • 完全符合接口隔离原则:不需要任何类实现自己用不到的接口方法,彻底消灭无意义的空实现
  • 符合开闭原则:后续新增其他能力(比如唱歌、玩桌游)时,只要新增对应能力接口,在对应场景触发时筛选实现了该接口的对象调用即可,不需要修改原有核心逻辑
  • 无额外侵入:Party类全程只和抽象接口交互,不需要依赖任何具体的人员实现类,也不需要写针对具体类型的分支判断

注:这里的类型判断是针对抽象能力接口而非具体实现类,本质是多态能力匹配,不属于违反依赖倒置的坏味道。如果追求更彻底的解耦,也可以换成事件驱动模式:音乐开始时发布事件,所有会跳舞的参会者自行订阅事件响应跳舞逻辑,不会跳舞的人无需感知该事件,最终效果一致。


内容的提问来源于stack exchange,提问作者André Escrich

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 00:18:27