В нашей команде мы реализуем (как минимум, 3 или 4 года) эту идеальную идею о том, что вся бизнес-логика должна быть полностью удалена от бизнес-логики. Поэтому мы строим много услуг.
Мы верим, что в этом совершенном мире, если у вас есть определенный охват, вы создаете для него сервис. Как ранее упоминал Микаэль, «ClientsRepository» будет предоставлять SCRUD (s-search) для клиентов, только мы называем его ClientsService (как в Service, который сообщает вам все о клиентах). Здесь у вас есть угроза, что когда неосведомленный разработчик или тот, кто находится под чрезвычайным давлением или сроками, увидит код, подобный этому:
public ModifyClientResponse ModifyClient(ModifyClientRequest request){
ClientEntity clientEntity=new ClientEntity();
ModifyClientResponse clientResponse = new ModifyClientResponse();
ClientMapper mapper=new ClientMapper();
mapper.Map(request.Client, clientEntity);
clientEntity.Update();
ClientDTO responseClientDto=new ClientDTO();
mapper.Map(clientEntity, responseClient);
clientResponse.Client=responseClientDto;
return clientResponse
}
Что, я думаю, довольно просто. И тот же разработчик получает задание: сделать что-то вроде: «когда адрес доставки клиента обновлен, нам нужно изменить его адресные данные в счетах, которые еще не утверждены или не отправлены», это станет примерно так:
public ModifyClientResponse ModifyClient(ModifyClientRequest request){
ClientEntity clientEntity=new ClientEntity();
ModifyClientResponse clientResponse = new ModifyClientResponse();
ClientMapper mapper=new ClientMapper();
mapper.Map(request.Client, clientEntity);
clientEntity.Update();
if(clientEntity.Address.DataModification==DataModification.Modified){
// all the silly business logics about address being changed
}
ClientDTO responseClientDto=new ClientDTO();
mapper.Map(clientEntity, responseClient);
clientResponse.Client=responseClientDto;
return clientResponse
}
Теперь никто не обвиняет того разработчика в малом масштабе, что он достаточно эффективен и хорош. Но в конечном итоге это станет катастрофой. Постоянно меняющиеся требования будут все сложнее и сложнее поддерживать, и в основном мы думаем, что они противоречат SOA и большинству принципов разработки SOLID. Снижает единую ответственность служб - все виды плохих вещей.
Тем не менее, я хотел бы вернуться к тому, что это должно происходить в «идеальном мире»: приведенный выше код у нас обрабатывается путем запуска сообщения с клиентским DTO, чтобы каждый мог его обработать. Таким образом, сервис Invoice может подключиться к «Client Modify» и, используя обработчик, выполнить адекватную обработку. Таким образом мы держим наших клиентов изолированными - они могут находиться в другом источнике данных / сервере / планете / независимо от того, что нужно.
Мы также стараемся сделать это еще более чистым, без пользовательских обработчиков сообщений, но с рабочими процессами. У нас есть встроенный механизм рабочего процесса (почти что-то вроде основы рабочего процесса Windows или jboss), который может подписываться и запускать рабочие процессы в зависимости от некоторых событий.
В настоящее время мы изучаем создание механизма правил ECA (http://en.wikipedia.org/wiki/Event_condition_action),, который сделал бы это еще более гибким. Но достаточно о нас:)
Ваша задача, если бы я ее реализовал, была бы службой, которая выполняет только CRUD и запускает сообщения, и другой службой, которая обрабатывает эти сообщения и выполняет бизнес-логику. Но это был бы идеальный подход к миру, вероятно, оценка этого напугала бы кого-нибудь наверх. И я бы сделал это самым простым способом, то есть, соединив все вместе, но поддерживая основные принципы хорошего кода, просто чтобы было менее болезненно, если бы эта система внезапно выросла до масштабного продукта открытия и закрытия банка ветви.
Вкратце: я согласен, хранилища должны быть кристально чистыми, ничего не должно быть, кроме данных.