Как реализовать фабрику моделей в рамках, которые используют активные записи? - PullRequest
0 голосов
/ 12 февраля 2019

Итак, в моем фреймворке X, пусть это будет Phalcon , я часто создаю модели объектов.

Давайте предположим, что все поля уже проверены.Вопросы, связанные только с логикой создания.

Простой пример создания Users объекта и его сохранения в БД:

<?php

$user = new Users();
$user->setName($name);
$user->setLastName($lastname);
$user->setAge($age);
$user->create();

Для простоты я покажу здесьВсего 3 поля для настройки, в реальном мире их всегда больше.

У меня есть 3 вопроса:

1) Как лучше всего инкапсулировать эту логику в класс Factory ?Если я создам Factory класс, который будет создавать объекты, такие как Users object, каждый раз, когда мне потребуется передать большое количество параметров.

Пример:

<?php

$factory = new UsersFactory();
$factory->make($name, $lastname, $address, $phone, $status, $active);

2) Даже если я реализую Factory способом, показанным выше - должен ли Factory вставлять данные в БД?В моем примере вызов метода create () ?Или просто выполнить все операции установки?

3) И даже более того, что если мне нужно будет создать Users объекты с отношениями, с другими связанными объектами?

Спасибоза любые предложения.

Ответы [ 2 ]

0 голосов
/ 14 февраля 2019

Я не думаю, что совершенно необходимо использовать конструктор или "шаблон" для динамического заполнения свойств вашей модели.Хотя это субъективно к тому, что вы после.

Вы можете заполнять модели через конструктор следующим образом:

$user = new Users([
    'name' => $name,
    'lastName' => $lastname,
    'age' => $age,
]);
$user->create();

Таким образом, вы можете динамически заполнять модель, создавая массив вместо многочисленных вызовов методов.


Стоит также отметить, что если вы хотите использовать методы "setters" и "getter", вы должны определить свойства как protected.Причина этого в том, что Phalcon будет автоматически вызывать методы set / get, если они существуют, когда вы присваиваете значение защищенному свойству.

Например:

class User extends \Phalcon\Mvc\Model
{
    protected $name;

    public function setName(string $name): void
    {
        $this->name = $name;
    }

    public function getName(): string
    {
        return $this->name;
    }
}

$user= new MyModel();
$user->name = 'Cameron'; // This will invoke User::setName
echo $user->name; // This will invoke User::getName

Стоит также отметить, что свойства будут вести себя так, как вы ожидаете, что защищенное свойство будет вести себя так же, как традиционное защищенное свойство, если соответствующий методотсутствует.Например, вы не можете присвоить значение защищенному свойству модели без метода установки.

0 голосов
/ 12 февраля 2019

Ваш вопрос начинается с простого, а затем строится со сложностью.Когда вы читаете ваш пост, это звучит так, как будто вы обеспокоены количеством аргументов, которые вам нужно будет передать методу для создания объекта.Это разумный страх, так как вам следует избегать функций, которые принимают более 2 или 3 аргументов, и потому что иногда вам нужно будет передать 1-й 3-й и 5-й аргумент, а не 2-й и 4-й, что просто становится неудобным.

Вместо этого я бы посоветовал вам взглянуть на шаблон строителя.

В конце концов, он не будет сильно отличаться от простого использования вашего User объекта, однако это поможет вам избежать использования Userобъект в недопустимом состоянии (обязательные поля не установлены)

1) Каков наилучший способ инкапсулировать эту логику в классе Factory?Если я создаю класс Factory, который будет создавать такие объекты, как объект Users, каждый раз, когда мне потребуется передавать большое количество параметров.

Именно поэтому я рекомендовал шаблон построителя.Чтобы избежать передачи большого количества параметров в одну функцию.Это также позволит вам проверять состояние в методе сборки и обрабатывать или генерировать исключения.

class UserBuilder {
  protected $data = [];
  public static function named($fname, $lname) {
    $b = new static;
    return $b
      ->withFirstName($fname)
      ->withLastName($lname);
  }
  public function withFirstName($fname) {
    $this->data['first_name'] = $fname;
    return $this;
  }
  public function withFirstName($lname) {
    $this->data['last_name'] = $lname;
    return $this;
  }
  public function withAge($age) {
    $this->data['age'] = $age;
    return $this;
  }
  public function build() {
    $this->validate();
    $d = $this->data;
    $u = new User;
    $u->setFirstName($d['first_name']);
    $u->setLastName($d['last_name']);
    $u->setAge($d['age']);
    return $u;
  }
  protected function validate() {
    $d = $this->data;
    if (empty($d['age'])) {
      throw new Exception('age is required');
    }
  }
}

тогда вы просто делаете ..

$user = UserBuilder::named('John','Doe')->withAge(32);

сейчас вместо числа аргументов функцииС каждым параметром число методов растет.

2) Даже если я реализую Factory так, как показано выше - должна ли Factory вставлять данные в БД?В моем примере вызов метода create ()?Или просто выполнить все операции установки?

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

3) И даже больше, что если мне понадобится создавать объекты Users с отношениями, с другими связаннымиобъекты?

В Phalcon эти отношения являются частью сущности.Вы можете увидеть в их документах этот пример:

// Create an artist
$artist = new Artists();

$artist->name    = 'Shinichi Osawa';
$artist->country = 'Japan';

// Create an album
$album = new Albums();

$album->name   = 'The One';
$album->artist = $artist; // Assign the artist
$album->year   = 2008;

// Save both records
$album->save();

Итак, чтобы связать это с примером пользователя, предположим, что вы хотели сохранить информацию об адресе пользователя, но адреса хранятся вдругой стол.Построитель может предоставлять методы для определения адреса, а метод сборки будет создавать обе сущности вместе и возвращать построенный объект User, который имеет ссылку на объект Address внутри него, из-за того, как работают модели Phalcon.

...