У меня есть репозиторий для моих бизнес-объектов, и мне нужно создавать различные объекты на основе данных. Должен ли я создать их непосредственно в репо или переместить этот код куда-нибудь еще — на фабрику или в какой-нибудь класс на уровне бизнес-логики?
/**
* @returns Applier
*/
class ApplierRepository implements IApplierRepositoryInterface {
//some code
public function find($id) {
$data = $this->findBySql($id);
//Is it a business logic?
if($data['profile_id'] != null)
$object = new ProfileApplier();
if($data['user_id'] != null) {
$user = $this->userRepository->find($data['user_id']);
$object = new UserApplier($user);
}
//...
return $object;
}
}
Я бы посчитал вместилище как уровень абстракции между Уровень доступа к данным и ваш логика приложения.
Что у вас есть в вашем находить() Метод на самом деле Заводской метод.
Чтобы было понятно, представьте, что вам нужно проверить логику вашего класса с тестирование ramework. Чтобы ты делал? Похоже твой ProfileApplier, UserApplier и другие заявители называют некоторые источники данных получить пользовательские данные.
В тестовых методах вам необходимо заменить эти источники данных на тестовые. Вам также необходимо заменить методы доступа к источникам данных. И это то, что вместилище шаблон предназначен для.
Более чистый подход будет выглядеть примерно так:
class AppliersFactory {
IApplierRepository applierRepository;
public AppliersFactory(IApplierRepository repo)
{
$this->applierRepository = repo;
}
// factory method, it will create your buisness objects, regardless of the data source
public function create($data) {
if($data['profile_id'] != null)
$return new ProfileApplier();
if($data['user_id'] != null) {
$user = $this->applierRepository->find($data['user_id']);
$object = new UserApplier($user);
}
//...
return $object;
}
}
использовать этот репозиторий в вашем реальном приложении
class RealApplierDataStorageRepository implements IApplierRepositoryInterface {
//some code, retrieves data from real data sources
public function find($id) {
//...
}
}
и использовать этот в тестовых модулях, чтобы проверить свою логику
class TestApplierDataStorageRepository implements IApplierRepositoryInterface {
// some code, retrieves data from test data sources (lets say, some arrays of data)
public function find($id) {
//...
}
}
Надеюсь, поможет
Других решений пока нет …