Мне кажется, что мне не хватает опыта хорошего дизайна, и я могу слишком усложнить ситуацию, дайте мне знать, если я это сделаю:)
Давайте рассмотрим пример сущности User и репозитория User.Я начну с репозитория
class UserRepository {
public function save(User $user) {
if($user->getStatus() == User::STATUS_NEW)
$this->getDataAccessObject()->insert($user->getState());
else
$this->getDataAccessObject()->update($user->getState());
$user->setStatus(User::STATUS_MANAGED);
}
}
И сам пользователь
class UserEntity {
const STATUS_NEW = 1;
const STATUS_MANAGED = 2;
private $_status = self::STATUS_NEW;
private $_state = array();
public static function create($username, $password) {
return new UserEntity(array('Username' => $username, 'Password' => $password));
}
public function __construct(array $state) {
$this->_state = $state;
}
public function getState() {
return $this->_state;
}
public function getStatus() {
return $this->_status;
}
public function setStatus($status) {
$this->_status = $status;
}
}
Так мало примечаний к коду, прежде чем я задам вопрос:
Его php (жесткий должен быть легким для понимания для всех, кто владеет C ++ \ C # \ Java)
Я опустил базовые классы (такие как абстрактный Repository и абстрактный Entity, из которых UserRepository и UserEntityнаследует) для простоты примера.
Я отказался от фабричного шаблона объекта / класса и вместо этого предпочитаю использовать фабричный шаблон метода внутри самого объекта Entity.
Заводской метод выглядит избыточным в этом примере и может быть заменен на
$ user = UserEntity (array ('Username' => $ username, 'Password' => $ password));
Но на самом деле все немного сложнее, поскольку фабрика принимает "необработанные" данные (например, из формы POST) и создает все необходимые объекты Entity или Value, чтобы затем создать действительный пользовательский объектмеч внутри сущности может быть не реальным паролем, а объектом-значением, который содержит хэш пароля, а не пароля).
Теперь к вопросу:
Я не закончил с моимЯ в том, что я предоставляю миру методы getState () и setStatus ().Эти методы должны использоваться только внутри репозитория, но поскольку они общедоступны, ничто не запрещает мне получать доступ к состоянию сущности и / или изменять его статус в любом месте.Опять же, это может быть из-за реакции и из-за усложнения вещей, но я чувствую, что это неправильно.
Единственное «решение», которое я нахожу, - это передать все через хранилище, что-то вроде
class Entity {
public static function create($identity, $param1, $param2, Repository $r) {
$state = $r->getNewState($identity, $param1, $param2);
return new Entity($state);
}
private $_state = null;
public function __construct(State $state) {
$this->_state = $state;
}
public function getIdentity() {
$this->_state->getIdentity();
}
}
class Repository {
private $_states = array();
public function getNewState($identity, ...) {
$state = new State($identity, ...);
$this->_states[$identity] = $state;
return $state;
}
public function save(Entity $entity) {
$id = $entity->getIdentity();
//maybe check if such entity is managed by this repository..
if($this->_states[$id]->getStatus() === State::STATUS_NEW)
$this->getDataAccessObject()->insert($this->_states[$id]->toArray());
else
$this->getDataAccessObject()->update($this->_states[$id]->toArray());
$this->_states[$id]->setStatus(State::STATUS_MANAGED);
}
}
class State {
const STATUS_NEW = 1;
const STATUS_MANAGED = 2;
private $_state = array()
private $_identity = 'something';
public function getIdentity() {
return $this->_state[$this->_identity];
}
public function toArray() {
return $this->_state;
}
}
Это выглядит «более правильным» для меня, так как здесь я не раскрываю внутреннее состояние сущности, и об этом знает только хранилище.
Так что вы думаете?Является ли раскрытие внутреннего состояния сущности в порядке?Или, может быть, второй пример - лучший способ спроектировать такую систему?Или, может быть, вы знаете лучшие способы?
Большое спасибо!