Не могу понять "противоречие" в статье Роберта Мартина о интернет-провайдере.

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

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

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

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

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

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

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

Другие вопросы по тегам