c = game.makeMoveCommand(NORTH);
else if (command.equalsIgnoreCase("s"))
c = game.makeMoveCommand(SOUTH);
else if (command.equalsIgnoreCase("r"))
c = game.makeRestCommand();
else if (command.equalsIgnoreCase("sw"))
c = game.makeShootCommand(WEST);
else if (command.equalsIgnoreCase("se"))
c = game.makeShootCommand(EAST);
else if (command.equalsIgnoreCase("sn"))
c = game.makeShootCommand(NORTH);
else if (command.equalsIgnoreCase("ss"))
c = game.makeShootCommand(SOUTH);
else if (command.equalsIgnoreCase("q"))
return;
c.execute();
}
}
Отметьте также, что функция main создает поток ввода и содержит главный цикл игры, в котором происходит интерпретация простых команд, но их обработка поручается другим, высокоуровневым компонентам.
Наконец, посмотрите, как main создает карту подземелий.
private static void createMap() {
int nCaverns = (int) (Math.random() * 30.0 + 10.0);
while (nCaverns-- > 0)
caverns.add(makeName());
for (String cavern : caverns) {
maybeConnectCavern(cavern, NORTH);
maybeConnectCavern(cavern, SOUTH);
maybeConnectCavern(cavern, EAST);
maybeConnectCavern(cavern, WEST);
}
String playerCavern = anyCavern();
game.setPlayerCavern(playerCavern);
game.setWumpusCavern(anyOther(playerCavern));
game.addBatCavern(anyOther(playerCavern));
game.addBatCavern(anyOther(playerCavern));
game.addBatCavern(anyOther(playerCavern));
game.addPitCavern(anyOther(playerCavern));
game.addPitCavern(anyOther(playerCavern));
game.addPitCavern(anyOther(playerCavern));
game.setQuiver(5);
}
// здесь следует еще много кода...
}
Компонент Main — самый грязный низкоуровневый модуль, находящийся во внешнем круге чистой архитектуры. Он загружает все, что потребуется системе более высокого уровня, а затем передает ей управление.
Заключение
Представьте, что Main является плагином для приложения — плагином, который настраивает начальное окружение, загружает все внешние ресурсы и затем передает управление политике верхнего уровня. Так как это плагин, может иметься множество компонентов Main, по одному для каждой конфигурации приложения.
Например, у нас может иметься плагин Main для разработки, еще один для тестирования и третий для эксплуатации. Можно также создать по плагину Main для каждой страны, или каждой юрисдикции, или каждого клиента.
Когда вы начинаете думать о компоненте Main как о плагине, находящемся за архитектурной границей, проблемы настройки решаются намного проще.
Глава 27. Службы: большие и малые
Сервис-ориентированные «архитектуры» и микросервисные «архитектуры» приобрели особую популярность в последнее время. Эта популярность обусловлена, в том числе, следующими причинами:
• Службы выглядят полностью независимыми друг от друга. Но, как мы увидим далее, это верно лишь отчасти.
• Службы, похоже, можно разрабатывать и развертывать независимо. И снова, как мы увидим далее, это верно лишь отчасти.
Сервисная архитектура?
Прежде всего уточним, что утверждение, будто использование служб по своей природе является архитектурой, в принципе неверно. Архитектура системы определяется границами, отделяющими высокоуровневые политики от низкоуровневых деталей, и следованием правилу зависимостей. Службы, просто делящие приложение на функциональные элементы, по сути, являются лишь функциями, вызовы которых обходятся довольно дорого и не обязательно имеют важное архитектурное значение.
То есть не все службы должны быть архитектурно значимыми. Часто бывает выгодно создавать службы, распределяющие функциональные возможности по разным процессам и платформам, независимо от того, подчиняются ли они правилу зависимостей. Службы сами по себе не определяют архитектуру.
Наглядной аналогией является организация функций. Архитектура монолитной или компонентной системы определяется некоторыми вызовами функций, пересекающими архитектурные границы и следующими правилу зависимостей. Однако многие другие функции в системе просто отделяют одно поведение от другого и не являются архитектурно значимыми.
То же верно в отношении служб. Службы, в конечном счете, — это всего лишь вызовы функций через границы процессов и/или платформ. Некоторые из этих служб действительно являются архитектурно значимыми, а другие — нет. Основной интерес для нас в этой главе представляют первые.
Преимущества служб?
Знак вопроса в заголовке указывает, что в этом разделе мы поставим под сомнение популярное мнение о сервис-ориентированной архитектуре. Давайте рассмотрим предполагаемые преимущества по одному.
Заблуждение о независимости
Одно из самых больших предполагаемых преимуществ деления системы на службы заключается в полной независимости их друг от друга. В конце концов, каждая служба выполняется в отдельном процессе или даже на другой машине; поэтому службы не имеют доступа к переменным друг друга. Более того, для каждой службы должен быть четко определен ее интерфейс.
Все это верно до определенной степени, но не до конца. Да, службы независимы на уровне отдельных переменных. Но они все еще могут быть связаны вместе общими ресурсами на одной машине или в сети. Более того, они тесно связаны общими данными.