Skip to content

Instantly share code, notes, and snippets.

@tomphp
Last active August 29, 2015 14:05
Show Gist options
  • Save tomphp/6ab886465a0626a352a3 to your computer and use it in GitHub Desktop.
Save tomphp/6ab886465a0626a352a3 to your computer and use it in GitHub Desktop.
<?php
/*
* Say you have an entity class which has no need to expose its internal data
* fields in the business layer like so:
*/
class LibraryBook
{
/** @var string */
private $title;
/** @var bool */
private $isOnLoan;
/** @var int */
private $numberOfPages;
/**
* @param string $title
* @param bool $isOnLoan
* @param int $numberOfPages
*/
public function __construct($title, $isOnLoan, $numberOfPages)
{
$this->title = $title;
$this->isOnLoan = $isOnLoan;
$this->numberOfPages = $numberOfPages;
}
public function checkOut()
{
$this->isOnLoan = true;
}
public function checkIn()
{
$this->isOnLoan = false;
}
/** @param int $numberOfPages */
public function ripOutPages($numberOfPages)
{
$this->numberOfPages -= $numberOfPages;
}
}
/*
* How do you prefer to expose the internal fields for display & for your
* storage layer to access them?
*/
// Option 1: Add getters
class LibraryBook
{
// ...
public function getTitle()
{
return $this->title;
}
public function isOnLoan()
{
return $this->isOnLoan;
}
public function getNumberOfPages()
{
return $this->numberOfPages;
}
}
// Option 2: Return an array
class LibraryBook
{
// ...
public function asArray()
{
return [
'title' => $this->title,
'onLoan' => $this->isOnLoan,
'numberOfPages' => $this->numberOfPages
];
}
}
// Option 3: Return a DTO
// As Option 2 but return a BookDetails DTO object instead of a PHP array
class BookDetails
{
/** @var string */
private $title;
/** @var bool */
private $isOnLoan;
/** @var int */
private $numberOfPages;
/**
* @param string $title
* @param bool $isOnLoan
* @param int $numberOfPages
*/
public function __construct($title, $isOnLoan, $numberOfPages)
{
$this->title = $title;
$this->isOnLoan = $isOnLoan;
$this->numberOfPages = $numberOfPages;
}
public function getTitle()
{
return $this->title;
}
public function isOnLoan()
{
return $this->isOnLoan;
}
public function getNumberOfPages()
{
return $this->numberOfPages;
}
}
class LibraryBook
{
// ...
public function getDetails()
{
return new BookDetails(
$this->title,
$this->isOnLoan,
$this->numberOfPages
);
}
}
// Option 4: Ask the entity to present it's data via an interface
interface BookDetailsReceiver
{
/** @param $title string */
public function setTitle($title);
/** @param $isOnLoan bool */
public function setOnLoanStatus($isOnLoan);
/** @param $numPages int */
public function setNumberOfPages($numPages);
}
class LibraryBook
{
// ...
public function presentDetails(BookDetailsReceiver $receiver)
{
$receiver->setTitle($this->title);
$receiver->setOnLoanStatus($this->isOnLoan);
$receiver->setNumberOfPages($this->numberOfPages);
}
}
// Option 5: Some other way, please describe
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment