Skip to content

Instantly share code, notes, and snippets.

@AmyStephen
Last active December 12, 2015 08:08
Show Gist options
  • Save AmyStephen/4742008 to your computer and use it in GitHub Desktop.
Save AmyStephen/4742008 to your computer and use it in GitHub Desktop.
Week 2: Introducing the "Builder Design Pattern", useful for hiding the complexity of the object construction while presenting a simple-to-use access interface. [ Week 1: Proxy https://gist.github.com/AmyStephen/4693855 ]
<?php
/**
* @package Design Patterns
* @copyright 2013 Amy Stephen. All rights reserved.
* @license MIT
*
* Week 2: Builder Design Pattern ... [ Week 1: Proxy https://gist.github.com/AmyStephen/4693855 ]
*
* Useful to hide the complexity of the object construction while presenting a simple-to-use
* access interface
*
* This example demonstrates the example pattern, as follow:
*
* 1. The goal is to present a list of books, by author name, and to link to the email
* address for the author
*
* 2. The problem is the book list (MockBooksModel), author name (MockAuthorModel), and
* email (MockEmailModel) are on separate databases, so a simple join is not possible.
*
* 3. Using the Builder Design Pattern, we can hide the complexity of accessing those three
* data sources using a simple Interface (AuthorBookInterface) and concrete class
* (AuthorBooks).
*
* 4. The result, a simple API:
*
* $connect = new AuthorBooks();
* $authorBooks = $connect->get();
*
* Download this file and open it on your local website to see how it works.
*/
/**
* Mock-up for List of Book Titles and Author ID (Name and Email address on different databases)
*/
class MockBooksModel
{
/**
* Retrieve Books
*
* @return array
*/
public function get()
{
$listArray = array();
for ($i = 1; $i < 11; $i ++) {
$author_id = rand(1, 3);
$list = new stdClass();
$list->author_id = $author_id;
$list->id = $i * $author_id;
$list->title = 'Book Title ' . ($i * $author_id);
$list->text = '<p>Introductory text for the book goes here.</p>';
$listArray[] = $list;
}
return $listArray;
}
}
/**
* Mock-up Author Data is in a different Database
*/
class MockAuthorModel
{
/**
* Retrieve Author Name for Author ID
*
* @param int $author_id
*
* @return string
*/
public function get($author_id)
{
return 'Author Name' . $author_id;
}
}
/**
* Mock-up Email Data is in a different Database
*/
class MockEmailModel
{
/**
* Retrieve Author Email Address for Author ID
*
* @param int $author_id
*
* @return string
*/
public function get($author_id)
{
return 'AuthorName' . $author_id . '@example.com';
}
}
/**
* AuthorBookInterface, implement by the AuthorBooks Concrete Class
*/
interface AuthorBookInterface
{
/**
* Get List of Books, Author Name and Email
*
* @return mixed
* @throws Exception
*/
public function get();
}
/**
* AuthorBooks implements AuthorBookInterface
*/
class AuthorBooks implements AuthorBookInterface
{
/**
* Get Author's Books from the MockBooksModel
* Lookup the Author's Name using the MockEmailModel
* Lookup the Author's Email Address using the AuthorBookInterface
*
* @return array
* @throws Exception
*/
public function get()
{
/** Get all books for author */
try {
$list_model = new MockBooksModel();
$books = $list_model->get();
if (count($books) == 0) {
throw new Exception();
}
} catch (Exception $e) {
throw new Exception ('ListAdapter: Call to MockBooksModel failed.');
}
foreach ($books as $book) {
try {
$author_model = new MockAuthorModel();
$book->author_name = $author_model->get($book->author_id);
if ($book->author_name == false) {
throw new Exception();
}
} catch (Exception $e) {
throw new Exception ('ListAdapter: Call to MockAuthorModel for Author ID: '
. $book->author_id . ' failed.');
}
try {
$email_model = new MockEmailModel();
$book->author_email = $email_model->get($book->author_id);
if ($book->author_email == false) {
throw new Exception();
}
} catch (Exception $e) {
throw new Exception ('ListAdapter: Call to MockEmailModel for Author ID: '
. $book->author_id . ' failed.');
}
}
sort($books);
return $books;
}
}
/**
* Try the Builder Pattern Example:
*
* 1. Download and place file on your local server.
* 2. Open the file using your browser.
*/
$connect = new AuthorBooks();
$authorBooks = $connect->get();
/**
* Display Results: Author, linked with email address, followed by a list of their books
*/
$author = '';
foreach ($authorBooks as $item) {
if ($author == $item->author_name) {
} else {
if ($author == '') {
} else {
echo '</ul>';
}
$author = $item->author_name;
echo '<a href="mailto:' . $item->author_email . '">' . $item->author_name . '</a>';
echo '<ul>';
}
echo '<li>' . $item->title . '</li>';
}
echo '</ul>';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment