Last active
December 12, 2015 08:08
-
-
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 ]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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