Skip to content

Commit 8fc62e2

Browse files
committed
Initial commit including creational patterns, registry pattern, and unit tests for registry and singelton.
1 parent 8dc53fb commit 8fc62e2

16 files changed

+465
-11
lines changed

.gitignore

+3-11
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,4 @@
1-
# Bootstrap
2-
app/bootstrap*
3-
4-
# Symfony directories
51
vendor/*
6-
*/logs/*
7-
*/cache/*
8-
web/uploads/*
9-
web/bundles/*
10-
11-
# Configuration files
12-
app/config/parameters.ini
2+
build/*
3+
phpunit.xml
4+
composer.phar

composer.json

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"name": "Jeremeamia/PhpPatterns",
3+
"autoload": {
4+
"psr-0": {"Jeremeamia": "src/"}
5+
}
6+
}

phpunit.xml.dist

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit bootstrap="./test/bootstrap.php"
3+
colors="true"
4+
processIsolation="false"
5+
stopOnFailure="false"
6+
syntaxCheck="false"
7+
convertErrorsToExceptions="true"
8+
convertNoticesToExceptions="true"
9+
convertWarningsToExceptions="true"
10+
testSuiteLoaderClass="PHPUnit_Runner_StandardTestSuiteLoader">
11+
12+
<testsuites>
13+
<testsuite name="PhpPatterns">
14+
<directory>test/Jeremeamia/PhpPatterns/Test</directory>
15+
</testsuite>
16+
</testsuites>
17+
18+
<logging>
19+
<log type="junit" target="build/logs/junit.xml" logIncompleteSkipped="false" />
20+
</logging>
21+
22+
<filter>
23+
<whitelist>
24+
<directory suffix=".php">./src/Jeremeamia/PhpPatterns</directory>
25+
<exclude>
26+
<directory suffix="Interface.php">./src/Jeremeamia/PhpPatterns</directory>
27+
</exclude>
28+
</whitelist>
29+
</filter>
30+
31+
</phpunit>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
<?php
2+
3+
namespace Jeremeamia\PhpPatterns\Collection;
4+
5+
/**
6+
* The Registry Pattern
7+
*
8+
* Common Aliases: Map, Container, Collection
9+
* Related Patterns: Singleton Registry, Map
10+
*
11+
* Martin Fowler describes the Registry pattern as "A well-known object that
12+
* other objects can use to find common objects and services." In other words,
13+
* it is an object (whether a static, singleton, or instance) that contains
14+
* other objects or data, and keeps a references to those by a name or key. It's
15+
* essentially a simplified associative array with an object-oriented interface.
16+
*
17+
* Registries are commonly used to keep track of objects and data that need to
18+
* be accessed in a global or wide context. Because of this, they are often designed
19+
* to be a static or singleton class, even though that is not necessary, and is
20+
* generally discouraged.
21+
*
22+
* Also, the basic interface and functionality of a Registry can be re-used to
23+
* form the basis of other array-like patterns. Therefore, the RegistryTrait is
24+
* used by many other patterns in the PhpPatterns collection.
25+
*/
26+
trait RegistryTrait
27+
{
28+
/**
29+
* Get an object/value out of the Registry
30+
*
31+
* @param string $key The key of the object/value to retrieve
32+
* @param mixed $default The value to return if the key is missing
33+
*
34+
* @return mixed The object/value from the Registry
35+
*/
36+
public function get($key, $default = null)
37+
{
38+
return $this->has($key) ? $this->data[$key] : $default;
39+
}
40+
41+
/**
42+
* Store an object/value in the Registry
43+
*
44+
* @param string $key The key of the object/value being set
45+
* @param mixed $value The object/value to store
46+
*
47+
* @return self The instance of the Registry for chaining
48+
*/
49+
public function set($key, $value)
50+
{
51+
$this->data[$key] = $value;
52+
53+
return $this;
54+
}
55+
56+
/**
57+
* Check to see if a key exists in the Registry
58+
*
59+
* @param string $key The key of the object/value to check
60+
*
61+
* @return bool Whether or not the ey exists
62+
*/
63+
public function has($key)
64+
{
65+
return array_key_exists($key, $this->data);
66+
}
67+
68+
/**
69+
* Remove an object/value from the Registry
70+
*
71+
* @param string $key The key of the object/value to remove
72+
*
73+
* @return self The instance of the object for chaining
74+
*/
75+
public function remove($key)
76+
{
77+
unset($this->data[$key]);
78+
79+
return $this;
80+
}
81+
82+
/**
83+
* Removes all objects/values from the Registry
84+
*
85+
* @return self The instance of the object for chaining
86+
*/
87+
public function clear()
88+
{
89+
$this->data = [];
90+
91+
return $this;
92+
}
93+
94+
/**
95+
* Returns all objects/values in the Registry as an associative array
96+
*
97+
* @return array All of the objects/data
98+
*/
99+
public function all()
100+
{
101+
return $this->data;
102+
}
103+
104+
/**
105+
* Checks if the Registry is empty
106+
*
107+
* @return bool Whether or not its empty
108+
*/
109+
public function isEmpty()
110+
{
111+
return (0 === count($this->data));
112+
}
113+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace Jeremeamia\PhpPatterns\Creation;
4+
5+
/**
6+
* This trait establishes the class as a Builder pattern and requires that
7+
* the build() method be implemented.
8+
*/
9+
trait BuilderTrait
10+
{
11+
/**
12+
* Performs the logic for building the desired object and returns the fully-
13+
* instantiated object.
14+
*
15+
* @return mixed
16+
*/
17+
abstract public function build();
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Jeremeamia\PhpPatterns\Creation;
4+
5+
trait FactoryTrait
6+
{
7+
abstract public function create($name, array $context = []);
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
namespace Jeremeamia\PhpPatterns\Creation;
4+
5+
use Jeremeamia\PhpPatterns\Collection\RegistryTrait;
6+
7+
trait FlyweightFactoryTrait
8+
{
9+
use FactoryTrait;
10+
use RegistryTrait;
11+
12+
public function create($name, array $context = [])
13+
{
14+
$key = $this->calculateHashKey($name, $context);
15+
16+
if (!$this->has($key)) {
17+
$this->set($key, $this->doCreate($name, $context));
18+
}
19+
20+
return $this->get($key);
21+
}
22+
23+
protected function calculateHashKey($name, array $context)
24+
{
25+
return $name;
26+
}
27+
28+
abstract protected function doCreate($name, array $context);
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
namespace Jeremeamia\PhpPatterns\Creation;
4+
5+
use Jeremeamia\PhpPatterns\Collection\RegistryTrait;
6+
7+
trait MultitonTrait
8+
{
9+
use SingletonTrait;
10+
11+
public static function getInstance()
12+
{
13+
return static::getNamedInstance();
14+
}
15+
16+
public static function getNamedInstance($key = '__DEFAULT__')
17+
{
18+
if (!isset(static::$instance[$key])) {
19+
if (!static::$instance) {
20+
static::$instance = [];
21+
}
22+
static::$instance[$key] = new static;
23+
}
24+
25+
return static::$instance[$key];
26+
}
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace Jeremeamia\PhpPatterns\Creation;
4+
5+
trait PrototypeTrait
6+
{
7+
public function copy()
8+
{
9+
return clone $this;
10+
}
11+
12+
public function __clone()
13+
{
14+
// Default clone method is not required and assumes shallow copying
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
namespace Jeremeamia\PhpPatterns\Creation;
4+
5+
trait SingleOriginPrototypeTrait
6+
{
7+
use SingletonTrait, PrototypeTrait
8+
{
9+
PrototypeTrait::__clone insteadof SingletonTrait;
10+
}
11+
12+
public static function getInstance()
13+
{
14+
if (!static::$instance) {
15+
static::$instance = new static;
16+
}
17+
18+
return clone static::$instance;
19+
}
20+
21+
public function copy()
22+
{
23+
return clone static::$instance;
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
namespace Jeremeamia\PhpPatterns\Creation;
4+
5+
trait SingletonTrait
6+
{
7+
protected static $instance;
8+
9+
/**
10+
* @return self
11+
*/
12+
public static function getInstance()
13+
{
14+
if (!static::$instance) {
15+
static::$instance = (new \ReflectionClass(get_called_class()))
16+
->newInstanceWithoutConstructor();
17+
}
18+
19+
return static::$instance;
20+
}
21+
22+
public function __construct()
23+
{
24+
throw new \RuntimeException('You may not explicitly instantiate this '
25+
. 'object, because it is a singleton.');
26+
}
27+
28+
public function __clone()
29+
{
30+
throw new \RuntimeException('You may not clone this object, because it '
31+
. 'is a singleton.');
32+
}
33+
34+
public function __wakeup()
35+
{
36+
throw new \RuntimeException('You may not unserialize this object, '
37+
. 'because it is a singleton.');
38+
}
39+
40+
public function unserialize($serialized_data)
41+
{
42+
throw new \RuntimeException('You may not unserialize this object, '
43+
. 'because it is a singleton.');
44+
}
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
namespace Jeremeamia\PhpPatterns\Test\Collection;
4+
5+
use Jeremeamia\PhpPatterns\Collection\RegistryTrait;
6+
7+
class RegistryTraitFixture
8+
{
9+
use RegistryTrait;
10+
11+
protected $data = [];
12+
}

0 commit comments

Comments
 (0)