Skip to content

Instantly share code, notes, and snippets.

@gbirke
Last active April 29, 2020 08:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gbirke/b84c5b1d8ed92b7f77445d53b66adde9 to your computer and use it in GitHub Desktop.
Save gbirke/b84c5b1d8ed92b7f77445d53b66adde9 to your computer and use it in GitHub Desktop.
Dependency inversion of PHP factories with callables
<?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