Class/interface split

Используя в сигнатурах клиентских методов и классов или интерфейс или тривиальный класс, который реализует данный интерфейс, вы тем самым неявно разделяете код на 2 части.

Это особенно проявляется, если объявить класс и интерфейс для DTO (domain transfer object). Он по своей сути много где используется и сможет заафектить много кода.

interface IMessage {
    string Id {get;}
}

class Message: IMessage {
    public string Id{get;}
}

Теперь где-то в коде

interface ISomeService {
    void Do(IMessage m);
}

interface IOtherService {
    void DoOther(Message m);
}

class Service : ISomeService, IOtherService {
    public void Do(IMessage m);
    void DoOther(Message m);
}

В чем проблема?

Дело в том, что методы Do и DoOther могут порождать другие классы и интерфейсы и таким образом произойдет неявный сплит вашего кода на 2 части – те, кто работают с IMessage и с Message.

Проблема усугубляется, если вы используете генерики

interface ISomeService<T> {
    void Do(T m);
}

interface IOtherService<T> {
    void DoOther(T m);
}

interface IThirdService<T> {
    void Do(T m);
    void DoOther(T m);
}

class Service : ISomeService<IMessage>, IOtherService<Message>, 	   
    IThirdService<?> {
    public void Do(IMessage m);
    void DoOther(Message m);
}

Решение этой проблемы достаточно очевидно – с самого начала использовать одну из 2-х сущностей везде – класс или интерфейс (для DTO в C# удобно использовать record).

Если вы уже попали в эту ловушку, то можно попробовать привести меньшую по объему ветку кода к общему типу данных.

Эта проблема кажется игрушечной. Однако, чтобы ее решить, вам нужно будет потратить значительную часть времени соизмеримую с объемом кода, на котором она наблюдается. Причем вам потребуется признать себя идиотом (ведь это идиотская проблема, так?). Это спровоцирует вас не решать ее, когда вы поймете, что что-то не так. И так до тех пор, пока вы не столкнетесь с чем-то похожим на пример выше, когда игнорировать проблему уже невозможно. Тогда вы поймете, что вы попали в ловушку.