├── .gitignore
├── .travis.yml
├── Behavioral
├── ChainOfResponsibilities
│ ├── Handler.php
│ ├── README.md
│ ├── Request.php
│ ├── Responsible
│ │ ├── FastStorage.php
│ │ └── SlowStorage.php
│ ├── Tests
│ │ └── ChainTest.php
│ └── uml
│ │ ├── ChainOfResponsibilities.uml
│ │ ├── uml.png
│ │ └── uml.svg
├── Command
│ ├── CommandInterface.php
│ ├── HelloCommand.php
│ ├── Invoker.php
│ ├── README.md
│ ├── Receiver.php
│ ├── Tests
│ │ └── CommandTest.php
│ └── uml
│ │ ├── Command.uml
│ │ ├── uml.png
│ │ └── uml.svg
├── Iterator
│ ├── Book.php
│ ├── BookList.php
│ ├── BookListIterator.php
│ ├── BookListReverseIterator.php
│ ├── README.md
│ ├── Tests
│ │ └── IteratorTest.php
│ └── uml
│ │ ├── Iterator.uml
│ │ ├── uml.png
│ │ └── uml.svg
├── Mediator
│ ├── Colleague.php
│ ├── Mediator.php
│ ├── MediatorInterface.php
│ ├── README.md
│ ├── Subsystem
│ │ ├── Client.php
│ │ ├── Database.php
│ │ └── Server.php
│ ├── Tests
│ │ └── MediatorTest.php
│ └── uml
│ │ ├── Mediator.uml
│ │ ├── uml.png
│ │ └── uml.svg
├── Memento
│ ├── Caretaker.php
│ ├── Memento.php
│ ├── Originator.php
│ ├── README.md
│ ├── Tests
│ │ └── MementoTest.php
│ └── uml
│ │ ├── Momento.uml
│ │ ├── uml.png
│ │ └── uml.svg
├── NullObject
│ ├── LoggerInterface.php
│ ├── NullLogger.php
│ ├── PrintLogger.php
│ ├── README.md
│ ├── Service.php
│ ├── Tests
│ │ └── LoggerTest.php
│ └── uml
│ │ ├── NullObject.uml
│ │ ├── uml.png
│ │ └── uml.svg
├── Observer
│ ├── README.md
│ ├── Tests
│ │ └── ObserverTest.php
│ ├── User.php
│ ├── UserObserver.php
│ └── uml
│ │ ├── Observer.uml
│ │ ├── uml.png
│ │ └── uml.svg
├── README.md
├── Specification
│ ├── AbstractSpecification.php
│ ├── Either.php
│ ├── Item.php
│ ├── Not.php
│ ├── Plus.php
│ ├── PriceSpecification.php
│ ├── README.md
│ ├── SpecificationInterface.php
│ ├── Tests
│ │ └── SpecificationTest.php
│ └── uml
│ │ ├── Specification.uml
│ │ ├── uml.png
│ │ └── uml.svg
├── State
│ ├── CreateOrder.php
│ ├── OrderController.php
│ ├── OrderFactory.php
│ ├── OrderInterface.php
│ ├── README.md
│ ├── ShippingOrder.php
│ └── uml
│ │ ├── State.uml
│ │ ├── uml.png
│ │ └── uml.svg
├── Strategy
│ ├── ComparatorInterface.php
│ ├── DateComparator.php
│ ├── IdComparator.php
│ ├── ObjectCollection.php
│ ├── README.md
│ ├── Tests
│ │ └── StrategyTest.php
│ └── uml
│ │ ├── Strategy.uml
│ │ ├── uml.png
│ │ └── uml.svg
├── TemplateMethod
│ ├── BeachJourney.php
│ ├── CityJourney.php
│ ├── Journey.php
│ ├── README.md
│ ├── Tests
│ │ └── JourneyTest.php
│ └── uml
│ │ ├── TemplateMethod.uml
│ │ ├── uml.png
│ │ └── uml.svg
└── Visitor
│ ├── Group.php
│ ├── README.md
│ ├── Role.php
│ ├── RolePrintVisitor.php
│ ├── RoleVisitorInterface.php
│ ├── Tests
│ └── VisitorTest.php
│ ├── User.php
│ └── uml
│ ├── Visitor.uml
│ ├── uml.png
│ └── uml.svg
├── Creational
├── AbstractFactory
│ ├── AbstractFactory.php
│ ├── Html
│ │ ├── Picture.php
│ │ └── Text.php
│ ├── HtmlFactory.php
│ ├── Json
│ │ ├── Picture.php
│ │ └── Text.php
│ ├── JsonFactory.php
│ ├── MediaInterface.php
│ ├── Picture.php
│ ├── README.md
│ ├── Tests
│ │ └── AbstractFactoryTest.php
│ ├── Text.php
│ └── uml
│ │ ├── AbstractFactory.uml
│ │ ├── uml.png
│ │ └── uml.svg
├── Builder
│ ├── BikeBuilder.php
│ ├── BuilderInterface.php
│ ├── CarBuilder.php
│ ├── Director.php
│ ├── Parts
│ │ ├── Bike.php
│ │ ├── Car.php
│ │ ├── Door.php
│ │ ├── Engine.php
│ │ ├── README.md
│ │ ├── Vehicle.php
│ │ └── Wheel.php
│ ├── README.md
│ ├── Tests
│ │ └── DirectorTest.php
│ └── uml
│ │ ├── Builder.uml
│ │ ├── uml.png
│ │ └── uml.svg
├── FactoryMethod
│ ├── Bicycle.php
│ ├── FactoryMethod.php
│ ├── Ferrari.php
│ ├── GermanFactory.php
│ ├── ItalianFactory.php
│ ├── Porsche.php
│ ├── README.md
│ ├── Tests
│ │ └── FactoryMethodTest.php
│ ├── VehicleInterface.php
│ └── uml
│ │ ├── FactoryMethod.uml
│ │ ├── uml.png
│ │ └── uml.svg
├── Multiton
│ ├── Multiton.php
│ ├── README.md
│ └── uml
│ │ ├── Multiton.uml
│ │ ├── uml.png
│ │ └── uml.svg
├── Pool
│ ├── Pool.php
│ ├── Processor.php
│ ├── README.md
│ ├── Tests
│ │ └── PoolTest.php
│ ├── Worker.php
│ └── uml
│ │ ├── Pool.uml
│ │ ├── uml.png
│ │ └── uml.svg
├── Prototype
│ ├── BarBookPrototype.php
│ ├── BookPrototype.php
│ ├── FooBookPrototype.php
│ ├── README.md
│ ├── index.php
│ └── uml
│ │ ├── Prototype.uml
│ │ ├── uml.png
│ │ └── uml.svg
├── README.md
├── SimpleFactory
│ ├── Bicycle.php
│ ├── ConcreteFactory.php
│ ├── README.md
│ ├── Scooter.php
│ ├── Tests
│ │ └── SimpleFactoryTest.php
│ ├── VehicleInterface.php
│ └── uml
│ │ ├── SimpleFactory.uml
│ │ ├── uml.png
│ │ └── uml.svg
├── Singleton
│ ├── README.md
│ ├── Singleton.php
│ ├── Tests
│ │ └── SingletonTest.php
│ └── uml
│ │ ├── Singleton.uml
│ │ ├── uml.png
│ │ └── uml.svg
└── StaticFactory
│ ├── FormatNumber.php
│ ├── FormatString.php
│ ├── FormatterInterface.php
│ ├── README.md
│ ├── StaticFactory.php
│ ├── Tests
│ └── StaticFactoryTest.php
│ └── uml
│ ├── StaticFactory.uml
│ ├── uml.png
│ └── uml.svg
├── LICENSE
├── More
├── Delegation
│ ├── JuniorDeveloper.php
│ ├── README.md
│ ├── TeamLead.php
│ ├── Tests
│ │ └── DelegationTest.php
│ ├── Usage.php
│ └── uml
│ │ ├── Delegation.uml
│ │ ├── uml.png
│ │ └── uml.svg
├── README.md
├── Repository
│ ├── MemoryStorage.php
│ ├── Post.php
│ ├── PostRepository.php
│ ├── README.md
│ ├── Storage.php
│ └── uml
│ │ ├── Repository.uml
│ │ ├── uml.png
│ │ └── uml.svg
└── ServiceLocator
│ ├── DatabaseService.php
│ ├── DatabaseServiceInterface.php
│ ├── LogService.php
│ ├── LogServiceInterface.php
│ ├── README.md
│ ├── ServiceLocator.php
│ ├── ServiceLocatorInterface.php
│ ├── Tests
│ └── ServiceLocatorTest.php
│ └── uml
│ ├── ServiceLocator.uml
│ ├── uml.png
│ └── uml.svg
├── README.md
├── Structural
├── Adapter
│ ├── Book.php
│ ├── EBookAdapter.php
│ ├── EBookInterface.php
│ ├── Kindle.php
│ ├── PaperBookInterface.php
│ ├── README.md
│ ├── Tests
│ │ └── AdapterTest.php
│ └── uml
│ │ ├── Adapter.uml
│ │ ├── uml.png
│ │ └── uml.svg
├── Bridge
│ ├── Assemble.php
│ ├── Car.php
│ ├── Motorcycle.php
│ ├── Produce.php
│ ├── README.md
│ ├── Tests
│ │ └── BridgeTest.php
│ ├── Vehicle.php
│ ├── Workshop.php
│ └── uml
│ │ ├── Bridge.uml
│ │ ├── uml.png
│ │ └── uml.svg
├── Composite
│ ├── Form.php
│ ├── FormElement.php
│ ├── InputElement.php
│ ├── README.md
│ ├── Tests
│ │ └── CompositeTest.php
│ ├── TextElement.php
│ └── uml
│ │ ├── Composite.uml
│ │ ├── uml.png
│ │ ├── uml.svg
│ │ └── uml.txt
├── DataMapper
│ ├── README.md
│ ├── Tests
│ │ └── DataMapperTest.php
│ ├── User.php
│ ├── UserMapper.php
│ └── uml
│ │ ├── DataMapper.uml
│ │ ├── uml.png
│ │ └── uml.svg
├── Decorator
│ ├── Decorator.php
│ ├── README.md
│ ├── RenderInJson.php
│ ├── RenderInXml.php
│ ├── RendererInterface.php
│ ├── Tests
│ │ └── DecoratorTest.php
│ ├── Webservice.php
│ └── uml
│ │ ├── Decorator.uml
│ │ ├── uml.png
│ │ └── uml.svg
├── DependencyInjection
│ ├── AbstractConfig.php
│ ├── ArrayConfig.php
│ ├── Connection.php
│ ├── Parameters.php
│ ├── README.md
│ ├── Tests
│ │ ├── DependencyInjectionTest.php
│ │ └── config.php
│ └── uml
│ │ ├── DependencyInjection.uml
│ │ ├── uml.png
│ │ └── uml.svg
├── Facade
│ ├── BiosInterface.php
│ ├── Facade.php
│ ├── OsInterface.php
│ ├── README.md
│ ├── Tests
│ │ └── FacadeTest.php
│ └── uml
│ │ ├── Facade.uml
│ │ ├── uml.png
│ │ └── uml.svg
├── FluentInterface
│ ├── README.md
│ ├── Sql.php
│ ├── Tests
│ │ └── FluentInterfaceTest.php
│ └── uml
│ │ ├── FluentInterface.uml
│ │ ├── uml.png
│ │ └── uml.svg
├── Proxy
│ ├── README.md
│ ├── Record.php
│ ├── RecordProxy.php
│ └── uml
│ │ ├── Proxy.uml
│ │ ├── uml.png
│ │ └── uml.svg
├── README.md
└── Registry
│ ├── README.md
│ ├── Registry.php
│ ├── Tests
│ └── RegistryTest.php
│ └── uml
│ ├── Registry.uml
│ ├── uml.png
│ └── uml.svg
├── composer.json
├── composer.lock
├── composer.phar
└── phpunit.xml.dist
/.gitignore:
--------------------------------------------------------------------------------
1 | # common
2 | .idea
3 | /nbproject
4 | /vendor/
5 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 | php:
3 | - 5.3
4 | - 5.4
5 | - 5.5
6 | - hhvm
7 |
8 | before_script:
9 | - composer self-update
10 | - composer install --prefer-source --no-interaction --dev
11 |
12 | branches:
13 | only:
14 | - master
15 |
16 | matrix:
17 | allow_failures:
18 | - php: hhvm
19 | fast_finish: true
20 |
--------------------------------------------------------------------------------
/Behavioral/ChainOfResponsibilities/README.md:
--------------------------------------------------------------------------------
1 | # Chain Of Responsibilities
2 |
3 | ## Propósito
4 |
5 | Construir uma cadeia de objetos para lidar com chamadas em ordem sequencial. Se
6 | um objeto não pode lidar com uma chamada, delega essa chamada para o próximo na
7 | cadeira (chain) e assim por diante.
8 |
9 | ## Exemplos
10 |
11 | * Framework de log, onde cada elemento da cadeia decide autonomamente o que fazer
12 | com uma mensagem de log
13 | * Filtro de Spam
14 | * Caching: primeiro objeto é uma instância de, por exemplo, uma interface
15 | Memcached; se ela não souber lidar com a requisição, passa para uma interface de
16 | banco de dados
17 | * Yii Framework: CFilterChain é uma cadeia de filtros de ação de controller. O
18 | ponto de execução é passado de um filtro para o próximo na cadeia e, apenas se
19 | todos os filtros disserem "sim", a ação pode ser invocada.
20 |
21 | ## Diagrama UML
22 |
23 | 
24 |
--------------------------------------------------------------------------------
/Behavioral/ChainOfResponsibilities/Request.php:
--------------------------------------------------------------------------------
1 | data = $data;
24 | }
25 |
26 | protected function processing(Request $req)
27 | {
28 | if ('get' === $req->verb) {
29 | if (array_key_exists($req->key, $this->data)) {
30 | // the handler IS responsible and then processes the request
31 | $req->response = $this->data[$req->key];
32 | // instead of returning true, I could return the value but it proves
33 | // to be a bad idea. What if the value IS "false" ?
34 | return true;
35 | }
36 | }
37 |
38 | return false;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/Behavioral/ChainOfResponsibilities/Responsible/SlowStorage.php:
--------------------------------------------------------------------------------
1 | data = $data;
31 | }
32 |
33 | protected function processing(Request $req)
34 | {
35 | if ('get' === $req->verb) {
36 | if (array_key_exists($req->key, $this->data)) {
37 | $req->response = $this->data[$req->key];
38 |
39 | return true;
40 | }
41 | }
42 |
43 | return false;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Behavioral/ChainOfResponsibilities/uml/ChainOfResponsibilities.uml:
--------------------------------------------------------------------------------
1 |
2 |
3 | PHP
4 | \DesignPatterns\Behavioral\ChainOfResponsibilities\Handler
5 |
6 | \DesignPatterns\Behavioral\ChainOfResponsibilities\Handler
7 | \DesignPatterns\Behavioral\ChainOfResponsibilities\Responsible\SlowStorage
8 | \DesignPatterns\Behavioral\ChainOfResponsibilities\Responsible\FastStorage
9 | \DesignPatterns\Behavioral\ChainOfResponsibilities\Request
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | Fields
30 | Constants
31 | Constructors
32 | Methods
33 |
34 | private
35 |
36 |
37 |
--------------------------------------------------------------------------------
/Behavioral/ChainOfResponsibilities/uml/uml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webfatorial/PadroesDeProjetoPHP/29e0acbb384dba6415141d3ae0270a31fb527553/Behavioral/ChainOfResponsibilities/uml/uml.png
--------------------------------------------------------------------------------
/Behavioral/Command/CommandInterface.php:
--------------------------------------------------------------------------------
1 | output = $console;
25 | }
26 |
27 | /**
28 | * execute and output "Hello World"
29 | */
30 | public function execute()
31 | {
32 | // sometimes, there is no receiver and this is the command which
33 | // does all the work
34 | $this->output->write('Hello World');
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Behavioral/Command/Invoker.php:
--------------------------------------------------------------------------------
1 | command = $cmd;
25 | }
26 |
27 | /**
28 | * executes the command
29 | */
30 | public function run()
31 | {
32 | // here is a key feature of the invoker
33 | // the invoker is the same whatever is the command
34 | $this->command->execute();
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Behavioral/Command/README.md:
--------------------------------------------------------------------------------
1 | # Command
2 |
3 | ## Propósito
4 |
5 | Encapsular invocação e desacoplação
6 |
7 | Tem-se um Invoker (invocador) e um Receiver (receptor). Esse Padrão usa um
8 | comando ("Command") para delegar a chamada ao método contra o Receiver e
9 | apresentar o mesmo método "execute". Assim, o Invoker sabe que é preciso chamar
10 | "execute" para processar o comando do cliente. O Receiver é desacoplado do
11 | Invoker.
12 |
13 | O segundo aspecto desse padrão é o `undo()`, que desfaz o método `execute()`.
14 | Command também pode ser agregado para combinar comandos mais complexos com um
15 | copiar-colar mínimo e confiando na composição em detrimento de herança.
16 |
17 | ## Exemplos
18 |
19 | * Um editor de texto: todos eventos são Commands que podem ser desfeitos,
20 | empilhados e salvos
21 | * Symfony2: Commands SF2 que podem ser rodados a partir da linha de comando (CLI)
22 | com apenas o Padrão Command em mente
23 | * Grandes ferramentas CLI usam subcomandos para distribuir várias tarefas e
24 | agrupá-las em "módulos", cada um podendo ser implementado com Command (por
25 | exemplo, Vagrant)
26 |
27 | ## Diagrama UML
28 |
29 | 
30 |
--------------------------------------------------------------------------------
/Behavioral/Command/Receiver.php:
--------------------------------------------------------------------------------
1 | invoker = new Invoker();
28 | $this->receiver = new Receiver();
29 | }
30 |
31 | public function testInvocation()
32 | {
33 | $this->invoker->setCommand(new HelloCommand($this->receiver));
34 | $this->expectOutputString('Hello World');
35 | $this->invoker->run();
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Behavioral/Command/uml/Command.uml:
--------------------------------------------------------------------------------
1 |
2 |
3 | PHP
4 | \DesignPatterns\Behavioral\Command\HelloCommand
5 |
6 | \DesignPatterns\Behavioral\Command\Invoker
7 | \DesignPatterns\Behavioral\Command\HelloCommand
8 | \DesignPatterns\Behavioral\Command\Receiver
9 | \DesignPatterns\Behavioral\Command\CommandInterface
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | Fields
22 | Constants
23 | Constructors
24 | Methods
25 |
26 | private
27 |
28 |
29 |
--------------------------------------------------------------------------------
/Behavioral/Command/uml/uml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webfatorial/PadroesDeProjetoPHP/29e0acbb384dba6415141d3ae0270a31fb527553/Behavioral/Command/uml/uml.png
--------------------------------------------------------------------------------
/Behavioral/Iterator/Book.php:
--------------------------------------------------------------------------------
1 | author = $author;
15 | $this->title = $title;
16 | }
17 |
18 | public function getAuthor()
19 | {
20 | return $this->author;
21 | }
22 |
23 | public function getTitle()
24 | {
25 | return $this->title;
26 | }
27 |
28 | public function getAuthorAndTitle()
29 | {
30 | return $this->getTitle() . ' by ' . $this->getAuthor();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Behavioral/Iterator/BookList.php:
--------------------------------------------------------------------------------
1 | count()) {
13 | return $this->books[$bookNumberToGet];
14 | }
15 |
16 | return null;
17 | }
18 |
19 | public function addBook(Book $book)
20 | {
21 | $this->books[] = $book;
22 |
23 | return $this->count();
24 | }
25 |
26 | public function removeBook(Book $bookToRemove)
27 | {
28 | foreach ($this as $key => $book) {
29 | /** @var Book $book */
30 | if ($book->getAuthorAndTitle() === $bookToRemove->getAuthorAndTitle()) {
31 | unset($this->books[$key]);
32 | }
33 | }
34 |
35 | return $this->count();
36 | }
37 |
38 | public function count()
39 | {
40 | return count($this->books);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Behavioral/Iterator/BookListReverseIterator.php:
--------------------------------------------------------------------------------
1 | bookList = $bookList;
11 | $this->currentBook = $this->bookList->count() - 1;
12 | }
13 |
14 | public function next()
15 | {
16 | $this->currentBook--;
17 | }
18 |
19 | public function valid()
20 | {
21 | return 0 <= $this->currentBook;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Behavioral/Iterator/README.md:
--------------------------------------------------------------------------------
1 | # Iterator
2 |
3 | ## Propósito
4 |
5 | Fazer um objeto "interagível" e fazê-lo parecer como uma coleção de objetos.
6 |
7 | ## Exemplos
8 |
9 | * Processar um arquivo linha a linha passando por todas as linhas (que têm uma
10 | representação de objeto) por um arquivo (que, claro, é um objeto, também)
11 |
12 | ## Nota
13 |
14 | Standard PHP Library (SPL) define uma interface Iterator que é adequada para isso!
15 | Frequentemente você vai querer implementar a interface Countable, também, para
16 | permitir `count($object)` em seu objeto iterável.
17 |
18 | ## Diagrama UML
19 |
20 | 
21 |
--------------------------------------------------------------------------------
/Behavioral/Iterator/uml/Iterator.uml:
--------------------------------------------------------------------------------
1 |
2 |
3 | PHP
4 | \DesignPatterns\Behavioral\Iterator\Book
5 |
6 | \DesignPatterns\Behavioral\Iterator\BookListReverseIterator
7 | \DesignPatterns\Behavioral\Iterator\BookList
8 | \DesignPatterns\Behavioral\Iterator\BookListIterator
9 | \DesignPatterns\Behavioral\Iterator\Book
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | Fields
22 | Constants
23 | Constructors
24 | Methods
25 |
26 | private
27 |
28 |
29 |
--------------------------------------------------------------------------------
/Behavioral/Iterator/uml/uml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webfatorial/PadroesDeProjetoPHP/29e0acbb384dba6415141d3ae0270a31fb527553/Behavioral/Iterator/uml/uml.png
--------------------------------------------------------------------------------
/Behavioral/Mediator/Colleague.php:
--------------------------------------------------------------------------------
1 | mediator;
22 | }
23 |
24 | /**
25 | * @param MediatorInterface $medium
26 | */
27 | public function __construct(MediatorInterface $medium)
28 | {
29 | // in this way, we are sure the concrete colleague knows the mediator
30 | $this->mediator = $medium;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Behavioral/Mediator/Mediator.php:
--------------------------------------------------------------------------------
1 | database = $db;
37 | $this->server = $srv;
38 | $this->client = $cl;
39 | }
40 |
41 | /**
42 | * make request
43 | */
44 | public function makeRequest()
45 | {
46 | $this->server->process();
47 | }
48 |
49 | /**
50 | * query db
51 | * @return mixed
52 | */
53 | public function queryDb()
54 | {
55 | return $this->database->getData();
56 | }
57 |
58 | /**
59 | * send response
60 | *
61 | * @param string $content
62 | */
63 | public function sendResponse($content)
64 | {
65 | $this->client->output($content);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/Behavioral/Mediator/MediatorInterface.php:
--------------------------------------------------------------------------------
1 | getMediator()->makeRequest();
18 | }
19 |
20 | /**
21 | * output content
22 | *
23 | * @param string $content
24 | */
25 | public function output($content)
26 | {
27 | echo $content;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Behavioral/Mediator/Subsystem/Database.php:
--------------------------------------------------------------------------------
1 | getMediator()->queryDb();
18 | $this->getMediator()->sendResponse("Hello $data");
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Behavioral/Mediator/Tests/MediatorTest.php:
--------------------------------------------------------------------------------
1 | client = new Client($media);
22 | $media->setColleague(new Database($media), $this->client, new Server($media));
23 | }
24 |
25 | public function testOutputHelloWorld()
26 | {
27 | // testing if Hello World is output :
28 | $this->expectOutputString('Hello World');
29 | // as you see, the 3 components Client, Server and Database are totally decoupled
30 | $this->client->request();
31 | // Anyway, it remains complexity in the Mediator that's why the pattern
32 | // Observer is preferable in mnay situations.
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Behavioral/Mediator/uml/uml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webfatorial/PadroesDeProjetoPHP/29e0acbb384dba6415141d3ae0270a31fb527553/Behavioral/Mediator/uml/uml.png
--------------------------------------------------------------------------------
/Behavioral/Memento/Caretaker.php:
--------------------------------------------------------------------------------
1 | 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 | }
34 |
--------------------------------------------------------------------------------
/Behavioral/Memento/Memento.php:
--------------------------------------------------------------------------------
1 | state = $stateToSave;
16 | }
17 |
18 | /**
19 | * @return mixed
20 | */
21 | public function getState()
22 | {
23 | return $this->state;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Behavioral/Memento/Originator.php:
--------------------------------------------------------------------------------
1 | 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 | }
36 |
--------------------------------------------------------------------------------
/Behavioral/Memento/README.md:
--------------------------------------------------------------------------------
1 | # Memento
2 |
3 | ## Propósito
4 |
5 | Prover a habilidade de restaurar um objeto a seu estado anterior ("desfazer"
6 | através de rollback).
7 |
8 | O Padrão Memento é implementado com 3 objetos: Originator (originador), Caretaker
9 | (zelador) e Memento (memória).
10 |
11 | O Originator é algum objeto que tem um estado interno.
12 |
13 | Caretaker vai fazer alguma coisa para o Originator, mas espera ser apto para
14 | desfazer (undo) a mudança. O Caretaker primeiro pergunta ao Originator pelo
15 | objeto Memento. Então ele faz qualquer operação (ou sequência de operações) que
16 | foi designado. Para reverter (roll back) ao estado anterior às operações, ele
17 | retorna o objeto Memento ao Originator. O objeto Memento, em si, é opaco -- um
18 | que o Caretaker não pode (ou não deveria) mudar.
19 |
20 | Ao usar este Padrão, deve-se tomar cuidado se o Originator puder alterar outros
21 | objetos ou recuros -- Memento opera em um objeto único.
22 |
23 | ## Exemplos
24 |
25 | * A semente (seed) de um pseudo-gerador de números
26 | * O estado numa máquina de estados finitos
27 |
28 | ## Diagrama UML
29 |
30 | 
31 |
--------------------------------------------------------------------------------
/Behavioral/Memento/uml/Momento.uml:
--------------------------------------------------------------------------------
1 |
2 |
3 | PHP
4 | \DesignPatterns\Behavioral\Memento\Caretaker
5 |
6 | \DesignPatterns\Behavioral\Memento\Caretaker
7 | \DesignPatterns\Behavioral\Memento\Originator
8 | \DesignPatterns\Behavioral\Memento\Memento
9 |
10 |
11 |
12 |
13 |
14 |
15 | Fields
16 | Constants
17 | Constructors
18 | Methods
19 |
20 | private
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Behavioral/Memento/uml/uml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webfatorial/PadroesDeProjetoPHP/29e0acbb384dba6415141d3ae0270a31fb527553/Behavioral/Memento/uml/uml.png
--------------------------------------------------------------------------------
/Behavioral/NullObject/LoggerInterface.php:
--------------------------------------------------------------------------------
1 | menos casos de uso
12 |
13 | Toda vez que se tem um método que retorna um objeto ou `null`, você deveria
14 | retornar um objeto ou um `NullObject`. Com NullObject, você não precisa mais de
15 | uma declaração como `if (!is_null($obj)) { $obj->callSomething(); }`.
16 |
17 | ## Exemplos
18 |
19 | * Symfony2: null logger do profiler
20 | * Symfony2: null output em Symfony/Console
21 | * null handler num Padrão Chain of Responsibilities
22 | * null command num Padrão Command
23 |
24 | ## Diagrama UML
25 |
26 | 
27 |
--------------------------------------------------------------------------------
/Behavioral/NullObject/Service.php:
--------------------------------------------------------------------------------
1 | logger = $log;
23 | }
24 |
25 | /**
26 | * do something ...
27 | */
28 | public function doSomething()
29 | {
30 | // no more check "if (!is_null($this->logger))..." with the NullObject pattern
31 | $this->logger->log('We are in ' . __METHOD__);
32 | // something to do...
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Behavioral/NullObject/Tests/LoggerTest.php:
--------------------------------------------------------------------------------
1 | expectOutputString(null); // no output
21 | $service->doSomething();
22 | }
23 |
24 | public function testStandardLogger()
25 | {
26 | $service = new Service(new PrintLogger());
27 | $this->expectOutputString('We are in DesignPatterns\Behavioral\NullObject\Service::doSomething');
28 | $service->doSomething();
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Behavioral/NullObject/uml/NullObject.uml:
--------------------------------------------------------------------------------
1 |
2 |
3 | PHP
4 | \DesignPatterns\Behavioral\NullObject\Service
5 |
6 | \DesignPatterns\Behavioral\NullObject\NullLogger
7 | \DesignPatterns\Behavioral\NullObject\PrintLogger
8 | \DesignPatterns\Behavioral\NullObject\LoggerInterface
9 | \DesignPatterns\Behavioral\NullObject\Service
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | Fields
30 | Constants
31 | Constructors
32 | Methods
33 |
34 | private
35 |
36 |
37 |
--------------------------------------------------------------------------------
/Behavioral/NullObject/uml/uml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webfatorial/PadroesDeProjetoPHP/29e0acbb384dba6415141d3ae0270a31fb527553/Behavioral/NullObject/uml/uml.png
--------------------------------------------------------------------------------
/Behavioral/Observer/README.md:
--------------------------------------------------------------------------------
1 | # Observer
2 |
3 | ## Propósito
4 |
5 | Implementar um comportamento publicar/subscrever a um objeto. Sempre que um
6 | objeto "Subject" ("Assunto") muda seu estado, os "Observers" ("Observadores")
7 | anexos serão notificados. Isso é usado para diminuir a quantidade de objetos
8 | acoplados e proporcionar baixo acoplamento
9 |
10 | ## Exemplos
11 |
12 | * Um sistema de fila de mensagem é "observado" para mostrar o progresso de um
13 | job em uma GUI
14 |
15 | ## Nota
16 |
17 | PHP já define 2 interfaces que podem ajudar a implementar esse padrão: SplObserver and SplSubject.
18 |
19 | ## Diagrama UML
20 |
21 | 
22 |
--------------------------------------------------------------------------------
/Behavioral/Observer/Tests/ObserverTest.php:
--------------------------------------------------------------------------------
1 | observer = new UserObserver();
19 | }
20 |
21 | /**
22 | * Tests the notification
23 | */
24 | public function testNotify()
25 | {
26 | $this->expectOutputString('DesignPatterns\Behavioral\Observer\User has been updated');
27 | $subject = new User();
28 |
29 | $subject->attach($this->observer);
30 | $subject->property = 123;
31 | }
32 |
33 | /**
34 | * Tests the subscribing
35 | */
36 | public function testAttachDetach()
37 | {
38 | $subject = new User();
39 | $this->assertAttributeEmpty('observers', $subject);
40 | $subject->attach($this->observer);
41 | $this->assertAttributeNotEmpty('observers', $subject);
42 | $subject->detach($this->observer);
43 | $this->assertAttributeEmpty('observers', $subject);
44 | }
45 |
46 | /**
47 | * Tests the update() invocation on a mockup
48 | */
49 | public function testUpdateCalling()
50 | {
51 | $subject = new User();
52 | $observer = $this->getMock('SplObserver');
53 | $subject->attach($observer);
54 |
55 | $observer->expects($this->once())
56 | ->method('update')
57 | ->with($subject);
58 |
59 | $subject->notify();
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/Behavioral/Observer/User.php:
--------------------------------------------------------------------------------
1 | observers[] = $observer;
37 | }
38 |
39 | /**
40 | * detach an observer
41 | *
42 | * @param \SplObserver $observer
43 | *
44 | * @return void
45 | */
46 | public function detach(\SplObserver $observer)
47 | {
48 | $index = array_search($observer, $this->observers);
49 |
50 | if (false !== $index) {
51 | unset($this->observers[$index]);
52 | }
53 | }
54 |
55 | /**
56 | * notify observers
57 | *
58 | * @return void
59 | */
60 | public function notify()
61 | {
62 | /** @var \SplObserver $observer */
63 | foreach ($this->observers as $observer) {
64 | $observer->update($this);
65 | }
66 | }
67 |
68 | /**
69 | * Ideally one would better write setter/getter for all valid attributes and only call notify()
70 | * on attributes that matter when changed
71 | *
72 | * @param string $name
73 | * @param mixed $value
74 | *
75 | * @return void
76 | */
77 | public function __set($name, $value)
78 | {
79 | $this->data[$name] = $value;
80 |
81 | // notify the observers, that user has been updated
82 | $this->notify();
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/Behavioral/Observer/UserObserver.php:
--------------------------------------------------------------------------------
1 |
2 |
3 | PHP
4 | \DesignPatterns\Behavioral\Observer\User
5 |
6 | \DesignPatterns\Behavioral\Observer\UserObserver
7 | \DesignPatterns\Behavioral\Observer\User
8 | \SplSubject
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | Fields
21 | Constants
22 | Constructors
23 | Methods
24 |
25 | private
26 |
27 |
28 |
--------------------------------------------------------------------------------
/Behavioral/Observer/uml/uml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webfatorial/PadroesDeProjetoPHP/29e0acbb384dba6415141d3ae0270a31fb527553/Behavioral/Observer/uml/uml.png
--------------------------------------------------------------------------------
/Behavioral/README.md:
--------------------------------------------------------------------------------
1 | # Comportamental
2 |
3 | Em Engenharia de Software, Padrão de Projeto Comportamentais identificam padrões
4 | de comunicação comuns entre objetos. Ao fazer isso, esses Padrões aumentam a
5 | flexibilidade na realização dessa comunicação.
6 |
7 | * [ChainOfResponsibilities](ChainOfResponsibilities) [:notebook:](http://pt.wikipedia.org/wiki/Chain_of_Responsibility)
8 | * [Command](Command) [:notebook:](http://pt.wikipedia.org/wiki/Command)
9 | * [Iterator](Iterator) [:notebook:](http://pt.wikipedia.org/wiki/Iterator)
10 | * [Mediator](Mediator) [:notebook:](http://pt.wikipedia.org/wiki/Mediator)
11 | * [Memento](Memento) [:notebook:](http://pt.wikipedia.org/wiki/Memento_(inform%C3%A1tica))
12 | * [NullObject](NullObject) [:notebook:](http://en.wikipedia.org/wiki/Null_Object_pattern)
13 | * [Observer](Observer) [:notebook:](http://pt.wikipedia.org/wiki/Observer)
14 | * [Specification](Specification) [:notebook:](http://en.wikipedia.org/wiki/Specification_pattern)
15 | * [State](State) [:notebook:](http://pt.wikipedia.org/wiki/State)
16 | * [Strategy](Strategy) [:notebook:](http://pt.wikipedia.org/wiki/Strategy)
17 | * [TemplateMethod](TemplateMethod) [:notebook:](http://pt.wikipedia.org/wiki/Template_Method)
18 | * [Visitor](Visitor) [:notebook:](http://pt.wikipedia.org/wiki/Visitor_pattern)
19 |
--------------------------------------------------------------------------------
/Behavioral/Specification/AbstractSpecification.php:
--------------------------------------------------------------------------------
1 | left = $left;
22 | $this->right = $right;
23 | }
24 |
25 | /**
26 | * Returns the evaluation of both wrapped specifications as a logical OR
27 | *
28 | * @param Item $item
29 | *
30 | * @return bool
31 | */
32 | public function isSatisfiedBy(Item $item)
33 | {
34 | return $this->left->isSatisfiedBy($item) || $this->right->isSatisfiedBy($item);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Behavioral/Specification/Item.php:
--------------------------------------------------------------------------------
1 | price = $price;
19 | }
20 |
21 | /**
22 | * Get the items price
23 | *
24 | * @return int
25 | */
26 | public function getPrice()
27 | {
28 | return $this->price;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Behavioral/Specification/Not.php:
--------------------------------------------------------------------------------
1 | spec = $spec;
20 | }
21 |
22 | /**
23 | * Returns the negated result of the wrapped specification
24 | *
25 | * @param Item $item
26 | *
27 | * @return bool
28 | */
29 | public function isSatisfiedBy(Item $item)
30 | {
31 | return !$this->spec->isSatisfiedBy($item);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Behavioral/Specification/Plus.php:
--------------------------------------------------------------------------------
1 | left = $left;
22 | $this->right = $right;
23 | }
24 |
25 | /**
26 | * Checks if the composite AND of specifications passes
27 | *
28 | * @param Item $item
29 | *
30 | * @return bool
31 | */
32 | public function isSatisfiedBy(Item $item)
33 | {
34 | return $this->left->isSatisfiedBy($item) && $this->right->isSatisfiedBy($item);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Behavioral/Specification/PriceSpecification.php:
--------------------------------------------------------------------------------
1 | maxPrice = $maxPrice;
20 | }
21 |
22 | /**
23 | * Sets the optional minimum price
24 | *
25 | * @param int $minPrice
26 | */
27 | public function setMinPrice($minPrice)
28 | {
29 | $this->minPrice = $minPrice;
30 | }
31 |
32 | /**
33 | * Checks if Item price falls between bounds
34 | *
35 | * @param Item $item
36 | *
37 | * @return bool
38 | */
39 | public function isSatisfiedBy(Item $item)
40 | {
41 | if (!empty($this->maxPrice) && $item->getPrice() > $this->maxPrice) {
42 | return false;
43 | }
44 | if (!empty($this->minPrice) && $item->getPrice() < $this->minPrice) {
45 | return false;
46 | }
47 |
48 | return true;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/Behavioral/Specification/README.md:
--------------------------------------------------------------------------------
1 | # Specification
2 |
3 | ## Propósito
4 |
5 | Construir uma especificação clara de regras de negócio, na qual objetos podem ser
6 | verificados. A classe de especificação tem um método chamado `isSatisfiedBy` que
7 | retorna `true` ou `false`, dependendo se dado objeto satisfaz a especificação.
8 |
9 | ## Diagrama UML
10 |
11 | 
12 |
--------------------------------------------------------------------------------
/Behavioral/Specification/SpecificationInterface.php:
--------------------------------------------------------------------------------
1 | order = $order;
26 | }
27 |
28 | /**
29 | * @return mixed
30 | */
31 | public function shipOrder()
32 | {
33 | $this->order['status'] = 'shipping';
34 | $this->order['updatedTime'] = time();
35 |
36 | // Setting the new order status into database;
37 | return $this->updateOrder($this->order);
38 | }
39 |
40 | /**
41 | * @return mixed|void
42 | * @throws \Exception
43 | */
44 | public function completeOrder()
45 | {
46 | //Can not complete the order which status is created, throw exception;
47 | throw new \Exception('Can not complete the order which status is created!');
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/Behavioral/State/OrderController.php:
--------------------------------------------------------------------------------
1 | shipOrder();
18 | } catch (Exception $e) {
19 | //handle error!
20 | }
21 | // response to browser
22 | }
23 |
24 | /**
25 | * @param int $id
26 | */
27 | public function completeAction($id)
28 | {
29 | $order = OrderFactory::getOrder($id);
30 | try {
31 | $order->completeOrder();
32 | } catch (Exception $e) {
33 | //handle error!
34 | }
35 | // response to browser
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Behavioral/State/OrderFactory.php:
--------------------------------------------------------------------------------
1 | order = $order;
26 | }
27 |
28 | /**
29 | * @return mixed|void
30 | * @throws \Exception
31 | */
32 | public function shipOrder()
33 | {
34 | //Can not ship the order which status is shipping, throw exception;
35 | throw new \Exception('Can not ship the order which status is shipping!');
36 | }
37 |
38 | /**
39 | * @return mixed
40 | */
41 | public function completeOrder()
42 | {
43 | $this->order['status'] = 'completed';
44 | $this->order['updatedTime'] = time();
45 |
46 | // Setting the new order status into database;
47 | return $this->updateOrder($order);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/Behavioral/State/uml/State.uml:
--------------------------------------------------------------------------------
1 |
2 |
3 | PHP
4 | \DesignPatterns\Behavioral\State\OrderInterface
5 |
6 | \DesignPatterns\Behavioral\State\OrderFactory
7 | \DesignPatterns\Behavioral\State\CreateOrder
8 | \DesignPatterns\Behavioral\State\OrderController
9 | \DesignPatterns\Behavioral\State\OrderInterface
10 | \DesignPatterns\Behavioral\State\ShippingOrder
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | Fields
31 | Constants
32 | Constructors
33 | Methods
34 |
35 | private
36 |
37 |
38 |
--------------------------------------------------------------------------------
/Behavioral/State/uml/uml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webfatorial/PadroesDeProjetoPHP/29e0acbb384dba6415141d3ae0270a31fb527553/Behavioral/State/uml/uml.png
--------------------------------------------------------------------------------
/Behavioral/Strategy/ComparatorInterface.php:
--------------------------------------------------------------------------------
1 | elements = $elements;
26 | }
27 |
28 | /**
29 | * @return array
30 | */
31 | public function sort()
32 | {
33 | if (!$this->comparator) {
34 | throw new \LogicException("Comparator is not set");
35 | }
36 |
37 | $callback = array($this->comparator, 'compare');
38 | uasort($this->elements, $callback);
39 |
40 | return $this->elements;
41 | }
42 |
43 | /**
44 | * @param ComparatorInterface $comparator
45 | *
46 | * @return void
47 | */
48 | public function setComparator(ComparatorInterface $comparator)
49 | {
50 | $this->comparator = $comparator;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/Behavioral/Strategy/README.md:
--------------------------------------------------------------------------------
1 | # Strategy
2 |
3 | ## Terminologia
4 |
5 | * Context (Contexto)
6 | * Strategy (Estratégia)
7 | * Concrete Strategy (Estratégia Concreta)
8 |
9 | ## Propósito
10 |
11 | Separar estratégias e permitir uma troca rápida entre elas. Esse padrão também
12 | é uma boa alternativa a herança -- não é preciso ter uma classe abstrata que é
13 | estendida.
14 |
15 | ## Exemplos
16 |
17 | * Ordenar uma lista de objetos, uma estratégia por data, outra por ID
18 | * Simplificar teste unitário: alternar entre armazenado em arquivo e em memória
19 |
20 | ## Diagrama UML
21 |
22 | 
23 |
--------------------------------------------------------------------------------
/Behavioral/Strategy/uml/Strategy.uml:
--------------------------------------------------------------------------------
1 |
2 |
3 | PHP
4 | \DesignPatterns\Behavioral\Strategy\ComparatorInterface
5 |
6 | \DesignPatterns\Behavioral\Strategy\ObjectCollection
7 | \DesignPatterns\Behavioral\Strategy\DateComparator
8 | \DesignPatterns\Behavioral\Strategy\ComparatorInterface
9 | \DesignPatterns\Behavioral\Strategy\IdComparator
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | Fields
30 | Constants
31 | Constructors
32 | Methods
33 |
34 | private
35 |
36 |
37 |
--------------------------------------------------------------------------------
/Behavioral/Strategy/uml/uml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webfatorial/PadroesDeProjetoPHP/29e0acbb384dba6415141d3ae0270a31fb527553/Behavioral/Strategy/uml/uml.png
--------------------------------------------------------------------------------
/Behavioral/TemplateMethod/BeachJourney.php:
--------------------------------------------------------------------------------
1 | buyAFlight();
19 | $this->takePlane();
20 | $this->enjoyVacation();
21 | $this->buyGift();
22 | $this->takePlane();
23 | }
24 |
25 | /**
26 | * This method must be implemented, this is the key-feature of this pattern
27 | */
28 | abstract protected function enjoyVacation();
29 |
30 | /**
31 | * This method is also part of the algorithm but it is optional.
32 | * This is an "adapter" (do not confuse with the Adapter pattern, not related)
33 | * You can override it only if you need to.
34 | */
35 | protected function buyGift()
36 | {
37 | }
38 |
39 | /**
40 | * This method will be unknown by subclasses (better)
41 | */
42 | private function buyAFlight()
43 | {
44 | echo "Buying a flight\n";
45 | }
46 |
47 | /**
48 | * Subclasses will get access to this method but cannot override it and
49 | * compromise this algorithm (warning : cause of cyclic dependencies)
50 | */
51 | final protected function takePlane()
52 | {
53 | echo "Taking the plane\n";
54 | }
55 |
56 | // A note regarding the keyword "final" : don't use it when you start coding :
57 | // add it after you narrow and know exactly what change and what remain unchanged
58 | // in this algorithm.
59 | // [abstract] x [3 access] x [final] = 12 combinations, it can be hard !
60 | }
61 |
--------------------------------------------------------------------------------
/Behavioral/TemplateMethod/README.md:
--------------------------------------------------------------------------------
1 | # Template Method
2 |
3 | ## Propósito
4 |
5 | Permitir que subclasses de uma template abstrato "termine" o comportamento de
6 | um algoritmo. Também é conhecido como Princípio de Hollywood: "Não nos chame,
7 | nós chamamos você" ("Don't call us, we call you").
8 |
9 | Essa classe não é chamada por subclasses; pelo contrário. Mas como? Com
10 | abstração, evidentemente. Em outras palavras, é um esqueleto do algoritmo, ideal
11 | para bibliotecas de frameworks. Quem está usando deve somente implementar um
12 | método e a superclasse faz o restante do serviço.
13 |
14 | Essa é uma maneira fácil de desacoplar classes concretas e reduzir o copiar-colar,
15 | e é por isso que você encontra esse Padrão por toda parte.
16 |
17 | ## Diagrama UML
18 |
19 | 
20 |
--------------------------------------------------------------------------------
/Behavioral/TemplateMethod/Tests/JourneyTest.php:
--------------------------------------------------------------------------------
1 | expectOutputRegex('#sun-bathing#');
17 | $journey->takeATrip();
18 | }
19 |
20 | public function testCity()
21 | {
22 | $journey = new TemplateMethod\CityJourney();
23 | $this->expectOutputRegex('#drink#');
24 | $journey->takeATrip();
25 | }
26 |
27 | /**
28 | * How to test an abstract template method with PHPUnit
29 | */
30 | public function testLasVegas()
31 | {
32 | $journey = $this->getMockForAbstractClass('DesignPatterns\Behavioral\TemplateMethod\Journey');
33 | $journey->expects($this->once())
34 | ->method('enjoyVacation')
35 | ->will($this->returnCallback(array($this, 'mockUpVacation')));
36 | $this->expectOutputRegex('#Las Vegas#');
37 | $journey->takeATrip();
38 | }
39 |
40 | public function mockUpVacation()
41 | {
42 | echo "Fear and loathing in Las Vegas\n";
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Behavioral/TemplateMethod/uml/TemplateMethod.uml:
--------------------------------------------------------------------------------
1 |
2 |
3 | PHP
4 | \DesignPatterns\Behavioral\TemplateMethod\BeachJourney
5 |
6 | \DesignPatterns\Behavioral\TemplateMethod\CityJourney
7 | \DesignPatterns\Behavioral\TemplateMethod\Journey
8 | \DesignPatterns\Behavioral\TemplateMethod\BeachJourney
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | Fields
29 | Constants
30 | Constructors
31 | Methods
32 |
33 | private
34 |
35 |
36 |
--------------------------------------------------------------------------------
/Behavioral/TemplateMethod/uml/uml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webfatorial/PadroesDeProjetoPHP/29e0acbb384dba6415141d3ae0270a31fb527553/Behavioral/TemplateMethod/uml/uml.png
--------------------------------------------------------------------------------
/Behavioral/Visitor/Group.php:
--------------------------------------------------------------------------------
1 | name = (string) $name;
21 | }
22 |
23 | /**
24 | * @return string
25 | */
26 | public function getName()
27 | {
28 | return "Group: " . $this->name;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Behavioral/Visitor/README.md:
--------------------------------------------------------------------------------
1 | # Visitor
2 |
3 | ## Propósito
4 |
5 | Permite terceirizar operações de objetos para outros objetos. A razão principal
6 | para se fazer isso é manter a separação de interesses. Mas classes têm de definir
7 | um "contrato" para permitir visitantes (o método `Role::accept` no exemplo).
8 |
9 | O contrato é uma classe abstrata, mas também é possível se ter uma interface.
10 | Nesse caso, cada Visitor (Visitante) deve escolher qual método invocar no
11 | visitante.
12 |
13 | ## Diagrama UML
14 |
15 | 
16 |
--------------------------------------------------------------------------------
/Behavioral/Visitor/Role.php:
--------------------------------------------------------------------------------
1 | getName();
18 | }
19 |
20 | /**
21 | * {@inheritdoc}
22 | */
23 | public function visitUser(User $role)
24 | {
25 | echo "Role: " . $role->getName();
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Behavioral/Visitor/RoleVisitorInterface.php:
--------------------------------------------------------------------------------
1 | visitor = new Visitor\RolePrintVisitor();
18 | }
19 |
20 | public function getRole()
21 | {
22 | return array(
23 | array(new Visitor\User("Dominik"), 'Role: User Dominik'),
24 | array(new Visitor\Group("Administrators"), 'Role: Group: Administrators')
25 | );
26 | }
27 |
28 | /**
29 | * @dataProvider getRole
30 | */
31 | public function testVisitSomeRole(Visitor\Role $role, $expect)
32 | {
33 | $this->expectOutputString($expect);
34 | $role->accept($this->visitor);
35 | }
36 |
37 | /**
38 | * @expectedException \InvalidArgumentException
39 | * @expectedExceptionMessage Mock
40 | */
41 | public function testUnknownObject()
42 | {
43 | $mock = $this->getMockForAbstractClass('DesignPatterns\Behavioral\Visitor\Role');
44 | $mock->accept($this->visitor);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/Behavioral/Visitor/User.php:
--------------------------------------------------------------------------------
1 | name = (string) $name;
23 | }
24 |
25 | /**
26 | * @return string
27 | */
28 | public function getName()
29 | {
30 | return "User " . $this->name;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Behavioral/Visitor/uml/Visitor.uml:
--------------------------------------------------------------------------------
1 |
2 |
3 | PHP
4 | \DesignPatterns\Behavioral\Visitor\Group
5 |
6 | \DesignPatterns\Behavioral\Visitor\Role
7 | \DesignPatterns\Behavioral\Visitor\RolePrintVisitor
8 | \DesignPatterns\Behavioral\Visitor\Group
9 | \DesignPatterns\Behavioral\Visitor\RoleVisitorInterface
10 | \DesignPatterns\Behavioral\Visitor\User
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | Fields
35 | Constants
36 | Constructors
37 | Methods
38 |
39 | private
40 |
41 |
42 |
--------------------------------------------------------------------------------
/Behavioral/Visitor/uml/uml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webfatorial/PadroesDeProjetoPHP/29e0acbb384dba6415141d3ae0270a31fb527553/Behavioral/Visitor/uml/uml.png
--------------------------------------------------------------------------------
/Creational/AbstractFactory/AbstractFactory.php:
--------------------------------------------------------------------------------
1 | ', $this->path, $this->name);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Creational/AbstractFactory/Html/Text.php:
--------------------------------------------------------------------------------
1 | ' . htmlspecialchars($this->text) . '';
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Creational/AbstractFactory/HtmlFactory.php:
--------------------------------------------------------------------------------
1 | $this->name, 'path' => $this->path));
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Creational/AbstractFactory/Json/Text.php:
--------------------------------------------------------------------------------
1 | $this->text));
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Creational/AbstractFactory/JsonFactory.php:
--------------------------------------------------------------------------------
1 | name = (string) $name;
28 | $this->path = (string) $path;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Creational/AbstractFactory/README.md:
--------------------------------------------------------------------------------
1 | # Abstract Factory
2 |
3 | ## Propósito
4 |
5 | Criar séries de objetos correlatos ou dependentes sem especificar suas classes
6 | concretas. Geralmente todas as classes criadas implementam uma mesma interface.
7 | O cliente da Abstract Factory não se importa sobre como esses objetos são criados,
8 | apenas como eles interagem entre si.
9 |
10 | ## Diagrama UML
11 |
12 | 
13 |
--------------------------------------------------------------------------------
/Creational/AbstractFactory/Tests/AbstractFactoryTest.php:
--------------------------------------------------------------------------------
1 | createText('Lorem Ipsum'),
33 | $factory->createPicture('/image.jpg', 'caption'),
34 | $factory->createText('footnotes')
35 | );
36 |
37 | $this->assertContainsOnly('DesignPatterns\Creational\AbstractFactory\MediaInterface', $article);
38 |
39 | /* this is the time to look at the Builder pattern. This pattern
40 | * helps you to create complex object like that article above with
41 | * a given Abstract Factory
42 | */
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Creational/AbstractFactory/Text.php:
--------------------------------------------------------------------------------
1 | text = (string) $text;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Creational/AbstractFactory/uml/AbstractFactory.uml:
--------------------------------------------------------------------------------
1 |
2 |
3 | PHP
4 | \DesignPatterns\Creational\AbstractFactory\AbstractFactory
5 |
6 | \DesignPatterns\Creational\AbstractFactory\Html\Text
7 | \DesignPatterns\Creational\AbstractFactory\Html\Picture
8 | \DesignPatterns\Creational\AbstractFactory\HtmlFactory
9 | \DesignPatterns\Creational\AbstractFactory\JsonFactory
10 | \DesignPatterns\Creational\AbstractFactory\AbstractFactory
11 | \DesignPatterns\Creational\AbstractFactory\MediaInterface
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | Fields
32 | Constants
33 | Constructors
34 | Methods
35 |
36 | private
37 |
38 |
39 |
--------------------------------------------------------------------------------
/Creational/AbstractFactory/uml/uml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webfatorial/PadroesDeProjetoPHP/29e0acbb384dba6415141d3ae0270a31fb527553/Creational/AbstractFactory/uml/uml.png
--------------------------------------------------------------------------------
/Creational/Builder/BikeBuilder.php:
--------------------------------------------------------------------------------
1 | bike->setPart('engine', new Parts\Engine());
29 | }
30 |
31 | /**
32 | * {@inheritdoc}
33 | */
34 | public function addWheel()
35 | {
36 | $this->bike->setPart('forwardWheel', new Parts\Wheel());
37 | $this->bike->setPart('rearWheel', new Parts\Wheel());
38 | }
39 |
40 | /**
41 | * {@inheritdoc}
42 | */
43 | public function createVehicle()
44 | {
45 | $this->bike = new Parts\Bike();
46 | }
47 |
48 | /**
49 | * {@inheritdoc}
50 | */
51 | public function getVehicle()
52 | {
53 | return $this->bike;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/Creational/Builder/BuilderInterface.php:
--------------------------------------------------------------------------------
1 | car->setPart('rightdoor', new Parts\Door());
21 | $this->car->setPart('leftDoor', new Parts\Door());
22 | }
23 |
24 | /**
25 | * @return void
26 | */
27 | public function addEngine()
28 | {
29 | $this->car->setPart('engine', new Parts\Engine());
30 | }
31 |
32 | /**
33 | * @return void
34 | */
35 | public function addWheel()
36 | {
37 | $this->car->setPart('wheelLF', new Parts\Wheel());
38 | $this->car->setPart('wheelRF', new Parts\Wheel());
39 | $this->car->setPart('wheelLR', new Parts\Wheel());
40 | $this->car->setPart('wheelRR', new Parts\Wheel());
41 | }
42 |
43 | /**
44 | * @return void
45 | */
46 | public function createVehicle()
47 | {
48 | $this->car = new Parts\Car();
49 | }
50 |
51 | /**
52 | * @return Parts\Car
53 | */
54 | public function getVehicle()
55 | {
56 | return $this->car;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/Creational/Builder/Director.php:
--------------------------------------------------------------------------------
1 | createVehicle();
24 | $builder->addDoors();
25 | $builder->addEngine();
26 | $builder->addWheel();
27 |
28 | return $builder->getVehicle();
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Creational/Builder/Parts/Bike.php:
--------------------------------------------------------------------------------
1 | data[$key] = $value;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Creational/Builder/Parts/Wheel.php:
--------------------------------------------------------------------------------
1 | director = new Director();
21 | }
22 |
23 | public function getBuilder()
24 | {
25 | return array(
26 | array(new CarBuilder()),
27 | array(new BikeBuilder())
28 | );
29 | }
30 |
31 | /**
32 | * Here we test the build process. Notice that the client don't know
33 | * anything about the contrete builder.
34 | *
35 | * @dataProvider getBuilder
36 | */
37 | public function testBuild(BuilderInterface $builder)
38 | {
39 | $newVehicle = $this->director->build($builder);
40 | $this->assertInstanceOf('DesignPatterns\Creational\Builder\Parts\Vehicle', $newVehicle);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Creational/Builder/uml/uml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webfatorial/PadroesDeProjetoPHP/29e0acbb384dba6415141d3ae0270a31fb527553/Creational/Builder/uml/uml.png
--------------------------------------------------------------------------------
/Creational/FactoryMethod/Bicycle.php:
--------------------------------------------------------------------------------
1 | color = $rgb;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Creational/FactoryMethod/FactoryMethod.php:
--------------------------------------------------------------------------------
1 | createVehicle($type);
35 | $obj->setColor("#f00");
36 |
37 | return $obj;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Creational/FactoryMethod/Ferrari.php:
--------------------------------------------------------------------------------
1 | color = $rgb;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Creational/FactoryMethod/GermanFactory.php:
--------------------------------------------------------------------------------
1 | addTuningAMG();
24 |
25 | return $obj;
26 | break;
27 | default:
28 | throw new \InvalidArgumentException("$type is not a valid vehicle");
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Creational/FactoryMethod/ItalianFactory.php:
--------------------------------------------------------------------------------
1 | color = $rgb;
21 | }
22 |
23 | /**
24 | * although tuning by AMG is only offered for Mercedes Cars,
25 | * this is a valid coding example ...
26 | */
27 | public function addTuningAMG()
28 | {
29 |
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Creational/FactoryMethod/README.md:
--------------------------------------------------------------------------------
1 | # Factory Method
2 |
3 | ## Propósito
4 |
5 | O bom do SimpleFactory é que você pode "subclasseá-lo" para implementar diferentes
6 | maneiras de criar objetos.
7 |
8 | Para casos simples, essa classe abstrata poderia ser apenas uma internface.
9 |
10 | Esse Padrão é um Padrão de Projeto "real" porque está consonante ao Princípio da
11 | Inversão de Dependência (Dependency Inversion Principle), o "D" dos princípios
12 | S.O.L.I.D.
13 |
14 | Isso significa que a classe FactoryMethod depende de abstrações, não de classes
15 | concretas. Esse é o verdadeiro "truque" comparado a Simple Factory ou Static
16 | Factory.
17 |
18 | ## Diagrama UML
19 |
20 | 
21 |
--------------------------------------------------------------------------------
/Creational/FactoryMethod/Tests/FactoryMethodTest.php:
--------------------------------------------------------------------------------
1 | type as $oneType) {
36 | $vehicle = $shop->create($oneType);
37 | $this->assertInstanceOf('DesignPatterns\Creational\FactoryMethod\VehicleInterface', $vehicle);
38 | }
39 | }
40 |
41 | /**
42 | * @dataProvider getShop
43 | * @expectedException \InvalidArgumentException
44 | * @expectedExceptionMessage spaceship is not a valid vehicle
45 | */
46 | public function testUnknownType(FactoryMethod $shop)
47 | {
48 | $shop->create('spaceship');
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/Creational/FactoryMethod/VehicleInterface.php:
--------------------------------------------------------------------------------
1 |
2 |
3 | PHP
4 | \DesignPatterns\Creational\Multiton\Multiton
5 |
6 | \DesignPatterns\Creational\Multiton\Multiton
7 |
8 |
9 |
10 |
11 |
12 |
13 | Fields
14 | Constants
15 | Constructors
16 | Methods
17 |
18 | private
19 |
20 |
21 |
--------------------------------------------------------------------------------
/Creational/Multiton/uml/uml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webfatorial/PadroesDeProjetoPHP/29e0acbb384dba6415141d3ae0270a31fb527553/Creational/Multiton/uml/uml.png
--------------------------------------------------------------------------------
/Creational/Pool/Pool.php:
--------------------------------------------------------------------------------
1 | class = $class;
14 | }
15 |
16 | public function get()
17 | {
18 | if (count($this->instances) > 0) {
19 | return array_pop($this->instances);
20 | }
21 |
22 | return new $this->class();
23 | }
24 |
25 | public function dispose($instance)
26 | {
27 | $this->instances[] = $instance;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Creational/Pool/Processor.php:
--------------------------------------------------------------------------------
1 | pool = $pool;
16 | }
17 |
18 | public function process($image)
19 | {
20 | if ($this->processing++ < $this->maxProcesses) {
21 | $this->createWorker($image);
22 | } else {
23 | $this->pushToWaitingQueue($image);
24 | }
25 | }
26 |
27 | private function createWorker($image)
28 | {
29 | $worker = $this->pool->get();
30 | $worker->run($image, array($this, 'processDone'));
31 | }
32 |
33 | public function processDone($worker)
34 | {
35 | $this->processing--;
36 | $this->pool->dispose($worker);
37 |
38 | if (count($this->waitingQueue) > 0) {
39 | $this->createWorker($this->popFromWaitingQueue());
40 | }
41 | }
42 |
43 | private function pushToWaitingQueue($image)
44 | {
45 | $this->waitingQueue[] = $image;
46 | }
47 |
48 | private function popFromWaitingQueue()
49 | {
50 | return array_pop($this->waitingQueue);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/Creational/Pool/README.md:
--------------------------------------------------------------------------------
1 | Pool
2 | ====
3 |
4 | ## Propósito
5 |
6 | Ser um Padrão de Projeto que usa uma série de objetos
7 | inicializados mantidos prontos para uso -- uma "pool" (poço, tanque) -- ao invés
8 | de os instânciar e destruir conforme a demanda. Um cliente requererá um objeto da
9 | poll e fará operações neste objeto retornado. Quando o cliente tiver terminado,
10 | retornará o objeto -- que é um tipo específico de objeto "factory" -- para a poll
11 | ao invés de destruí-lo.
12 |
13 | Usar este Padrão pode oferecer uma melhoria significativa de performance em
14 | situações em que o custo de inicializar um objeto é alto, a taxa de instânciação
15 | é alta e o número de instâncias em uso a qualquer momento é baixo. O objeto
16 | retirado da poll é obtido em um tempo previsível quando a criação de novos
17 | objetos (especialmente através da rede) pode levar algum tempo.
18 |
19 | Entretanto, esses benefícios são em sua maioria verdadeiros para objetos que são
20 | dispendiosos em relação ao tempo, tal como conexões a BDs, conexões a sockets,
21 | threads e grandes objetos de gráficos como fontes e bitmaps. Em certas situações,
22 | "object pooling" (que não armazena nenhum recurso externo, mas ocupa memória)
23 | pode não ser eficiente e pode ocasionar decréscimo de performance.
24 |
25 | ## Diagrama UML
26 |
27 | 
28 |
--------------------------------------------------------------------------------
/Creational/Pool/Tests/PoolTest.php:
--------------------------------------------------------------------------------
1 | get();
19 |
20 | $this->assertEquals(1, $worker->id);
21 |
22 | $worker->id = 5;
23 | $pool->dispose($worker);
24 |
25 | $this->assertEquals(5, $pool->get()->id);
26 | $this->assertEquals(1, $pool->get()->id);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Creational/Pool/Worker.php:
--------------------------------------------------------------------------------
1 |
2 |
3 | PHP
4 | \DesignPatterns\Creational\Pool\Processor
5 |
6 | \DesignPatterns\Creational\Pool\Pool
7 | \DesignPatterns\Creational\Pool\Processor
8 | \DesignPatterns\Creational\Pool\Worker
9 |
10 |
11 |
12 |
13 |
14 |
15 | Fields
16 | Constants
17 | Constructors
18 | Methods
19 |
20 | private
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Creational/Pool/uml/uml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webfatorial/PadroesDeProjetoPHP/29e0acbb384dba6415141d3ae0270a31fb527553/Creational/Pool/uml/uml.png
--------------------------------------------------------------------------------
/Creational/Prototype/BarBookPrototype.php:
--------------------------------------------------------------------------------
1 | title;
32 | }
33 |
34 | /**
35 | * @param string $title
36 | */
37 | public function setTitle($title)
38 | {
39 | $this->title = $title;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Creational/Prototype/FooBookPrototype.php:
--------------------------------------------------------------------------------
1 | setTitle('Foo Book No ' . $i);
12 | }
13 |
14 | for ($i = 0; $i < 5000; $i++) {
15 | $book = clone $barPrototype;
16 | $book->setTitle('Bar Book No ' . $i);
17 | }
18 |
--------------------------------------------------------------------------------
/Creational/Prototype/uml/Prototype.uml:
--------------------------------------------------------------------------------
1 |
2 |
3 | PHP
4 | \DesignPatterns\Creational\Prototype\BarBookPrototype
5 |
6 | \DesignPatterns\Creational\Prototype\BookPrototype
7 | \DesignPatterns\Creational\Prototype\FooBookPrototype
8 | \DesignPatterns\Creational\Prototype\BarBookPrototype
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | Fields
29 | Constants
30 | Constructors
31 | Methods
32 |
33 | private
34 |
35 |
36 |
--------------------------------------------------------------------------------
/Creational/Prototype/uml/uml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webfatorial/PadroesDeProjetoPHP/29e0acbb384dba6415141d3ae0270a31fb527553/Creational/Prototype/uml/uml.png
--------------------------------------------------------------------------------
/Creational/README.md:
--------------------------------------------------------------------------------
1 | # Criacional
2 |
3 | Em Engenharia de Software, Padrões de Projeto Criacionais são os que lidam com
4 | os mecanismos de criação de objetos, tentando criá-los de uma maneira adequada
5 | a cada situação. A forma básica de criação de objeto pode resultar em problemas
6 | de design ou acrescentar complexidade adicional ao design. Padrões de Projeto
7 | Criacionais resolvem este problema ao controlar a forma como objetos são criados.
8 |
9 | * [AbstractFactory](AbstractFactory) [:notebook:](http://pt.wikipedia.org/wiki/Abstract_Factory)
10 | * [Builder](Builder) [:notebook:](http://pt.wikipedia.org/wiki/Builder)
11 | * [FactoryMethod](FactoryMethod) [:notebook:](http://pt.wikipedia.org/wiki/Factory_Method)
12 | * [Multiton](Multiton) (considerado um anti-pattern! :no_entry:)
13 | * [Pool](Pool) [:notebook:](http://en.wikipedia.org/wiki/Object_pool_pattern)
14 | * [Prototype](Prototype) [:notebook:](http://pt.wikipedia.org/wiki/Prototype)
15 | * [SimpleFactory](SimpleFactory)
16 | * [Singleton](Singleton) [:notebook:](http://pt.wikipedia.org/wiki/Singleton) (considerado um anti-pattern! :no_entry:)
17 | * [StaticFactory](StaticFactory)
18 |
--------------------------------------------------------------------------------
/Creational/SimpleFactory/Bicycle.php:
--------------------------------------------------------------------------------
1 | typeList = array(
22 | 'bicycle' => __NAMESPACE__ . '\Bicycle',
23 | 'other' => __NAMESPACE__ . '\Scooter'
24 | );
25 | }
26 |
27 | /**
28 | * Creates a vehicle
29 | *
30 | * @param string $type a known type key
31 | *
32 | * @return VehicleInterface a new instance of VehicleInterface
33 | * @throws \InvalidArgumentException
34 | */
35 | public function createVehicle($type)
36 | {
37 | if (!array_key_exists($type, $this->typeList)) {
38 | throw new \InvalidArgumentException("$type is not valid vehicle");
39 | }
40 | $className = $this->typeList[$type];
41 |
42 | return new $className();
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Creational/SimpleFactory/README.md:
--------------------------------------------------------------------------------
1 | # Simple Factory
2 |
3 | ## Propósito
4 |
5 | Concrete Factory é um Padrão simples de factory (fábrica).
6 |
7 | Difere da Static Factory porque NÃO É estático e, como você sabe, `static` =>
8 | `global` => evil!
9 |
10 | Portanto, você pode ter múltiplas factories diferentemente parametrizadas, pode
11 | "subclassear" e pode usar mockups.
12 |
13 | ## Diagrama UML
14 |
15 | 
16 |
--------------------------------------------------------------------------------
/Creational/SimpleFactory/Scooter.php:
--------------------------------------------------------------------------------
1 | factory = new ConcreteFactory();
18 | }
19 |
20 | public function getType()
21 | {
22 | return array(
23 | array('bicycle'),
24 | array('other')
25 | );
26 | }
27 |
28 | /**
29 | * @dataProvider getType
30 | */
31 | public function testCreation($type)
32 | {
33 | $obj = $this->factory->createVehicle($type);
34 | $this->assertInstanceOf('DesignPatterns\Creational\SimpleFactory\VehicleInterface', $obj);
35 | }
36 |
37 | /**
38 | * @expectedException \InvalidArgumentException
39 | */
40 | public function testBadType()
41 | {
42 | $this->factory->createVehicle('car');
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Creational/SimpleFactory/VehicleInterface.php:
--------------------------------------------------------------------------------
1 |
2 |
3 | PHP
4 | \DesignPatterns\Creational\SimpleFactory\ConcreteFactory
5 |
6 | \DesignPatterns\Creational\SimpleFactory\Scooter
7 | \DesignPatterns\Creational\SimpleFactory\ConcreteFactory
8 | \DesignPatterns\Creational\SimpleFactory\VehicleInterface
9 | \DesignPatterns\Creational\SimpleFactory\Bicycle
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | Fields
30 | Constants
31 | Constructors
32 | Methods
33 |
34 | private
35 |
36 |
37 |
--------------------------------------------------------------------------------
/Creational/SimpleFactory/uml/uml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webfatorial/PadroesDeProjetoPHP/29e0acbb384dba6415141d3ae0270a31fb527553/Creational/SimpleFactory/uml/uml.png
--------------------------------------------------------------------------------
/Creational/Singleton/README.md:
--------------------------------------------------------------------------------
1 | # Singleton
2 |
3 | **ISSO É CONSIDERADO UM ANTI-PATTERN! PARA UMA MELHOR TESTABILIDADE E
4 | MANTENIBILIDADE, USE INJEÇÃO DE DEPENDÊNCIA!**
5 |
6 | # Propósito
7 |
8 | Ter apenas uma instância de um objeto na aplicação que irá lidar com as chamadas.
9 |
10 | ## Exemplos
11 |
12 | * DB Connector
13 | * Logger (também pode ser um Multiton se houver vários arquivos de log para vários
14 | propósitos diferentes
15 | * Travar um arquivo para a aplicação (há somente um no sistema de arquivos...)
16 |
17 | ## Diagrama UML
18 |
19 | 
20 |
--------------------------------------------------------------------------------
/Creational/Singleton/Singleton.php:
--------------------------------------------------------------------------------
1 | assertInstanceOf('DesignPatterns\Creational\Singleton\Singleton', $firstCall);
17 | $secondCall = Singleton::getInstance();
18 | $this->assertSame($firstCall, $secondCall);
19 | }
20 |
21 | public function testNoConstructor()
22 | {
23 | $obj = Singleton::getInstance();
24 |
25 | $refl = new \ReflectionObject($obj);
26 | $meth = $refl->getMethod('__construct');
27 | $this->assertTrue($meth->isPrivate());
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Creational/Singleton/uml/Singleton.uml:
--------------------------------------------------------------------------------
1 |
2 |
3 | PHP
4 | \DesignPatterns\Creational\Singleton\Singleton
5 |
6 | \DesignPatterns\Creational\Singleton\Singleton
7 |
8 |
9 |
10 |
11 |
12 |
13 | Fields
14 | Constants
15 | Constructors
16 | Methods
17 |
18 | private
19 |
20 |
21 |
--------------------------------------------------------------------------------
/Creational/Singleton/uml/uml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webfatorial/PadroesDeProjetoPHP/29e0acbb384dba6415141d3ae0270a31fb527553/Creational/Singleton/uml/uml.png
--------------------------------------------------------------------------------
/Creational/StaticFactory/FormatNumber.php:
--------------------------------------------------------------------------------
1 | global => evil
7 | * Note2: Cannot be subclassed or mock-upped or have multiple different instances
8 | */
9 | class StaticFactory
10 | {
11 | /**
12 | * the parametrized function to get create an instance
13 | *
14 | * @param string $type
15 | *
16 | * @static
17 | *
18 | * @throws \InvalidArgumentException
19 | * @return FormatterInterface
20 | */
21 | public static function factory($type)
22 | {
23 | $className = __NAMESPACE__ . '\Format' . ucfirst($type);
24 |
25 | if (!class_exists($className)) {
26 | throw new \InvalidArgumentException('Missing format class.');
27 | }
28 |
29 | return new $className();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Creational/StaticFactory/Tests/StaticFactoryTest.php:
--------------------------------------------------------------------------------
1 | assertInstanceOf('DesignPatterns\Creational\StaticFactory\FormatterInterface', $obj);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Creational/StaticFactory/uml/StaticFactory.uml:
--------------------------------------------------------------------------------
1 |
2 |
3 | PHP
4 | \DesignPatterns\Creational\StaticFactory\FormatNumber
5 |
6 | \DesignPatterns\Creational\StaticFactory\FormatNumber
7 | \DesignPatterns\Creational\StaticFactory\StaticFactory
8 | \DesignPatterns\Creational\StaticFactory\FormatString
9 | \DesignPatterns\Creational\StaticFactory\FormatterInterface
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | Fields
30 | Constants
31 | Constructors
32 | Methods
33 |
34 | private
35 |
36 |
37 |
--------------------------------------------------------------------------------
/Creational/StaticFactory/uml/uml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webfatorial/PadroesDeProjetoPHP/29e0acbb384dba6415141d3ae0270a31fb527553/Creational/StaticFactory/uml/uml.png
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2011 Dominik Liebler
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/More/Delegation/JuniorDeveloper.php:
--------------------------------------------------------------------------------
1 | slave = $junior;
22 | }
23 |
24 | /**
25 | * TeamLead drink coffee, junior work
26 | * @return mixed
27 | */
28 | public function writeCode()
29 | {
30 | return $this->slave->writeBadCode();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/More/Delegation/Tests/DelegationTest.php:
--------------------------------------------------------------------------------
1 | assertEquals($junior->writeBadCode(), $teamLead->writeCode());
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/More/Delegation/Usage.php:
--------------------------------------------------------------------------------
1 | writeCode();
10 |
--------------------------------------------------------------------------------
/More/Delegation/uml/Delegation.uml:
--------------------------------------------------------------------------------
1 |
2 |
3 | PHP
4 | \DesignPatterns\More\Delegation\JuniorDeveloper
5 |
6 | \DesignPatterns\More\Delegation\JuniorDeveloper
7 | \DesignPatterns\More\Delegation\TeamLead
8 |
9 |
10 |
11 |
12 |
13 |
14 | Fields
15 | Constants
16 | Constructors
17 | Methods
18 |
19 | private
20 |
21 |
22 |
--------------------------------------------------------------------------------
/More/Delegation/uml/uml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webfatorial/PadroesDeProjetoPHP/29e0acbb384dba6415141d3ae0270a31fb527553/More/Delegation/uml/uml.png
--------------------------------------------------------------------------------
/More/README.md:
--------------------------------------------------------------------------------
1 | # Mais
2 |
3 | * [Delegation](Delegation) [:notebook:](http://en.wikipedia.org/wiki/Delegation_pattern)
4 | * [ServiceLocator](ServiceLocator) [:notebook:](http://en.wikipedia.org/wiki/Service_locator_pattern)
5 | * [Repository](Repository)
6 |
--------------------------------------------------------------------------------
/More/Repository/MemoryStorage.php:
--------------------------------------------------------------------------------
1 | data = array();
18 | $this->lastId = 0;
19 | }
20 |
21 | /**
22 | * {@inheritdoc}
23 | */
24 | public function persist($data)
25 | {
26 | $this->data[++$this->lastId] = $data;
27 | return $this->lastId;
28 | }
29 |
30 | /**
31 | * {@inheritdoc}
32 | */
33 | public function retrieve($id)
34 | {
35 | return isset($this->data[$id]) ? $this->data[$id] : null;
36 | }
37 |
38 | /**
39 | * {@inheritdoc}
40 | */
41 | public function delete($id)
42 | {
43 | if(!isset($this->data[$id])){
44 | return false;
45 | }
46 |
47 | $this->data[$id] = null;
48 | unset($this->data[$id]);
49 |
50 | return true;
51 | }
52 |
53 | }
54 |
55 |
--------------------------------------------------------------------------------
/More/Repository/README.md:
--------------------------------------------------------------------------------
1 | # Repository
2 |
3 | ## Propósito
4 |
5 | Fazer a mediação entre domínio e camadas de data mapping usando interfaces tipo
6 | coleção para acessar objetos de domínio.
7 |
8 | Esse Padrão encapsula o conjunto de objetos persistidos em armazenamento de dados
9 | e as operações feitas nele, provendo uma visão mais orientada a objetos da
10 | camada de persistência.
11 |
12 | Repository também suporta o objetivo de alcançar uma separação clara e dependência
13 | de mão única entre o domínio e camadas de data mapping.
14 |
15 | ## Exemplos
16 |
17 | * Doctrine2 ORM: há um Repository que faz a mediação entre Entity e DBAL e
18 | contém métodos para retornar objetos
19 | * Framework Laravel
20 |
21 | ## Diagrama UML
22 |
23 | 
24 |
--------------------------------------------------------------------------------
/More/Repository/Storage.php:
--------------------------------------------------------------------------------
1 |
2 |
3 | PHP
4 | \DesignPatterns\Repository\PostRepository
5 |
6 | \DesignPatterns\Repository\Storage
7 | \DesignPatterns\Repository\MemoryStorage
8 | \DesignPatterns\Repository\Post
9 | \DesignPatterns\Repository\PostRepository
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | Fields
22 | Constants
23 | Constructors
24 | Methods
25 |
26 | private
27 |
28 |
29 |
--------------------------------------------------------------------------------
/More/Repository/uml/uml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webfatorial/PadroesDeProjetoPHP/29e0acbb384dba6415141d3ae0270a31fb527553/More/Repository/uml/uml.png
--------------------------------------------------------------------------------
/More/ServiceLocator/DatabaseService.php:
--------------------------------------------------------------------------------
1 |
2 |
3 | PHP
4 | \DesignPatterns\More\ServiceLocator\DatabaseServiceInterface
5 |
6 | \DesignPatterns\More\ServiceLocator\DatabaseServiceInterface
7 | \DesignPatterns\More\ServiceLocator\LogService
8 | \DesignPatterns\More\ServiceLocator\ServiceLocator
9 | \DesignPatterns\More\ServiceLocator\ServiceLocatorInterface
10 | \DesignPatterns\More\ServiceLocator\LogServiceInterface
11 | \DesignPatterns\More\ServiceLocator\DatabaseService
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | Fields
32 | Constants
33 | Constructors
34 | Methods
35 |
36 | private
37 |
38 |
39 |
--------------------------------------------------------------------------------
/More/ServiceLocator/uml/uml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webfatorial/PadroesDeProjetoPHP/29e0acbb384dba6415141d3ae0270a31fb527553/More/ServiceLocator/uml/uml.png
--------------------------------------------------------------------------------
/Structural/Adapter/Book.php:
--------------------------------------------------------------------------------
1 | eBook = $ebook;
26 | }
27 |
28 | /**
29 | * This class makes the proper translation from one interface to another
30 | */
31 | public function open()
32 | {
33 | $this->eBook->pressStart();
34 | }
35 |
36 | /**
37 | * turns pages
38 | */
39 | public function turnPage()
40 | {
41 | $this->eBook->pressNext();
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Structural/Adapter/EBookInterface.php:
--------------------------------------------------------------------------------
1 | open();
39 | $book->turnPage();
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Structural/Adapter/uml/Adapter.uml:
--------------------------------------------------------------------------------
1 |
2 |
3 | PHP
4 | \DesignPatterns\Structural\Adapter\Book
5 |
6 | \DesignPatterns\Structural\Adapter\EBookAdapter
7 | \DesignPatterns\Structural\Adapter\Book
8 | \DesignPatterns\Structural\Adapter\Kindle
9 | \DesignPatterns\Structural\Adapter\EBookInterface
10 | \DesignPatterns\Structural\Adapter\PaperBookInterface
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | Fields
35 | Constants
36 | Constructors
37 | Methods
38 |
39 | private
40 |
41 |
42 |
--------------------------------------------------------------------------------
/Structural/Adapter/uml/uml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webfatorial/PadroesDeProjetoPHP/29e0acbb384dba6415141d3ae0270a31fb527553/Structural/Adapter/uml/uml.png
--------------------------------------------------------------------------------
/Structural/Bridge/Assemble.php:
--------------------------------------------------------------------------------
1 | workShop1->work();
20 | $this->workShop2->work();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Structural/Bridge/Motorcycle.php:
--------------------------------------------------------------------------------
1 | workShop1->work();
20 | $this->workShop2->work();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Structural/Bridge/Produce.php:
--------------------------------------------------------------------------------
1 | expectOutputString('Car Produced Assembled');
17 | $vehicle->manufacture();
18 | }
19 |
20 | public function testMotorcycle()
21 | {
22 | $vehicle = new Motorcycle(new Produce(), new Assemble());
23 | $this->expectOutputString('Motorcycle Produced Assembled');
24 | $vehicle->manufacture();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Structural/Bridge/Vehicle.php:
--------------------------------------------------------------------------------
1 | workShop1 = $workShop1;
17 | $this->workShop2 = $workShop2;
18 | }
19 |
20 | public function manufacture()
21 | {
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Structural/Bridge/Workshop.php:
--------------------------------------------------------------------------------
1 | elements as $element) {
31 | $formCode .= $element->render($indent + 1) . PHP_EOL;
32 | }
33 |
34 | return $formCode;
35 | }
36 |
37 | /**
38 | * @param FormElement $element
39 | */
40 | public function addElement(FormElement $element)
41 | {
42 | $this->elements[] = $element;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Structural/Composite/FormElement.php:
--------------------------------------------------------------------------------
1 | ';
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Structural/Composite/README.md:
--------------------------------------------------------------------------------
1 | # Composite
2 |
3 | ## Propósito
4 |
5 | Tratar um grupo de objetos da mesma maneira, como se fossem uma instância de um
6 | único objeto.
7 |
8 | ## Exemplos
9 |
10 | * Uma instância de uma classe de formulário lida com todos seus elementos como
11 | se uma única instância desse formumário, quando `render()` é chamado, ele
12 | subsequentemente roda através de todos seus elementos-filhos e chama `render()`
13 | neles
14 | * `Zend_Config`: uma árvore de opções de configuração, cada uma é um objeto `Zend_Config`
15 |
16 | ## Diagrama UML
17 |
18 | 
19 |
--------------------------------------------------------------------------------
/Structural/Composite/Tests/CompositeTest.php:
--------------------------------------------------------------------------------
1 | addElement(new Composite\TextElement());
17 | $form->addElement(new Composite\InputElement());
18 | $embed = new Composite\Form();
19 | $embed->addElement(new Composite\TextElement());
20 | $embed->addElement(new Composite\InputElement());
21 | $form->addElement($embed); // here we have a embedded form (like SF2 does)
22 |
23 | $this->assertRegExp('#^\s{4}#m', $form->render());
24 | }
25 |
26 | /**
27 | * The all point of this pattern, a Composite must inherit from the node
28 | * if you want to builld trees
29 | */
30 | public function testFormImplementsFormEelement()
31 | {
32 | $className = 'DesignPatterns\Structural\Composite\Form';
33 | $abstractName = 'DesignPatterns\Structural\Composite\FormElement';
34 | $this->assertTrue(is_subclass_of($className, $abstractName));
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Structural/Composite/TextElement.php:
--------------------------------------------------------------------------------
1 |
2 |
3 | PHP
4 | \DesignPatterns\Structural\Composite\InputElement
5 |
6 | \DesignPatterns\Structural\Composite\TextElement
7 | \DesignPatterns\Structural\Composite\FormElement
8 | \DesignPatterns\Structural\Composite\InputElement
9 | \DesignPatterns\Structural\Composite\Form
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | \DesignPatterns\Structural\Composite\InputElement
33 |
34 |
35 | Fields
36 | Constants
37 | Constructors
38 | Methods
39 |
40 | private
41 |
42 |
43 |
--------------------------------------------------------------------------------
/Structural/Composite/uml/uml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webfatorial/PadroesDeProjetoPHP/29e0acbb384dba6415141d3ae0270a31fb527553/Structural/Composite/uml/uml.png
--------------------------------------------------------------------------------
/Structural/Composite/uml/uml.txt:
--------------------------------------------------------------------------------
1 | @startuml
2 | class Form {
3 | #elements : array|FormElement[]
4 | +render($indent = 0 : int)
5 | +addElement(FormElement $element)
6 | }
7 |
8 | abstract class FormElement {
9 | +render($indent = 0 : int)
10 | }
11 |
12 | class InputElement {
13 | +render($indent = 0 : int)
14 | }
15 |
16 | class TextElement {
17 | +render($indent = 0 : int)
18 | }
19 |
20 | FormElement <|.. TextElement
21 | FormElement <|.. InputElement
22 | FormElement <|.. Form
23 | @enduml
--------------------------------------------------------------------------------
/Structural/DataMapper/README.md:
--------------------------------------------------------------------------------
1 | # Data Mapper
2 |
3 | ## Propósito
4 |
5 | Um Data Mapper é uma camada de acesso a dados que realiza transferências
6 | bidirecionais e dados entre uma cama de persistência (geralmente um Banco de
7 | Dados Relacional) e uma representação de dados em memória (a camada de domínio).
8 | O objetivo desse Padrão é manter a representação de dados em memória e a camada
9 | de persistência de dados independentes uma da outra e do próprio Data Mapper.
10 |
11 | A camada é composta por um ou mais mappers -- ou Data Access Objects (Objetos de
12 | Acesso a Dados) -- fazendo a transferência de dados. Cada implementação de um
13 | mapper varia em escopo: mappers genéricos lidarão com vários tipos diferentes de
14 | entidades de domínio; mappers dedicados lidarão com um ou alguns.
15 |
16 | A chave desse Padrão -- diferentemente do Active Record -- é fazer com que o
17 | modelo de dados (data model) siga o Princípio da Responsabilidade Única do
18 | S.O.L.I.D.
19 |
20 | ## Exemplos
21 |
22 | * DB Object Relational Mapper (ORM): Doctrine2 usa um DAO chamado "EntityRepository"
23 |
24 | ## Diagrama UML
25 |
26 | 
27 |
--------------------------------------------------------------------------------
/Structural/DataMapper/User.php:
--------------------------------------------------------------------------------
1 | userId = $id;
38 | $this->username = $username;
39 | $this->email = $email;
40 | }
41 |
42 | /**
43 | * @return int
44 | */
45 | public function getUserId()
46 | {
47 | return $this->userId;
48 | }
49 |
50 | /**
51 | * @param int $userId
52 | */
53 | public function setUserID($userId)
54 | {
55 | $this->userId = $userId;
56 | }
57 |
58 | /**
59 | * @return string
60 | */
61 | public function getUsername()
62 | {
63 | return $this->username;
64 | }
65 |
66 | /**
67 | * @param string $username
68 | */
69 | public function setUsername($username)
70 | {
71 | $this->username = $username;
72 | }
73 |
74 | /**
75 | * @return string
76 | */
77 | public function getEmail()
78 | {
79 | return $this->email;
80 | }
81 |
82 | /**
83 | * @param string $email
84 | */
85 | public function setEmail($email)
86 | {
87 | $this->email = $email;
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/Structural/DataMapper/uml/DataMapper.uml:
--------------------------------------------------------------------------------
1 |
2 |
3 | PHP
4 | \DesignPatterns\Structural\DataMapper\User
5 |
6 | \DesignPatterns\Structural\DataMapper\User
7 | \DesignPatterns\Structural\DataMapper\UserMapper
8 |
9 |
10 |
11 |
12 |
13 | \DesignPatterns\Structural\DataMapper\User
14 |
15 |
16 | Fields
17 | Constants
18 | Constructors
19 | Methods
20 |
21 | private
22 |
23 |
24 |
--------------------------------------------------------------------------------
/Structural/DataMapper/uml/uml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webfatorial/PadroesDeProjetoPHP/29e0acbb384dba6415141d3ae0270a31fb527553/Structural/DataMapper/uml/uml.png
--------------------------------------------------------------------------------
/Structural/Decorator/Decorator.php:
--------------------------------------------------------------------------------
1 | wrapped = $wrappable;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Structural/Decorator/README.md:
--------------------------------------------------------------------------------
1 | # Decorator
2 |
3 | ## Propósito
4 |
5 | Dinamicamente adicionar novas funcionalidades a instância de classes.
6 |
7 | ## Exemplos
8 |
9 | * Zend Framework: decorators para instâncias de `Zend_Form_Element`
10 | * Web Service Layer: Decorators JSON e XML para um serviço REST (nesse caso,
11 | obviamente apenas um desses deve ser permitido)
12 |
13 | ## Diagrama UML
14 |
15 | 
16 |
--------------------------------------------------------------------------------
/Structural/Decorator/RenderInJson.php:
--------------------------------------------------------------------------------
1 | wrapped->renderData();
18 |
19 | return json_encode($output);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Structural/Decorator/RenderInXml.php:
--------------------------------------------------------------------------------
1 | wrapped->renderData();
18 |
19 | // do some fancy conversion to xml from array ...
20 |
21 | $doc = new \DOMDocument();
22 |
23 | foreach ($output as $key => $val) {
24 | $doc->appendChild($doc->createElement($key, $val));
25 | }
26 |
27 | return $doc->saveXML();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Structural/Decorator/RendererInterface.php:
--------------------------------------------------------------------------------
1 | data = $data;
21 | }
22 |
23 | /**
24 | * @return string
25 | */
26 | public function renderData()
27 | {
28 | return $this->data;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Structural/Decorator/uml/uml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webfatorial/PadroesDeProjetoPHP/29e0acbb384dba6415141d3ae0270a31fb527553/Structural/Decorator/uml/uml.png
--------------------------------------------------------------------------------
/Structural/DependencyInjection/AbstractConfig.php:
--------------------------------------------------------------------------------
1 | storage = $storage;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Structural/DependencyInjection/ArrayConfig.php:
--------------------------------------------------------------------------------
1 | storage[$key])) {
22 | return $this->storage[$key];
23 | }
24 | return $default;
25 | }
26 |
27 | /**
28 | * Set parameter
29 | *
30 | * @param string|int $key
31 | * @param mixed $value
32 | */
33 | public function set($key, $value)
34 | {
35 | $this->storage[$key] = $value;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Structural/DependencyInjection/Connection.php:
--------------------------------------------------------------------------------
1 | configuration = $config;
26 | }
27 |
28 | /**
29 | * connection using the injected config
30 | */
31 | public function connect()
32 | {
33 | $host = $this->configuration->get('host');
34 | // connection to host, authentication etc...
35 |
36 | //if connected
37 | $this->host = $host;
38 | }
39 |
40 | /*
41 | * Get currently connected host
42 | *
43 | * @return string
44 | */
45 | public function getHost()
46 | {
47 | return $this->host;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/Structural/DependencyInjection/Parameters.php:
--------------------------------------------------------------------------------
1 | source = include 'config.php';
16 | $this->config = new ArrayConfig($this->source);
17 | }
18 |
19 | public function testDependencyInjection()
20 | {
21 | $connection = new Connection($this->config);
22 | $connection->connect();
23 | $this->assertEquals($this->source['host'], $connection->getHost());
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Structural/DependencyInjection/Tests/config.php:
--------------------------------------------------------------------------------
1 | 'github.com');
4 |
--------------------------------------------------------------------------------
/Structural/DependencyInjection/uml/DependencyInjection.uml:
--------------------------------------------------------------------------------
1 |
2 |
3 | PHP
4 | \DesignPatterns\Structural\DependencyInjection\AbstractConfig
5 |
6 | \DesignPatterns\Structural\DependencyInjection\Connection
7 | \DesignPatterns\Structural\DependencyInjection\ArrayConfig
8 | \DesignPatterns\Structural\DependencyInjection\Parameters
9 | \DesignPatterns\Structural\DependencyInjection\AbstractConfig
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | \DesignPatterns\Structural\DependencyInjection\AbstractConfig
29 |
30 |
31 | Fields
32 | Constants
33 | Constructors
34 | Methods
35 |
36 | private
37 |
38 |
39 |
--------------------------------------------------------------------------------
/Structural/DependencyInjection/uml/uml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webfatorial/PadroesDeProjetoPHP/29e0acbb384dba6415141d3ae0270a31fb527553/Structural/DependencyInjection/uml/uml.png
--------------------------------------------------------------------------------
/Structural/Facade/BiosInterface.php:
--------------------------------------------------------------------------------
1 | bios = $bios;
31 | $this->os = $os;
32 | }
33 |
34 | /**
35 | * turn on the system
36 | */
37 | public function turnOn()
38 | {
39 | $this->bios->execute();
40 | $this->bios->waitForKeyPress();
41 | $this->bios->launch($this->os);
42 | }
43 |
44 | /**
45 | * turn off the system
46 | */
47 | public function turnOff()
48 | {
49 | $this->os->halt();
50 | $this->bios->powerDown();
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/Structural/Facade/OsInterface.php:
--------------------------------------------------------------------------------
1 | getMockBuilder('DesignPatterns\Structural\Facade\BiosInterface')
16 | ->setMethods(array('launch', 'execute', 'waitForKeyPress'))
17 | ->disableAutoload()
18 | ->getMock();
19 | $operatingSys = $this->getMockBuilder('DesignPatterns\Structural\Facade\OsInterface')
20 | ->setMethods(array('getName'))
21 | ->disableAutoload()
22 | ->getMock();
23 | $bios->expects($this->once())
24 | ->method('launch')
25 | ->with($operatingSys);
26 | $operatingSys
27 | ->expects($this->once())
28 | ->method('getName')
29 | ->will($this->returnValue('Linux'));
30 |
31 | $facade = new Computer($bios, $operatingSys);
32 | return array(array($facade, $operatingSys));
33 | }
34 |
35 | /**
36 | * @dataProvider getComputer
37 | */
38 | public function testComputerOn(Computer $facade, $os)
39 | {
40 | // interface is simpler :
41 | $facade->turnOn();
42 | // but I can access to lower component
43 | $this->assertEquals('Linux', $os->getName());
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Structural/Facade/uml/Facade.uml:
--------------------------------------------------------------------------------
1 |
2 |
3 | PHP
4 | \DesignPatterns\Structural\Facade\BiosInterface
5 |
6 | \DesignPatterns\Structural\Facade\BiosInterface
7 | \DesignPatterns\Structural\Facade\OsInterface
8 | \DesignPatterns\Structural\Facade\Facade
9 |
10 |
11 |
12 |
13 |
14 | \DesignPatterns\Structural\Facade\BiosInterface
15 |
16 |
17 | Fields
18 | Constants
19 | Constructors
20 | Methods
21 |
22 | private
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Structural/Facade/uml/uml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webfatorial/PadroesDeProjetoPHP/29e0acbb384dba6415141d3ae0270a31fb527553/Structural/Facade/uml/uml.png
--------------------------------------------------------------------------------
/Structural/FluentInterface/README.md:
--------------------------------------------------------------------------------
1 | # Fluent Interface
2 |
3 | ## Propósito
4 |
5 | Escrever código que seja tão fácil de ler como sentenças em linguagem natural
6 | (como Português ou Inglês).
7 |
8 | ## Exemplos
9 |
10 | * QueryBuilder do Doctrine2 trabalha mais ou menos como essa classe complexa abaixo
11 | * PHPUnit usa Fluent Interfaces para construir objetos mock
12 | * Yii Framework: CDbCommand e CActiveRecord usam esse Padrão, também
13 |
14 | ## Diagrama UML
15 |
16 | 
17 |
--------------------------------------------------------------------------------
/Structural/FluentInterface/Sql.php:
--------------------------------------------------------------------------------
1 | fields = $fields;
35 |
36 | return $this;
37 | }
38 |
39 | /**
40 | * adds a FROM clause
41 | *
42 | * @param string $table
43 | * @param string $alias
44 | *
45 | * @return SQL
46 | */
47 | public function from($table, $alias)
48 | {
49 | $this->from[] = $table . ' AS ' . $alias;
50 |
51 | return $this;
52 | }
53 |
54 | /**
55 | * adds a WHERE condition
56 | *
57 | * @param string $condition
58 | *
59 | * @return SQL
60 | */
61 | public function where($condition)
62 | {
63 | $this->where[] = $condition;
64 |
65 | return $this;
66 | }
67 |
68 | /**
69 | * Gets the query, just an example of building a query,
70 | * no check on consistency
71 | *
72 | * @return string
73 | */
74 | public function getQuery()
75 | {
76 | return 'SELECT ' . implode(',', $this->fields)
77 | . ' FROM ' . implode(',', $this->from)
78 | . ' WHERE ' . implode(' AND ', $this->where);
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/Structural/FluentInterface/Tests/FluentInterfaceTest.php:
--------------------------------------------------------------------------------
1 | select(array('foo', 'bar'))
17 | ->from('foobar', 'f')
18 | ->where('f.bar = ?')
19 | ->getQuery();
20 |
21 | $this->assertEquals('SELECT foo,bar FROM foobar AS f WHERE f.bar = ?', $query);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Structural/FluentInterface/uml/FluentInterface.uml:
--------------------------------------------------------------------------------
1 |
2 |
3 | PHP
4 | \DesignPatterns\Structural\FluentInterface\Sql
5 |
6 | \DesignPatterns\Structural\FluentInterface\Sql
7 |
8 |
9 |
10 |
11 |
12 | \DesignPatterns\Structural\FluentInterface\Sql
13 |
14 |
15 | Fields
16 | Constants
17 | Constructors
18 | Methods
19 |
20 | private
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Structural/FluentInterface/uml/uml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webfatorial/PadroesDeProjetoPHP/29e0acbb384dba6415141d3ae0270a31fb527553/Structural/FluentInterface/uml/uml.png
--------------------------------------------------------------------------------
/Structural/Proxy/README.md:
--------------------------------------------------------------------------------
1 | # Proxy
2 |
3 | ## Propósito
4 |
5 | Fazer uma interface para qualquer coisa que seja custosa ou impossível de duplicar.
6 |
7 | ## Exemplos
8 |
9 | * Doctrine2 usa proxies para implementar mágica de framework -- por exemplo,
10 | instanciação preguiçosa (lazy initialization) -- enquanto o usuário continua a
11 | trabalhar com suas próprias classes e nunca usará ou nunca tocará nos proxies
12 |
13 | ## Diagrama UML
14 |
15 | 
16 |
--------------------------------------------------------------------------------
/Structural/Proxy/Record.php:
--------------------------------------------------------------------------------
1 | data = (array) $data;
21 | }
22 |
23 | /**
24 | * magic setter
25 | *
26 | * @param string $name
27 | * @param mixed $value
28 | *
29 | * @return void
30 | */
31 | public function __set($name, $value)
32 | {
33 | $this->data[(string) $name] = $value;
34 | }
35 |
36 | /**
37 | * magic getter
38 | *
39 | * @param string $name
40 | *
41 | * @return mixed|null
42 | */
43 | public function __get($name)
44 | {
45 | if (array_key_exists($name, $this->data)) {
46 | return $this->data[(string) $name];
47 | } else {
48 | return null;
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Structural/Proxy/RecordProxy.php:
--------------------------------------------------------------------------------
1 | isInitialized = true;
33 | $this->isDirty = true;
34 | }
35 | }
36 |
37 | /**
38 | * magic setter
39 | *
40 | * @param string $name
41 | * @param mixed $value
42 | *
43 | * @return void
44 | */
45 | public function __set($name, $value)
46 | {
47 | $this->isDirty = true;
48 | parent::__set($name, $value);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/Structural/Proxy/uml/Proxy.uml:
--------------------------------------------------------------------------------
1 |
2 |
3 | PHP
4 | \DesignPatterns\Structural\Proxy\Record
5 |
6 | \DesignPatterns\Structural\Proxy\Record
7 | \DesignPatterns\Structural\Proxy\RecordProxy
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | \DesignPatterns\Structural\Proxy\Record
19 |
20 |
21 | Fields
22 | Constants
23 | Constructors
24 | Methods
25 |
26 | private
27 |
28 |
29 |
--------------------------------------------------------------------------------
/Structural/Proxy/uml/uml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webfatorial/PadroesDeProjetoPHP/29e0acbb384dba6415141d3ae0270a31fb527553/Structural/Proxy/uml/uml.png
--------------------------------------------------------------------------------
/Structural/README.md:
--------------------------------------------------------------------------------
1 | # Estrutural
2 |
3 | Em Engenharia de Software, Padrões de Projeto Estruturais são os que facilitam
4 | o design ao identificar uma maneira simples de realizar relacionamentos entre
5 | entidades
6 |
7 | * [Adapter](Adapter) [:notebook:](http://pt.wikipedia.org/wiki/Adapter)
8 | * [Bridge](Bridge) [:notebook:](http://pt.wikipedia.org/wiki/Bridge_%28padr%C3%A3o_de_projeto_de_software%29)
9 | * [Composite](Composite) [:notebook:](http://pt.wikipedia.org/wiki/Composite)
10 | * [DataMapper](DataMapper) [:notebook:](http://en.wikipedia.org/wiki/Data_mapper_pattern)
11 | * [Decorator](Decorator) [:notebook:](http://pt.wikipedia.org/wiki/Decorator)
12 | * [DependencyInjection](DependencyInjection) [:notebook:](http://en.wikipedia.org/wiki/Dependency_injection)
13 | * [Facade](Facade) [:notebook:](http://pt.wikipedia.org/wiki/Fa%C3%A7ade)
14 | * [FluentInterface](FluentInterface) [:notebook:](http://en.wikipedia.org/wiki/Fluent_interface)
15 | * [Proxy](Proxy) [:notebook:](http://pt.wikipedia.org/wiki/Proxy_%28padr%C3%B5es_de_projeto%29)
16 | * [Registry](Registry) [:notebook:](http://en.wikipedia.org/wiki/Service_locator_pattern)
17 |
--------------------------------------------------------------------------------
/Structural/Registry/README.md:
--------------------------------------------------------------------------------
1 | # Registry
2 |
3 | ## Propósito
4 |
5 | Implementar um armazenamento central para objetos frequentemente usados em toda
6 | a aplicação. É tipicamente implementado usando uma classe abstrata com apenas
7 | métodos estáticos -- ou o Padrão Singleton.
8 |
9 | ## Exemplos
10 |
11 | * Zend Framework: `Zend_Registry` armazena o objeto de log da aplicação, front
12 | controller etc
13 | * Yii Framework: `CWebApplication` armazena todos os componentes da aplicação,
14 | como `CWebUser`, `CUrlManager` etc
15 |
16 | ## Diagrama UML
17 |
18 | 
19 |
--------------------------------------------------------------------------------
/Structural/Registry/Registry.php:
--------------------------------------------------------------------------------
1 | assertInstanceOf('StdClass', $logger);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Structural/Registry/uml/Registry.uml:
--------------------------------------------------------------------------------
1 |
2 |
3 | PHP
4 | \DesignPatterns\Structural\Registry\Registry
5 |
6 | \DesignPatterns\Structural\Registry\Registry
7 |
8 |
9 |
10 |
11 |
12 | \DesignPatterns\Structural\Registry\Registry
13 |
14 |
15 | Fields
16 | Constants
17 | Constructors
18 | Methods
19 |
20 | private
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Structural/Registry/uml/uml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webfatorial/PadroesDeProjetoPHP/29e0acbb384dba6415141d3ae0270a31fb527553/Structural/Registry/uml/uml.png
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "domnikl/design-patterns-php",
3 | "description": "Sample code for several design patterns in PHP",
4 | "authors": [
5 | {
6 | "name": "Dominik Liebler",
7 | "email": "liebler.dominik@googlemail.com"
8 | }
9 | ],
10 | "minimum-stability": "stable",
11 | "require-dev": {
12 | "phpunit/phpunit": "3.7.*",
13 | "squizlabs/php_codesniffer": "1.5.*"
14 | },
15 | "autoload": {
16 | "psr-4": {
17 | "DesignPatterns\\": ""
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/composer.phar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/webfatorial/PadroesDeProjetoPHP/29e0acbb384dba6415141d3ae0270a31fb527553/composer.phar
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Behavioral/*/Tests
7 | Creational/*/Tests
8 | More/*/Tests
9 | Structural/*/Tests
10 |
11 |
12 |
13 |
14 | ./vendor
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------