Подтвердить что ты не робот

Понимание объекта домена + шаблон карты данных?

Я всегда работал с различными ORM в прошлом и размещал всю свою логику внутри своих моделей независимо от ее природы - запросы SQL, MongoDB и даже выборку удаленных объектов JSON. Но когда необходимо обеспечить свободные сцепления, чтобы обеспечить высокий уровень проверки, проблемы этой методологии быстро появляются.

Сегодня я читал о разделении моделей на две части: Domain objects и Data mappers.
Если я полностью его понял, Domain objects полностью не знают о используемом хранилище и вместо этого существует для обработки бизнес-логики. Data mappers, с другой стороны, заботится о сохранении набора данных в Domain objects в установленном хранилище данных.

Однако мне сложно найти хороший, простой в понимании пример онлайн о том, как работать с DomainObjects и DataMappers в реальном мире.

Будет ли это (ниже показанный код) подходящим способом работы с DomainObjects и DataMappers в моем коде для хранения пользователей или у меня все в голове?

$user = new User_DO;
$userSave = new User_DM;
$userSave->store( $user->add(array('name' => 'John Doe')) );

class User_DO {

    function add($array) {
        if(!isset($array['name'])) {
            throw new Exception("Name must be set");
        }

        return $array;

    }

}

class User_DM {

    function store($array) {
        MyDatabase::execute("INSERT INTO...");
    }

}
4b9b3361

Ответ 1

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

class person_DO {
    public $id;
    public $firstname;
    public $lastname;
    public $addresses;
}

Загрузка экземпляров этой модели домена (объектов домена) и персистентности осуществляется с помощью карт данных - например, адрес вышеуказанного человека может быть расположен в другой таблице через отношение 1: n, как таковое:

TABLE person {
    id        INTEGER PRIMARY KEY,
    firstname VARCHAR(32),
    lastname  VARCHAR(32)
}

TABLE addresses {
    id INTEGER PRIMARY KEY,
    person_id  INTEGER FOREIGN KEY ON person.id, --Reference on person-row
    street     VARCHAR(64),
    ...
}

Person_DO не нужно знать об этом, но datamapper делает это, поскольку он должен собирать данные во время загрузки и разделить при сохранении:

class person_DM {
    /**
     * @param  [integer] $id
     * @return [person_DO] an instance of a person or null, if no person
     *                     with that id was found.
     */
    public function findById ($id) {...}

    /**
     * @return [array of person_DO]
     */
    public function fetchAll() {...}

    /**
     * persists a person object
     * @param [person_DO] an instance of a person
     */
    public function saveOrUpdate(person_DO $person) {...}
}

Чтобы разделить разные части еще больше, DataMappers обычно используют шлюз DbTable или аналогичный шаблон, позволяющий использовать разные базы данных или подобные действия. Таким образом, я могу иметь несколько баз данных с одинаковыми схемами, но, например, в разных организациях создать хранилище данных с тем же кодом, только разные объекты базы данных.

В качестве практического примера я бы предложил посмотреть Учебное пособие по быстрому запуску в Zend Framework, которое делает именно то, что я только что объяснил кратко.

Ответ 2

Примерный способ, да. Хотя я бы настоятельно рекомендовал не изобретать колесо и использовать сложный ORM, например Doctrine 2.x, которые реализуют такой шаблон. Вы можете посмотреть их документацию (Глава 8: Работа с объектами), чтобы пробовать интерфейс.