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);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.