Вопрос о дизайне: Как я могу прозрачно получить доступ к механизму IPC?

#language-agnostic #design-patterns #ipc #soa #rpc

Вопрос:

Я хочу сделать это (без определенного языка):

 print(foo.objects.bookdb.books[12].title);
 

или это:

 book = foo.objects.bookdb.book.new();
book.title = 'RPC for Dummies';
book.save();
 

Где foo на самом деле является службой, подключенной к моей программе через некоторый IPC, и для доступа к ее методам и объектам некоторый уровень фактически отправляет и получает сообщения по сети.

Теперь я на самом деле не ищу механизм IPC, так как есть из чего выбирать. Скорее всего, он будет основан не на XML, а на чем-то вроде буферов протоколов Google, dbus или CORBA. В чем я не уверен, так это в том, как структурировать приложение, чтобы я мог получить доступ к IPC так же, как к любому объекту.

Другими словами, как у меня может быть ООП, которая прозрачно отображает границы процессов?

Не то чтобы это был вопрос дизайна, и я все еще работаю на довольно высоком уровне общей архитектуры. Так что я пока довольно скептически отношусь к тому, на каком языке это будет. Однако C#, Java и Python, скорее всего, будут использованы.

Ответ №1:

Я думаю, что способ сделать то, что вы просите, состоит в том, чтобы вся связь с объектами рассматривалась как передача сообщений. Именно так методы объектов обрабатываются, в частности, в ruby и smalltalk.

С передачей сообщения (а не вызовом метода) в качестве механизма связи с объектом, Такие операции, как вызов метода, которого не существовало при написании кода, становятся разумными, поскольку объект все равно может сделать что-то разумное с сообщением (проверьте удаленную процедуру, верните значение для поля с тем же именем из базы данных и т. Д. Или Создайте исключение «метод не найден» или что-нибудь еще, о чем вы могли бы подумать).

Важно отметить, что для языков, которые не используют это в качестве механизма по умолчанию, вы все равно можете передавать сообщения (у каждого объекта есть метод handleMessage), но вы не получите тонкости синтаксиса, и вы не сможете получить помощь IDE без дополнительных усилий с вашей стороны, чтобы заставить IDE проанализировать ваш метод handleMessage для проверки допустимых входных данных.

Ответ №2:

Ознакомьтесь с RMI Java-вводный материал показывает, как вы можете получить локальное определение удаленного объекта.

Хитрость заключается в том, чтобы иметь два класса с одинаковыми сигнатурами методов. Локальная версия класса является фасадом по некоторому сетевому протоколу. Удаленная версия получает запросы по сети и выполняет фактическую работу объекта.

Вы можете определить пару классов, чтобы клиент мог иметь

 foo= NonLocalFoo( "http://host:port" )
foo.this= "that"
foo.save()
 

И сервер получает запросы метода set_this() и save() от клиентского соединения. Серверная сторона (как правило) нетривиальна, потому что у вас есть множество проблем с обнаружением и управлением экземплярами.

Ответ №3:

Ты не должен этого делать! Программистам очень важно видеть и чувствовать разницу между IPC/RPC и вызовом локального метода в коде. Если вы сделаете так, что им не придется думать об этом, они не будут думать об этом, и это приведет к очень плохой работе кода.

Думать о:

 foreach o, o.isGreen in someList { 
   o.makeBlue; 
}
 

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

Комментарии:

1. Да, это хороший аргумент. Я тоже уже думал об этом. Однако это легко исправить с помощью соглашений об именах. Если это всегда похоже на someIpcList или ipcFoo.bar(), вы знаете, что происходит. Я разрабатываю не для произвольного языка / фреймворка, а для конкретного приложения и конкретной команды.

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