Created
March 12, 2019 11:33
-
-
Save TorbenKoehn/d3788335326f5ba84607efa6dcfe5821 to your computer and use it in GitHub Desktop.
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
//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