Skip to content

Instantly share code, notes, and snippets.

@manuelpichler
Last active December 21, 2015 17:49
Show Gist options
  • Save manuelpichler/6343390 to your computer and use it in GitHub Desktop.
Save manuelpichler/6343390 to your computer and use it in GitHub Desktop.
Immutable objects and the builder pattern.
<?php
interface ImmutableObject {
public function getMandatory();
public function getOptional();
}
interface ImmutableObjectBuilder {
public function setOptional($optional);
/**
* @return ImmutableObject
*/
public function build($mandatory);
}
class MyObject implements ImmutableObject {
private $mandatory;
private $optional;
public function __construct($mandatory) { $this->mandatory = $mandatory; }
public function getMandatory() { return $this->mandatory; }
public function getOptional() { return $this->optional; }
public function setOptional() { $this->optional = $optional; }
}
class MyObjectBuilder {
private $optional;
public function setOptional() { $this->optional = $optional; }
/**
* @return ImmutableObject
*/
public function build($mandatory)
{
$object = new MyObject($mandatory);
if ($this->optional) {
$object->setOptional($this->optional);
}
return $object;
}
}
<?php
interface ImmutableObjectBuilder {
public function setOptional($optional);
/**
* @return ImmutableObject
*/
public function build($mandatory);
/**
* @return ImmutableObject
*/
public function modify(ImmutableObject $object);
}
class MyObjectBuilder {
private $optional;
public function setOptional() { $this->optional = $optional; }
/**
* @return ImmutableObject
*/
public function build($mandatory)
{
return $this->modify(new MyObject($mandatory));
}
/**
* @return ImmutableObject
*/
public function modify(ImmutableObject $object)
{
if ($this->optional) {
$object->setOptional($this->optional);
}
return $object;
}
}
<?php
class MyObjectService
{
private $converter;
/**
* @var \ImmutableObjectBuilder
*/
private $builder;
/**
* @return \ImmutableObject
*/
public function load($id)
{
$dataObject = $this->repository->find($id);
return $this->converter->toDomain($dataObject);
}
public function modify(\ImmutableObject $object, $optional)
{
// Some domain rule checks on $optional
$this->builder->setOptional($optional);
$object = $this->builder->modify($object);
$this->repository->persist($this->converter->fromDomain($object));
return $object;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment