Правильное разделение интерфейсов

299
24 апреля 2017, 01:11

Есть legacy проект и массивные классы моделей, где они представлены как есть. В них много свойств которые можно разделить на множество разных интерфейсов (сегрегация интерфейсов).

class FatModel : IFoo, IBar, IZaa...

Требуется передать экземпляр этого класса в слой приложения где нужен IFoo и немного IBar

И тут напрашиваются варианты

  1. Создать обобщенный интерфейс.

    interface IFooBar : IFoo, IBar
    class FatModel : IFooBar, IZaa...
    

    Но получается ерунда, потому что эти обобщенные интерфейсы плодятся как кролики. Создав обобщенный интерфейс на 2 интерфейса обязательно появится тот, кому нужны 3 или другие 2...и в разных комбинациях.

  2. Передать объект как есть и в нужных местах делать каст к нужному интерфейсу.

    Но в этом случае все проверки типов уходят в рантайм, что плохо.

  3. Адаптеры, где будут представлены нужные свойства?

    Никогда не делал адаптеров для моделей и полезности такого решения не знаю.

Какие есть еще варианты?

Answer 1

Начнём с того, что интерфейс (и классы, его реализующие) должен отображать предметную область.

Требуется передать экземпляр этого класса в слой приложения где нужен IFoo и немного IBar

Если комбинация IFoo и IBar имеет прикладное значение - её было бы нелишним ввести. Тогда всё очевидно просто, правда, переписывать legacy вряд ли захочется ради этого.

Если комбинация интерфейсов прикладного значения не имеет, то и метод, который требует и того и другого одновременно - тоже не имеет прикладного значения. Простой вариант решения этой проблемы - выделение двух методов, один из которых требует IFoo, второй - IBar.

UPD: не подумал сразу, но можно же сделать генерик метод, который указывает требования:

    static void Method<T>(T obj) where T : IFoo, IBar
READ ALSO
Open Graph в битрикс

Open Graph в битрикс

Всем привет! У меня при шаринге статьи не выводится картинка детального изображенияЧто я делаю не так?

501
COM объект перестал работать PHP

COM объект перестал работать PHP

ЗдравствуйтеНа сервере стоял "Windows NT WEB2003 5

295
Call to a member function rowCount() on boolean

Call to a member function rowCount() on boolean

PHP Fatal error: Uncaught Error: Call to a member function rowCount() on boolean in /var/www/html/indexphp:30\nStack trace:\n#0 {main}\n thrown in /var/www/html/index

422