Last active
April 29, 2020 08:50
-
-
Save gbirke/b84c5b1d8ed92b7f77445d53b66adde9 to your computer and use it in GitHub Desktop.
Dependency inversion of PHP factories with callables
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
<?php | |
// This example shows: | |
// 1) How to invert the dependency of initialization of factories in dependent | |
// modules by giving a callable. This will defer the initialization of the | |
// dependency. | |
// 2) How to use a closure inside of a class as a callable. Notice how accessing | |
// "$this->presenter" gives the current presenter, not the one that was stored | |
// when the closure was created. | |
// Submodule | |
interface Presenter { | |
public function present(); | |
} | |
class View { | |
private $presenter; | |
public function __construct( Presenter $presenter ) { | |
$this->presenter = $presenter; | |
} | |
public function show() { | |
printf("%s\n", $this->presenter->present()); | |
} | |
} | |
class ViewFactory{ | |
private $createPresenter; | |
public function __construct( callable $createPresenter ) { | |
$this->createPresenter = $createPresenter; | |
} | |
public function getView() { | |
return new View( call_user_func( $this->createPresenter ) ); | |
} | |
} | |
// Main Module | |
class PresenterA implements Presenter { | |
public function present() { | |
return "Presenter A"; | |
} | |
} | |
class PresenterB implements Presenter { | |
public function present() { | |
return "Presenter B"; | |
} | |
} | |
class MainFactory { | |
private $subFactory; | |
private $presenter; | |
public function __construct() { | |
$this->presenter = new PresenterA(); | |
$this->viewFactory = new ViewFactory( function() { | |
return $this->presenter; | |
} ); | |
} | |
public function setPresenter( Presenter $presenter ) { | |
$this->presenter = $presenter; | |
} | |
public function getView() { | |
return $this->viewFactory->getView(); | |
} | |
} | |
$factory = new MainFactory(); | |
$factory->setPresenter(new PresenterB()); | |
// Expected output: 'Presenter B' | |
$factory->getView()->show(); | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment