Не могу понять «противоречие» в статье Роберта Мартина о интернет-провайдере. - PullRequest
2 голосов
/ 06 мая 2020

Я прочитал статью Роберта Мартина о принципе разделения интерфейсов здесь . В конце статьи, решая проблему с архитектурой пользовательского интерфейса банкомата, он заявил:

Учтите также, что каждая отдельная транзакция, которую может выполнять банкомат, заключена как производная от класса Transaction. Таким образом, у нас могут быть такие классы, как DepositTransaction, WithdrawlTransaction, TransferTransaction, et c. Каждый из этих объектов отправляет сообщение на UI. Например, объект DepositTransaction вызывает функцию-член RequestDepositAmount класса UI. В то время как объект TransferTransaction вызывает функцию-член RequestTransferAmount для UI. Это соответствует диаграмме на Рисунке 5.

Обратите внимание, что это точно та ситуация, которую провайдер советует нам избегать. Каждая транзакция использует часть UI, которую не использует ни один другой объект. Это создает возможность того, что изменения в одной из производных от Transaction вызовут соответствующее изменение на UI, тем самым повлияв на все другие производные от Transaction и любой другой класс, который зависит от интерфейса UI.

Итак, мы имеем следующую ситуацию: если одна из производных Transaction изменяется, то UI изменяется и любой другой класс, использующий UI, также изменяется.

Затем эта проблема решается следующими изменениями:

Этого неудачного сцепления можно избежать, разделив интерфейс пользовательского интерфейса на отдельные абстрактные базовые классы, такие как DepositUI, WithdrawUI и TransferUI. Эти абстрактные базовые классы затем могут быть многократно унаследованы в последний абстрактный класс UI. На рисунке 6 и в листинге 6 показана эта модель.

Но затем Роберт Мартин заявляет, что:

Это правда, что всякий раз, когда создается новая производная от класса Transaction, Для абстрактного UI-класса потребуется соответствующий базовый класс. Таким образом, UI-класс и все его производные должны измениться. Однако эти классы не получили широкого распространения. В самом деле, они, вероятно, используются только основным или каким-либо другим процессом, загружающим систему и создающим конкретный экземпляр пользовательского интерфейса. Таким образом, влияние добавления новых базовых классов пользовательского интерфейса сдерживается.

И вот вопрос: как это возможно, что UI изменился, но никакие другие классы тоже не изменились? В конце концов, если какой-то TransactionX использует XUI, а XUI является суперклассом UI и UI изменяется (из-за какого-то ZUI), то (насколько мне известно) компилятор также необходимо перекомпилировать все классы, которые используют XUI, потому что vtable (в терминах C ++) или, возможно, некоторые базовые адреса функций были изменены путем изменения UI. Может ли кто-нибудь очистить его для меня?

1 Ответ

0 голосов
/ 06 мая 2020

если какой-то TransactionX использует XUI, а XUI является суперклассом пользовательского интерфейса и пользовательский интерфейс изменен, то (насколько мне известно) компилятору необходимо перекомпилировать все классы, которые тоже используют XUI

Да, но в данном случае только TransactionX зависит от XUI. Все остальные TransactionY и YUI не затронуты, и их не нужно перекомпилировать.

, потому что vtable (в терминах C ++) или, возможно, некоторые базовые адреса функций были изменены путем изменения пользовательского интерфейса .

Вы бы перекомпилировали main (или ui_globals.cc в тексте), где получается адрес интерфейсов X/Y/Z UI для передачи экземплярам Transaction X/Y/Z.

...