Skip to content

Instantly share code, notes, and snippets.

@TorbenKoehn
Created March 12, 2019 11:33
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 TorbenKoehn/d3788335326f5ba84607efa6dcfe5821 to your computer and use it in GitHub Desktop.
Save TorbenKoehn/d3788335326f5ba84607efa6dcfe5821 to your computer and use it in GitHub Desktop.
//Inheritance:
class ApiClient extends HttpClient
{
public function getUsers(): array
{
$this->options['my_option'] = stream_context_create(); //Man kann Unfug mit der Parent-Klasse treiben
return $this->get('/users')->parseJson();
}
}
//Probleme:
// - ApiClient kann alles, was auch HttpClient kann und ist public API.
// -> Heißt, bringt der API Client eine neue Methode rein, wird deine eigene public API (ohne dein Wissen) verändert
// - Innerhalb lässt sich mit protected eine Menge Unfug treiben
// - PHP enforciert nicht das aufrufen des Super-Konstruktors (auch wenn PHPStorm es einem mitteilt)
// - ES IST NICHT TESTBAR. Der interne HTTP Client lässt sich nicht mocken, man kann maximal einen Mock aus der gesamten
// Klasse erstellen und umgeht dann den Zweck von Unit-Tests (da der Mock sich anders verhält als deine tatsächliche Klasse)
// - Klasse ist nicht final, d.h. ich kann sie noch einmal ableiten und darin noch mehr unfug treiben und noch mehr
// public APIs durchschleifen
//vs. Decorator
final class ApiClient
{
private HttpClient $httpClient;
public function __construct(HttpClient $httpClient)
{
$this->httpClient = $httpClient;
}
public function getUsers(): array
{
return $this->httpClient->get('/users')->parseJson();
}
}
//Gelöste Probleme:
// - Die Public API von ApiClient besteht aus dem Konstruktor und genau den Methoden, die man
// auch tatsächlich zur Verfügung stellen will
// - Man kann keinen Unfug mit dem HTTP Client treiben (Und genau deshalb sollte der HTTP Client im besten Falle auch final sein und obiges
Pattern gar nicht erst zulassen)
// - Injection stellt sicher, dass die Klasse (außerhalb) instanziert wurde und korrekt funktionieren _muss_
// - Es ist testbar. Wir können einen Mock von HttpClient erstellen und die ->get() Methode überschreiben, um sämtliche
// responses zu mocken
// - Klasse ist final, umgeht also die Probleme, die entstehen würden, wenn jemand mit DIESER Klasse obiges Pattern benutzt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment