Skip to content

Instantly share code, notes, and snippets.

@gemmadlou
Last active October 28, 2017 15:49
Show Gist options
  • Select an option

  • Save gemmadlou/c70e17eab437ef3d644dcc3b9d3485d7 to your computer and use it in GitHub Desktop.

Select an option

Save gemmadlou/c70e17eab437ef3d644dcc3b9d3485d7 to your computer and use it in GitHub Desktop.
Rehydrating A Domain Object (Model)

Why Rehydrate Models In The First Place?

The problem

You've gone to lengths to model your domain with the correct behaviours, the common language and the business constraints.

For example, for a music venue, here'd be a simple model.

class Show {

  private $date;
  private $headlineAct;
  private $openingAct;
  private $ticketOptions;

  private function __construct() {}

  public static function book($date, $headlineAct, $openingAct)
  {
    if (!$date || !$headlineAct || !$openingAct) {
      throw new Exception('You cannot book a show unless you have a date, a headline and opening act');
    }
    $this->date = $date;
    $this->headlineAct = $headlineAct;
    $this->openingAct;
  }

  public function prepareTickets(TicketOptions $ticketOptions)
  {
    $this->ticketOptions = $ticketOptions;
  }
}

Okay, this might be a stupid scenario - because why would a venue only limit themselves to 1 headline and 1 opening act. However, this is just an example.

Now, when you first set up a new show, you call that initial function:

Show::book('2019-10-11 19:00', 'The Bombardiers', 'Just Another Garage Band');

Later, you finally set ticket options, whatever they maybe:

$show->prepareTickets(new TicketOptions(100, '£5.95'));

Note: I know putting £5.95 is not good, but it's just for verbosity here.

Questions:

Do I really need to call that initial method again php Show::book(...yadda yadda)? What if I've gone through several changes that alter the Show model? Do I need to go through all those business constraints?

What I want to do is this:

$id = 104;
$show = $repository->findBy($id); //Show model from database - regardless of what changes have been made.
$show->prepareTickets(new TicketOptions(100, '£5.95'));
$repository->save($show);

The (A) Solution

Okay, you don't need a repository, but somehow, we need to get back all that information. The process is simple. You create a rehydration method.

$data = SomeORM::find('show', 104);
$hydrate = [
  'date' => $data['date'],
  'headlineAct' => $data['headline_act'],
  'openingAct' => $data['opening_act']
];
$show = Show::hydrate($hydrate);

So now you have a model based on what was persisted. And now you can make modifications:

$data = SomeORM::find('show', 104);
$hydrate = [
  'date' => $data['date'],
  'headlineAct' => $data['headline_act'],
  'openingAct' => $data['opening_act']
];
$show = Show::hydrate($hydrate);
$show->prepareTickets(new TicketOptions(100, '£5.95'));
SomeORM::save('show', $show);

I'm foolish sometimes. I had a real day racking my brain trying to understand this. All I wanted to do was rebuild my model without having to go through business constraints which - while this example is nice, the reality may not be so.

Hope you found this useful.

<?php
class Name {
public $name;
public function __construct($name) {
$this->name = $name;
}
}
class Product {
private $name;
private $sku;
private $price;
public function __construct(Name $name, $sku, $price)
{
$this->setName($name);
$this->sku = $sku;
$this->price = $price;
}
public function name()
{
return $this->name;
}
public function __set($key, $value)
{
$this->{"set" . ucfirst($key)}($value);
}
private function setName(Name $name)
{
$this->name = $name;
}
}
$item = new Product(new Name('Playstation'), '123123', 200);
echo '<pre>';
//print_r($item);
print_r($item->name());
$item->__set('name',new Name('XBox'));
print_r($item->name());
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment