-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Facades #35
Draft
nibra
wants to merge
2
commits into
master
Choose a base branch
from
facades
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Facades #35
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
# Facades Meta Document | ||
|
||
## 1. Summary | ||
|
||
The facade pattern (also spelled façade) is a software-design pattern commonly used in object-oriented programming. | ||
Analogous to a facade in architecture, a facade is an object that serves as a front-facing interface masking more | ||
complex underlying or structural code. A facade can: | ||
|
||
* improve the readability and usability of a software library by masking interaction with more complex components behind | ||
a single (and often simplified) API | ||
* provide a context-specific interface to more generic functionality (complete with context-specific input validation) | ||
* serve as a launching point for a broader refactor of monolithic or tightly-coupled systems in favor of more | ||
loosely-coupled code | ||
|
||
Developers often use the facade design pattern when a system is very complex or difficult to understand because the | ||
system has many interdependent classes or because its source code is unavailable. This pattern hides the complexities of | ||
the larger system and provides a simpler interface to the client. It typically involves a single wrapper class that | ||
contains a set of members required by the client. These members access the system on behalf of the facade client and | ||
hide the implementation details. [[Wikipedia: Facade Pattern](https://en.wikipedia.org/wiki/Facade_pattern)] | ||
|
||
## 2. Why Bother? | ||
|
||
In Joomla, we have lots of places with code like this: | ||
|
||
```php | ||
$this->app->getIdentity()->authorise(...) | ||
``` | ||
|
||
or | ||
|
||
```php | ||
Factory::getUser()->authorise(...); | ||
``` | ||
|
||
While `Factory::getUser()` is deprecated, `$this->app->getIdentity()` relies on knowledge about the internal structure. | ||
Being able to use | ||
|
||
```php | ||
User::authorise(...); | ||
``` | ||
|
||
instead, would lower the cognitive load a lot. Additionally, it would make it easier for us to make changes in the | ||
underlying code without breaking extensions that use the feature in question. | ||
`authorise()` is just a single example here; there are several other places, where the facade pattern would simplify our lives: | ||
|
||
* App(lication) | ||
* Auth(orisation) | ||
* Config | ||
* Session | ||
* Lang(uage) | ||
* Doc(ument) | ||
* Database | ||
* Mail(er) | ||
* Event | ||
* Log(ger) | ||
|
||
## 3. Scope | ||
|
||
### 3.1 Goals | ||
|
||
### 3.2 Non-Goals | ||
|
||
## 4. Approaches | ||
|
||
### 4.1 Composite Pattern | ||
|
||
### 4.2 Chosen Approach | ||
|
||
## 5. Design Decisions | ||
|
||
## 6. People | ||
|
||
### 6.1 Editor(s) | ||
|
||
* Niels Braczek, <[email protected]> | ||
|
||
### 6.2 Sponsors | ||
|
||
* N/A | ||
|
||
### 6.3 Contributors | ||
|
||
* N/A | ||
|
||
## 7. Votes | ||
|
||
* **Entrance Vote:** _(not yet taken)_ | ||
* **Acceptance Vote:** _(not yet taken)_ | ||
|
||
## 8. Relevant Links | ||
|
||
_**Note:** Order descending chronologically._ | ||
|
||
## 9. Errata | ||
|
||
... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
# Content Elements | ||
|
||
|
||
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", | ||
"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be | ||
interpreted as described in [RFC 2119][]. | ||
|
||
[RFC 2119]: http://tools.ietf.org/html/rfc2119 | ||
|
||
### References | ||
|
||
- [RFC 2119][]: Key words for use in RFCs to Indicate Requirement Levels | ||
|
||
## 1. Specification | ||
|
||
### 1.1 Facade | ||
|
||
### 1.2 Application | ||
|
||
```php | ||
<?php | ||
|
||
namespace Joomla\Facade; | ||
|
||
use \Joomla\CMS\Application\CMSApplicationInterface; | ||
use Joomla\CMS\Factory; | ||
|
||
class App extends Facade | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it a good idea to add a requirement for typehint? /**
* @method Documeny getDocument()
* @method Potato getPotato()
* ....
* /
class App extends Facade There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, absolutely makes sense. |
||
{ | ||
/** | ||
* @var \Joomla\CMS\Application\CMSApplicationInterface | ||
*/ | ||
static private $instance; | ||
|
||
use Mockable; | ||
|
||
/** | ||
* Get the root object behind the facade. | ||
* | ||
* @return \Joomla\CMS\Application\CMSApplicationInterface | ||
*/ | ||
public static function getFacadeRoot(): CMSApplicationInterface | ||
{ | ||
if (self::$isMock) { | ||
return self::$mock; | ||
} | ||
|
||
if (self::$instance === null) { | ||
self::$instance = Factory::getApplication(); | ||
} | ||
|
||
return self::$instance; | ||
} | ||
} | ||
``` | ||
|
||
### 1.3 Content Visitor | ||
|
||
## 2. Interfaces, Traits and Classes | ||
|
||
### 2.1 Joomla\Facade\Facade | ||
|
||
```php | ||
<?php | ||
|
||
namespace Joomla\Facade; | ||
|
||
use RuntimeException; | ||
|
||
abstract class Facade | ||
{ | ||
/** | ||
* Get the root object behind the facade. | ||
*/ | ||
abstract public static function getFacadeRoot(); | ||
|
||
/** | ||
* Handle dynamic, static calls to the object. | ||
* | ||
* @param string $method | ||
* @param array $args | ||
* | ||
* @return mixed | ||
* | ||
* @throws RuntimeException | ||
*/ | ||
public static function __callStatic(string $method, array $args) | ||
{ | ||
$instance = static::getFacadeRoot(); | ||
if (!$instance) { | ||
throw new RuntimeException('A facade root has not been set.'); | ||
} | ||
|
||
return $instance->$method(...$args); | ||
} | ||
} | ||
``` | ||
|
||
### 2.2 Joomla\Facade\Mockable | ||
|
||
```php | ||
<?php | ||
|
||
namespace Joomla\Facade; | ||
|
||
trait Mockable | ||
{ | ||
protected static $isMock = false; | ||
|
||
protected static $mock; | ||
|
||
/** | ||
* @param $mock | ||
*/ | ||
public static function setMock($mock): void | ||
{ | ||
self::$mock = $mock; | ||
self::$isMock = true; | ||
} | ||
} | ||
``` |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe also
Layout
? CurrentlyLayoutHelper::render('blabla.layout')
And
Toolbar
:)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The list was not ment to be exhaustive.