Глава 7. Стратегии распределенных вычислений 113
Отсюда следует, что интерфейсы одного и того же объекта, предназначенные для ло-
кального и удаленного доступа, должны различаться.
На роль локального интерфейса более всего подходит интерфейс с высокой степе-
нью детализации. Хороший интерфейс класса, представляющего почтовый адрес, на-
пример, должен включать отдельные методы для задания/считывания почтового кода,
наименования города, названия улицы и т.п. Достоинство интерфейса с высокой сте-
пенью детализации состоит в том, что он следует общему принципу объектной ориен-
тации, состоящему в применении множества небольших простых фрагментов кода,
которые могут сочетаться и переопределяться разными способами для пополнения
и изменения множества функций класса в будущем.
Детальный интерфейс, однако, утрачивает свои преимущества при использовании
в режиме удаленного доступа. Когда вызов метода обрабатывается медленно, несомнен-
но, целесообразнее получать значения почтового кода, наименования города и названия
улицы сразу, а не по одному. Такой интерфейс, спроектированный не с учетом гибкости
и возможности расширения, а в целях уменьшения количества вызовов, должен отли-
чаться низкой степенью детализации. Он, очевидно, гораздо менее удобен в использова-
нии, но зато более эффективен в смысле быстродействия.
Конечно, поставщики инструментальных средств наверняка будут убеждать вас в том,
что различия в использовании их фирменного промежуточного профаммного обеспечения
в локальном и удаленном режимах "практически" неощутимы. Если вызов локален, он
осуществляется с максимальной скоростью. Если же речь вдет об удаленном вызове, скорость
снижается, но вы платите эту цену только тогда, когда без удаленного вызова действительно не
обойтись. Утверждение во многом справедливо; однако нельзя обойти вниманием то прин-
ципиальное положение, что любой объект, допускающий удаленные вызовы, должен быть
снабжен интерфейсом с низкой степенью детализации, а объект, адресуемый в локальном
режиме, — интерфейсом с высокой степенью детализации. Для поддержки взаимодействия
двух объектов следует выбрать подходящий тип интерфейса. Если объект допускает воз-
можность вызова из контекста стороннего процесса, вам придется использовать менее де-
тальный интерфейс и расплачиваться усложнением модели профаммирования и потерей
гибкости. Все это имеет смысл, разумеется, только тогда, когда приобретения того стоят;
в общем же случае взаимодействия между процессами, безусловно, следует избегать.
По этим причинам нельзя просто взять фуппу классов, спроектированных в расчете
на использование в едином процессе, применить технологию CORBA или что-то подоб-
ное и заявить, что распределенное приложение готово к работе. Распределенная модель
вычислений — это нечто большее. Основывая свою стратегию распределения на классах,
вы неизбежно придете к системе, изобилующей удаленными вызовами и потому нуж-
дающейся в реализации неповоротливых интерфейсов с низкой степенью детализации.
В завершение вы с удивлением заметите, что удаленных вызовов все еще слишком много
и любая незначительная модификация кода дается с большим трудом.
Вот мы и добрались до моего Первого Закона Распределения Объектов, который гласит:
"Не распределяйте объекты!"
Хорошо, но как тогда эффективно использовать несколько процессоров? В большин-
стве случаев этого можно добиться с помощью механизма кластеризации (рис. 7.2). Раз-
местите все классы в контексте одного процесса и активизируйте несколько копий про-
цесса на разных узлах. Тогда каждый процесс будет пользоваться только локальными вы-
зовами и достигнет цели значительно быстрее. Вы сможете применить во всех классах