{"id":21017860,"url":"https://github.com/matiux/php-design-patterns","last_synced_at":"2026-01-30T17:32:05.162Z","repository":{"id":49615362,"uuid":"129306868","full_name":"matiux/php-design-patterns","owner":"matiux","description":"PHP Design Patterns - Basato sul libro Head First Design Patterns Book - Based on Head First Design Patterns Book","archived":false,"fork":false,"pushed_at":"2024-11-06T20:56:34.000Z","size":9744,"stargazers_count":2,"open_issues_count":1,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-06-05T11:48:53.926Z","etag":null,"topics":["adapter-pattern","command-pattern","composite-pattern","decorator-pattern","design-pattern","design-patterns","facade-pattern","factory-pattern","hexagonal-architecture","iterator-pattern","observer-pattern","singleton-pattern","specification-pattern","state-pattern","strategy-pattern","template-pattern","visitor-pattern"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/matiux.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-04-12T20:20:07.000Z","updated_at":"2023-11-08T18:17:40.000Z","dependencies_parsed_at":"2025-04-12T10:16:06.716Z","dependency_job_id":null,"html_url":"https://github.com/matiux/php-design-patterns","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/matiux/php-design-patterns","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matiux%2Fphp-design-patterns","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matiux%2Fphp-design-patterns/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matiux%2Fphp-design-patterns/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matiux%2Fphp-design-patterns/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/matiux","download_url":"https://codeload.github.com/matiux/php-design-patterns/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matiux%2Fphp-design-patterns/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28916097,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-30T16:37:38.804Z","status":"ssl_error","status_checked_at":"2026-01-30T16:37:37.878Z","response_time":66,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["adapter-pattern","command-pattern","composite-pattern","decorator-pattern","design-pattern","design-patterns","facade-pattern","factory-pattern","hexagonal-architecture","iterator-pattern","observer-pattern","singleton-pattern","specification-pattern","state-pattern","strategy-pattern","template-pattern","visitor-pattern"],"created_at":"2024-11-19T10:22:16.998Z","updated_at":"2026-01-30T17:32:05.142Z","avatar_url":"https://github.com/matiux.png","language":"PHP","readme":"PHP Design Patterns\n========\n\n![check dependencies](https://github.com/matiux/php-design-patterns/actions/workflows/check-dependencies.yml/badge.svg)\n![check deps vulnerability](https://github.com/matiux/ddd-starter-pack/actions/workflows/dependencies-vulnerability.yml/badge.svg)\n![test](https://github.com/matiux/php-design-patterns/actions/workflows/tests.yml/badge.svg)\n[![type coverage](https://shepherd.dev/github/matiux/php-design-patterns/coverage.svg)](https://shepherd.dev/github/matiux/php-design-patterns)\n[![psalm level](https://shepherd.dev/github/matiux/php-design-patterns/level.svg)](https://shepherd.dev/github/matiux/php-design-patterns)\n![security analysis status](https://github.com/matiux/php-design-patterns/actions/workflows/security-analysis.yml/badge.svg)\n![coding standards status](https://github.com/matiux/php-design-patterns/actions/workflows/coding-standards.yml/badge.svg)\n\nPHP design patterns based on the book \"Head First Design Patterns\" and more\n\n## Getting Started\n### Run Docker container\n```\ngit clone git@github.com:matiux/php-design-patterns.git \u0026\u0026 cd php-design-patterns\n./dc up -d\n./dc enter # To enter in PHP container and execute examples\ncomposer install\n```\n\n## Pattern list\n\n### Strategy pattern\nStrategy pattern defines a family of algorithms, encapsulates each and makes them interchangeable. The strategy\nallows the algorithm to vary independently of the clients that use it.\n```\nphp src/Strategy/mini-duck-simulator.php\n```\n### Observer pattern\nObserver pattern defines a one-to-many dependency between objects so that when an object changes state,\nall its employees are notified and updated automatically.\n```\nphp src/Observer/weather-station.php\n```\n### Decorator pattern\nDecorator pattern associates additional responsibilities with an object in a dynamic way. Decorators offer an alternative\nflexible to the subclass to extend the functionality of an object.\n```\nphp src/Decorator/starbuzz-coffee.php\n```\n### Simple Factory pattern\nIt's not a proper design pattern, but it's an easy way to decouple the client from concrete classes.\n\nRead only:\n\n```\ncat src/Factory/SimpleFactory/SimplePizzaFactory.php\ncat src/Factory/SimpleFactory/PizzaStore.php\n```\n### Factory Method pattern\nThe Factory Method is based on inheritance: the creation of the object is delegated to subclasses, which implement the\n\"factory\" method to create objects.\n```\nphp src/Factory/FactoryMethod/client.php\n```\n### Abstract Factory pattern\nAbstract Factory is based on the composition of the objects: the creation of the object is implemented in exposed methods\nin the factory interface.\n```\nphp src/Factory/AbstractFactory/client.php\n```\n### Singleton pattern\nSingleton Pattern ensures that a class has only one instance and provides a global access point to it.\n```\nphp src/Singleton/client.php\n```\n### Command pattern\nCommand pattern encapsulates a request (a command) by binding together a set of actions to be performed\non a recipient (a receiver).\n```\nphp src/Command/Simple/client.php\nphp src/Command/Advance/client.php\nphp src/Command/Undo/client.php\nphp src/Command/Macro/client.php\n```\n### Adapter pattern\nAdapter pattern converts the interface of one class into another that the client expects. The Adapter allows the\nclasses to work together when they could not due to incompatible interfaces.\n```\nphp src/Adapter/Anatre/client-duck.php\nphp src/Adapter/Anatre/client-turkey.php \n```\n### Facade pattern\nFacade pattern provides a unified interface to a set of interfaces in a subsystem. Defines a higher level interface\nwhich simplifies the use of the subsystem. The difference between Facade and Adapter is in their intent.\nThe intent of the Adapter pattern is to modify an interface to match what a client expects.\nThe intent of the Facade pattern is to provide a simplified interface to a subsystem.\n```\nphp src/Facade/client.php\n```\n### Template method pattern\nTemplate Method pattern defines the skeleton of an algorithm in a method, delegating some steps to the subclasses.\nTemplate Method pattern allows subclasses to redefine certain steps of an algorithm without modifying any  structure.\n```\nphp src/TemplateMethod/NoHook/client.php\nphp src/TemplateMethod/Hook/client.php\n```\n### Iterator pattern\nIl pattern Iterator fornisce un modo per accedere sequenzialmente agli elementi di un oggetto aggregato senza esporre la\nsua rappresentazione sottostante. Ma l'effetto dell'utilizzo degli iteratori nel tuo progetto è altrettanto importante:\nuna volta che hai un modo uniforme di accedere agli elementi di tutti i tuoi oggetti aggregati, puoi scrivere codice\npolimorfico che funzioni con uno qualsiasi di questi aggregati, potendo usare indiscriminatamente array, ArrayObject,\ncollezioni di dominio ecc, a condizione che riesca a impossessarsi di un Iterator. Un altra cosa importante è che il\npattern Iterator assume la responsabilità di attraversare gli elementi e attribuisce tale responsabilità all'oggetto\niteratore, non all'oggetto aggregato. Ciò non solo mantiene più semplice l'interfaccia aggregata e l'implementazione,\nma rimuove la responsabilità dell'iterazione dall'aggregazione e mantiene l'aggregato focalizzato sulle cose su cui\ndovrebbe essere focalizzato (gestendo una collezione di oggetti), non sull'iterazione.\n```\nphp src/Iterator/DinerMerger/client.php\n\n#Con interfaccia Iterator di PHP\nphp src/Iterator/DinerMergerI/client.php\n```\n### Composite pattern\nComposite pattern allows you to compose objects in tree structures to represent entire hierarchies. Composite pattern\nallows clients to treat single objects and object compositions uniformly. Using a structure\ncomposite, we can apply the same operations to both composite data and individual objects. In other words, in the\nmost of the cases we can ignore the differences between the compositions of objects and individual objects. With this\npattern it seems that the principle of single responsibility is violated as a class that implements it is found\nto do two things, manage a hierarchy and manage operations on the end nodes (the leaves of the tree). We can however\nto say that the Composite pattern takes the design of the SRP and mistakes it for _transparency_; allowing the interface\nComponent to contain child management operations and leaf operations, a client can treat both uniformly\nthe composite data that the leaf nodes; therefore, if an element is a composite or leaf node it becomes transparent to the client.\nBy allowing the Component interface to contain child management operations and leaf operations, a client can\ntreat both composites and leaf nodes uniformly; so if an element is a composite or leaf node it becomes\ntransparent to the client. This is a classic case of compromise. Sometimes we intentionally do things one way\nwhich seems to violate the principle. In some cases, however, this is a matter of perspective; for example, it might\nseem wrong to have child management operations in leaf nodes (like _add()_, _remove()_ and _getChild()_), but then\nyou can always change perspective and see a leaf as a node with zero children.\n\n```\nphp src/Composite/Menu/client.php\n```\n\n### State pattern\nState pattern allows an object to alter its behavior when its internal state changes. The object will appear to change its class.\nSince the pattern encapsulates the state in separate classes and delegates to the object representing the current state, we know\nthat behavior changes along with the internal state. With the State pattern, we have a set of behaviors encapsulated in state objects;\nat any time the context is delegating to one of these states. Over time, the current state changes across the set of\nstate objects to reflect it internal state of the context, so the behavior of the context also changes over time.\nAt the level of the diagram this pattern is identical to the Pattern Strategy. In general, think of the Strategy as a\nflexible alternative to the subclass; if you use inheritance to define behavior of a class, then you are stuck with that\nbehavior even if you need to change it. With the Strategy you can change the behavior by composing with a different object.\nThe State pattern, on the other hand, should be thought of as an alternative to putting many conditionals in your context;\nencapsulating behaviors within state objects, you can simply change the state object in context to change its behavior.\n```\nphp src/State/GumballState/client.php\nphp src/State/GumballStateWinner/client.php\n```\n\n### Visitor pattern\nThe visitor is a behavioral pattern that allows you to separate algorithms from the objects on which they operate.\nThis pattern represents an operation that you want to perform on a collection of elements of a structure. The operation\ncan be modified without changing the classes of the elements on which it operates. Think of a structure that contains a\nheterogeneous set of objects, on which the same operation must be applied, which however is implemented in a different\nway for each class of object.\n\n```\nphp src/Visitor/client.php\n```\n\n### Specification\nBuilds a clear specification of business rules, where objects can be checked against. The composite specification class\nhas one method called isSatisfiedBy that returns either true or false depending on whether the given object satisfies\nthe specification. [reference](https://designpatternsphp.readthedocs.io/en/latest/Behavioral/Specification/README.html)\n```\nphp src/Specification/client.php\n```\n\n## Extra\n\n### Hexagonal Architecture (Ports and Adapters)\nIn this section, based on the book *Domain-Driven Design in PHP - Carlos Buenosvinos, Christian Soronellas and Keyvan Akbary*,\nI show a refactoring process from spaghetti code to code reorganization through the hexagonal architecture\n\nThe hexagonal architecture allows an application to be equally driven by users, programs, automated tests or batch\nscripts and to be developed and tested separately from its own devices and databases, if any.\n\nPrepare the database for running the examples:\n```\nphp src/HexagonalArchitecture/build.php\n```\n\nThe first 3 steps of refactoring:\n```\nphp src/HexagonalArchitecture/Step01/client.php\nphp src/HexagonalArchitecture/Step02/client.php\nphp src/HexagonalArchitecture/Step03/client.php\n```\nFinal step with implementation with various deliveries and tests:\n```\nphp src/HexagonalArchitecture/Step04/client.php\nphp src/HexagonalArchitecture/Step04/console app:create-idea 'Flying pig' Matiux\n```\n\n```\nproject phpunit # To execute tests\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmatiux%2Fphp-design-patterns","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmatiux%2Fphp-design-patterns","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmatiux%2Fphp-design-patterns/lists"}