Skip to content

Commit 14a9dfe

Browse files
merge from master
1 parent 9beb7d9 commit 14a9dfe

16 files changed

+324
-16
lines changed

Behavioral/Memento/Caretaker.php

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
namespace DesignPatterns\Behavioral\Memento;
4+
5+
class Caretaker
6+
{
7+
public static function run()
8+
{
9+
/* @var $savedStates Memento[] */
10+
11+
$savedStates = array();
12+
13+
$originator = new Originator();
14+
15+
//Setting state to State1
16+
$originator->setState("State1");
17+
//Setting state to State2
18+
$originator->setState("State2");
19+
//Saving State2 to Memento
20+
$savedStates[] = $originator->saveToMemento();
21+
//Setting state to State3
22+
$originator->setState("State3");
23+
24+
// We can request multiple mementos, and choose which one to roll back to.
25+
// Saving State3 to Memento
26+
$savedStates[] = $originator->saveToMemento();
27+
//Setting state to State4
28+
$originator->setState("State4");
29+
30+
$originator->restoreFromMemento($savedStates[1]);
31+
//State after restoring from Memento: State3
32+
}
33+
}

Behavioral/Memento/Memento.php

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
namespace DesignPatterns\Behavioral\Memento;
4+
5+
class Memento
6+
{
7+
/* @var mixed */
8+
private $state;
9+
10+
/**
11+
* @param mixed $stateToSave
12+
*/
13+
public function __construct($stateToSave)
14+
{
15+
$this->state = $stateToSave;
16+
}
17+
18+
/**
19+
* @return mixed
20+
*/
21+
public function getState()
22+
{
23+
return $this->state;
24+
}
25+
}

Behavioral/Memento/MementoTest.php

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
namespace DesignPatterns\Behavioral\Memento;
4+
5+
/**
6+
* MementoTest tests the memento pattern
7+
*/
8+
class MementoTest extends \PHPUnit_Framework_TestCase
9+
{
10+
11+
public function testStringState()
12+
{
13+
$originator = new Originator();
14+
$originator->setState("State1");
15+
16+
$this->assertAttributeEquals("State1", "state", $originator);
17+
18+
$originator->setState("State2");
19+
20+
$this->assertAttributeEquals("State2", "state", $originator);
21+
22+
$savedState = $originator->saveToMemento();
23+
24+
$this->assertAttributeEquals("State2", "state", $savedState);
25+
26+
$originator->setState("State3");
27+
28+
$this->assertAttributeEquals("State3", "state", $originator);
29+
30+
$originator->restoreFromMemento($savedState);
31+
32+
$this->assertAttributeEquals("State2", "state", $originator);
33+
}
34+
35+
public function testObjectState()
36+
{
37+
$originator = new Originator();
38+
39+
$foo = new \stdClass();
40+
$foo->data = "foo";
41+
42+
$originator->setState($foo);
43+
44+
$this->assertAttributeEquals($foo, "state", $originator);
45+
46+
$savedState = $originator->saveToMemento();
47+
48+
$this->assertAttributeEquals($foo, "state", $savedState);
49+
50+
$bar = new \stdClass();
51+
$bar->data = "bar";
52+
53+
$originator->setState($bar);
54+
55+
$this->assertAttributeEquals($bar, "state", $originator);
56+
57+
$originator->restoreFromMemento($savedState);
58+
59+
$this->assertAttributeEquals($foo, "state", $originator);
60+
61+
$foo->data = null;
62+
63+
$this->assertAttributeNotEquals($foo, "state", $savedState);
64+
65+
$this->assertAttributeNotEquals($foo, "state", $originator);
66+
}
67+
}

Behavioral/Memento/Originator.php

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace DesignPatterns\Behavioral\Memento;
4+
5+
class Originator
6+
{
7+
/* @var mixed */
8+
private $state;
9+
10+
// The class could also contain additional data that is not part of the
11+
// state saved in the memento..
12+
13+
/**
14+
* @param mixed $state
15+
*/
16+
public function setState($state)
17+
{
18+
$this->state = $state;
19+
}
20+
21+
/**
22+
* @return Memento
23+
*/
24+
public function saveToMemento()
25+
{
26+
$state = is_object($this->state) ? clone $this->state : $this->state;
27+
28+
return new Memento($state);
29+
}
30+
31+
public function restoreFromMemento(Memento $memento)
32+
{
33+
$this->state = $memento->getState();
34+
}
35+
}

Behavioral/Memento/README.md

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Memento
2+
3+
## Purpose
4+
5+
Provide the ability to restore an object to its previous state (undo via rollback).
6+
7+
The memento pattern is implemented with three objects: the originator, a caretaker and a memento.
8+
The originator is some object that has an internal state.
9+
The caretaker is going to do something to the originator, but wants to be able to undo the change.
10+
The caretaker first asks the originator for a memento object. Then it does whatever operation (or sequence of operations) it was going to do.
11+
To roll back to the state before the operations, it returns the memento object to the originator.
12+
The memento object itself is an opaque object (one which the caretaker cannot, or should not, change).
13+
When using this pattern, care should be taken if the originator may change other objects or resources - the memento pattern operates on a single object.
14+
15+
## Examples
16+
17+
* The seed of a pseudorandom number generator
18+
* The state in a finite state machine

More/ServiceLocator/ServiceLocatorTest.php

+4-11
Original file line numberDiff line numberDiff line change
@@ -26,22 +26,15 @@ class ServiceLocatorTest extends TestCase
2626

2727
public function setUp()
2828
{
29-
$this->serviceLocator = new ServiceLocator();
30-
31-
$this->logService = new LogService();
29+
$this->serviceLocator = new ServiceLocator();
30+
$this->logService = new LogService();
3231
$this->databaseService = new DatabaseService();
3332
}
3433

3534
public function testHasServices()
3635
{
37-
$this->serviceLocator->add(
38-
'DesignPatterns\More\ServiceLocator\LogServiceInterface',
39-
$this->logService
40-
);
41-
$this->serviceLocator->add(
42-
'DesignPatterns\More\ServiceLocator\DatabaseServiceInterface',
43-
$this->databaseService
44-
);
36+
$this->serviceLocator->add('DesignPatterns\More\ServiceLocator\LogServiceInterface', $this->logService);
37+
$this->serviceLocator->add('DesignPatterns\More\ServiceLocator\DatabaseServiceInterface', $this->databaseService);
4538

4639
$this->assertTrue($this->serviceLocator->has('DesignPatterns\More\ServiceLocator\LogServiceInterface'));
4740
$this->assertTrue($this->serviceLocator->has('DesignPatterns\More\ServiceLocator\DatabaseServiceInterface'));

README.md

+7-5
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,18 @@ The patterns can be structured in roughly three different categories. Please cli
1414

1515
* [AbstractFactory](Creational/AbstractFactory) [:notebook:](http://en.wikipedia.org/wiki/Abstract_factory_pattern)
1616
* [Builder](Creational/Builder) [:notebook:](http://en.wikipedia.org/wiki/Builder_pattern)
17-
* [SimpleFactory](Creational/SimpleFactory)
1817
* [FactoryMethod](Creational/FactoryMethod) [:notebook:](http://en.wikipedia.org/wiki/Factory_method_pattern)
19-
* [StaticFactory](Creational/StaticFactory)
20-
* [Prototype](Creational/Prototype) [:notebook:](http://en.wikipedia.org/wiki/Prototype_pattern)
18+
* [Multiton](Creational/Multiton) (is considered an anti-pattern! :no_entry:)
2119
* [Pool](Creational/Pool) [:notebook:](http://en.wikipedia.org/wiki/Object_pool_pattern)
20+
* [Prototype](Creational/Prototype) [:notebook:](http://en.wikipedia.org/wiki/Prototype_pattern)
21+
* [SimpleFactory](Creational/SimpleFactory)
2222
* [Singleton](Creational/Singleton) [:notebook:](http://en.wikipedia.org/wiki/Singleton_pattern) (is considered an anti-pattern! :no_entry:)
23-
* [Multiton](Creational/Multiton) (is considered an anti-pattern! :no_entry:)
23+
* [StaticFactory](Creational/StaticFactory)
2424

2525
### [Structural](Structural)
2626

2727
* [Adapter](Structural/Adapter) [:notebook:](http://en.wikipedia.org/wiki/Adapter_pattern)
28+
* [Bridge](Structural/Bridge) [:notebook:](http://en.wikipedia.org/wiki/Bridge_pattern)
2829
* [Composite](Structural/Composite) [:notebook:](http://en.wikipedia.org/wiki/Composite_pattern)
2930
* [DataMapper](Structural/DataMapper) [:notebook:](http://en.wikipedia.org/wiki/Data_mapper_pattern)
3031
* [Decorator](Structural/Decorator) [:notebook:](http://en.wikipedia.org/wiki/Decorator_pattern)
@@ -40,6 +41,7 @@ The patterns can be structured in roughly three different categories. Please cli
4041
* [Command](Behavioral/Command) [:notebook:](http://en.wikipedia.org/wiki/Command_pattern)
4142
* [Iterator](Behavioral/Iterator) [:notebook:](http://en.wikipedia.org/wiki/Iterator_pattern)
4243
* [Mediator](Behavioral/Mediator) [:notebook:](http://en.wikipedia.org/wiki/Mediator_pattern)
44+
* [Memento](Memento) [:notebook:](http://en.wikipedia.org/wiki/Memento_pattern)
4345
* [NullObject](Behavioral/NullObject) [:notebook:](http://en.wikipedia.org/wiki/Null_Object_pattern)
4446
* [Observer](Behavioral/Observer) [:notebook:](http://en.wikipedia.org/wiki/Observer_pattern)
4547
* [Specification](Behavioral/Specification) [:notebook:](http://en.wikipedia.org/wiki/Specification_pattern)
@@ -61,7 +63,7 @@ To establish a consistent code quality, please check your code using [PHP_CodeSn
6163

6264
(The MIT License)
6365

64-
Copyright (c) 2013 Dominik Liebler
66+
Copyright (c) 2014 Dominik Liebler
6567

6668
Permission is hereby granted, free of charge, to any person obtaining
6769
a copy of this software and associated documentation files (the

Structural/Bridge/Assemble.php

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
namespace DesignPatterns\Structural\Bridge;
4+
5+
class Assemble implements Workshop
6+
{
7+
8+
public function work()
9+
{
10+
print 'Assembled';
11+
}
12+
}

Structural/Bridge/BridgeTest.php

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace DesignPatterns\Structural\Bridge;
4+
5+
class BridgeTest extends \PHPUnit_Framework_TestCase
6+
{
7+
8+
public function testCar()
9+
{
10+
$vehicle = new Car(new Produce(), new Assemble());
11+
$this->expectOutputString('Car Produced Assembled');
12+
$vehicle->manufacture();
13+
}
14+
15+
public function testMotorcycle()
16+
{
17+
$vehicle = new Motorcycle(new Produce(), new Assemble());
18+
$this->expectOutputString('Motorcycle Produced Assembled');
19+
$vehicle->manufacture();
20+
}
21+
}

Structural/Bridge/Car.php

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace DesignPatterns\Structural\Bridge;
4+
5+
/**
6+
* Refined Abstraction
7+
*/
8+
class Car extends Vehicle
9+
{
10+
11+
public function __construct(Workshop $workShop1, Workshop $workShop2)
12+
{
13+
parent::__construct($workShop1, $workShop2);
14+
}
15+
16+
public function manufacture()
17+
{
18+
print 'Car ';
19+
$this->workShop1->work();
20+
$this->workShop2->work();
21+
}
22+
}

Structural/Bridge/Motorcycle.php

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace DesignPatterns\Structural\Bridge;
4+
5+
/**
6+
* Refined Abstraction
7+
*/
8+
class Motorcycle extends Vehicle
9+
{
10+
11+
public function __construct(Workshop $workShop1, Workshop $workShop2)
12+
{
13+
parent::__construct($workShop1, $workShop2);
14+
}
15+
16+
public function manufacture()
17+
{
18+
print 'Motorcycle ';
19+
$this->workShop1->work();
20+
$this->workShop2->work();
21+
}
22+
}

Structural/Bridge/Produce.php

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace DesignPatterns\Structural\Bridge;
4+
5+
/**
6+
* Concrete Implementation
7+
*/
8+
class Produce implements Workshop
9+
{
10+
11+
public function work()
12+
{
13+
print 'Produced ';
14+
}
15+
}

Structural/Bridge/README.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
## Purpose
2+
3+
Decouple an abstraction from its implementation so that the two can vary
4+
independently. (http://en.wikipedia.org/wiki/Bridge_pattern)
5+
6+
7+

Structural/Bridge/Vehicle.php

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace DesignPatterns\Structural\Bridge;
4+
5+
/**
6+
* Abstraction
7+
*/
8+
abstract class Vehicle
9+
{
10+
11+
protected $workShop1;
12+
protected $workShop2;
13+
14+
protected function __construct(Workshop $workShop1, Workshop $workShop2)
15+
{
16+
$this->workShop1 = $workShop1;
17+
$this->workShop2 = $workShop2;
18+
}
19+
20+
public function manufacture()
21+
{
22+
}
23+
}

Structural/Bridge/Workshop.php

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
namespace DesignPatterns\Structural\Bridge;
4+
5+
/**
6+
* Implementer
7+
*/
8+
interface Workshop
9+
{
10+
11+
public function work();
12+
}

Structural/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ ease the design by identifying a simple way to realize relationships between
55
entities.
66

77
* [Adapter](Adapter) [:notebook:](http://en.wikipedia.org/wiki/Adapter_pattern)
8+
* [Bridge](Bridge) [:notebook:](http://en.wikipedia.org/wiki/Bridge_pattern)
89
* [Composite](Composite) [:notebook:](http://en.wikipedia.org/wiki/Composite_pattern)
910
* [DataMapper](DataMapper) [:notebook:](http://en.wikipedia.org/wiki/Data_mapper_pattern)
1011
* [Decorator](Decorator) [:notebook:](http://en.wikipedia.org/wiki/Decorator_pattern)

0 commit comments

Comments
 (0)