Hallo zusammen,
ich beschäftige mich zurzeit ein wenig mit Silex und in diesem Zusammenhang mit dem Konzept der Services bzw. ServiceProviders.
Wenn ich das richtig sehe ist Silex an sich im Grunde genommen ein erweitertes Pimple-Container mit vorkonfigurierten Services wie request, routes, controllers etc. Eben mit allem was für ein Framework so benötigt wird (natürlich plus die entsprechende Framework-Logik, die sich intern dieser Services bedient). Die Applikation selbst ist somit gleichzeitig auch ein einfacher ServiceLocator.
Dabei sind die sogenannten ServiceProvider sozusagen vorkonfigurierte Services, die sich leicht zu jeder Silex-Applikation hinzufügen lassen.
Soweit so gut. Nun sehe ich mir den Beispielcode an für einen einfachen ServiceProvider:
http://silex.sensiolabs.org/doc/providers.html
und stelle fest, daß alle Parameter des „Hello“ Service einfach im $app-container gespeichert werden. Daraufhin habe ich mir mal die Implementierung einiger Silex ServiceProvider angeschaut
https://github.com/silexphp/Silex/tr...Silex/Provider
und sehe da - überall das Gleiche! Alles an Parametern wird einfach in den globalen Namensraum des Applikations-Containers rein geklatscht.
Nehmen wir z.B. den SessionServiceProvider:
https://github.com/silexphp/Silex/bl...ceProvider.php
alle internen Parameter des Services werden einfach im Namensraum der $app gespeichert.
Damit mutiert die Application mit jedem weiteren Service zu einem globalen Storage für alle Services und alle die internen Serviceparameter. Kapselung der Daten – Fehlanzeige, Schutz der Daten – Fehlanzeige!
Es ist von überall und jederzeit problemlos möglich nicht nur die Services zu ändern oder komplett zu überschreiben, sondern auch jeden internen ServiceParameter zu manipulieren. Alles liegt global und komplett ungeschützt auf dem Präsentierteller!
Und nicht nur das, wenn man z.B. einen neuen ServiceProvider definiert und diesem zufällig einen Namen vergibt, der bereits von einem anderen Service verwendet wird, dann wird der Eine Service durch den Anderen einfach kommentarlos überschrieben, je nachdem was zuletzt registriert wird. Damit werden Fremde Serviceprovider-Bibliotheken, ohne in den Quelltext zu schauen, quasi zum russischen Roulette.
Einfache Vertippter innerhalb der ServiceProviders können ebenfalls leicht zu schwer lokalisierbaren Fehlern führen:
Darüber hinaus gibt es natürlich auch keine konkrete Schnittstellen für den Zugriff auf die einzelnen Services. D.h. keinerlei Unterstützung durch die IDE für sämtliche Services.
Nun drängt sich mir die Frage auf, ob Silex mit der akt. Implementierung des ServiceProvider-Konzepts nicht eine der elementarsten Regeln für gutes OOD, die Datenkapselung, derart stark verletzt , daß es sich damit selbst als (Micro)-Framework quasi komplett disqualifiziert?
vg
jack88
P.S.
Achtung: ich sehe gerade, daß die Backslashes in den Codebeispielen gefiltert werden:
(Zwischen Silex und Application ist ein Backslash! (use Silex\Application )
ich beschäftige mich zurzeit ein wenig mit Silex und in diesem Zusammenhang mit dem Konzept der Services bzw. ServiceProviders.
Wenn ich das richtig sehe ist Silex an sich im Grunde genommen ein erweitertes Pimple-Container mit vorkonfigurierten Services wie request, routes, controllers etc. Eben mit allem was für ein Framework so benötigt wird (natürlich plus die entsprechende Framework-Logik, die sich intern dieser Services bedient). Die Applikation selbst ist somit gleichzeitig auch ein einfacher ServiceLocator.
Dabei sind die sogenannten ServiceProvider sozusagen vorkonfigurierte Services, die sich leicht zu jeder Silex-Applikation hinzufügen lassen.
PHP-Code:
$app->register(new MyService());
http://silex.sensiolabs.org/doc/providers.html
PHP-Code:
use Silex\Application;
use Silex\ServiceProviderInterface;
class HelloServiceProvider implements ServiceProviderInterface
{
public function register(Application $app)
{
$app['hello'] = $app->protect(function ($name) use ($app) {
$default = $app['hello.default_name'] ? $app['hello.default_name'] : '';
$name = $name ?: $default;
return 'Hello '.$app->escape($name);
});
}
public function boot(Application $app)
{
}
}
https://github.com/silexphp/Silex/tr...Silex/Provider
und sehe da - überall das Gleiche! Alles an Parametern wird einfach in den globalen Namensraum des Applikations-Containers rein geklatscht.
Nehmen wir z.B. den SessionServiceProvider:
https://github.com/silexphp/Silex/bl...ceProvider.php
alle internen Parameter des Services werden einfach im Namensraum der $app gespeichert.
Damit mutiert die Application mit jedem weiteren Service zu einem globalen Storage für alle Services und alle die internen Serviceparameter. Kapselung der Daten – Fehlanzeige, Schutz der Daten – Fehlanzeige!
Es ist von überall und jederzeit problemlos möglich nicht nur die Services zu ändern oder komplett zu überschreiben, sondern auch jeden internen ServiceParameter zu manipulieren. Alles liegt global und komplett ungeschützt auf dem Präsentierteller!
Und nicht nur das, wenn man z.B. einen neuen ServiceProvider definiert und diesem zufällig einen Namen vergibt, der bereits von einem anderen Service verwendet wird, dann wird der Eine Service durch den Anderen einfach kommentarlos überschrieben, je nachdem was zuletzt registriert wird. Damit werden Fremde Serviceprovider-Bibliotheken, ohne in den Quelltext zu schauen, quasi zum russischen Roulette.
Einfache Vertippter innerhalb der ServiceProviders können ebenfalls leicht zu schwer lokalisierbaren Fehlern führen:
PHP-Code:
class HelloService implements ServiceProviderInterface {
public function register(Application $app)
{
$app['hello'] = function () use ($app) {
return 'Hello Jack';
};
}
public function boot(Application $app)
{
}
}
class HalloService implements ServiceProviderInterface {
public function register(Application $app)
{
$app['hello'] = function () use ($app) {
return 'Hallo Peter';
};
}
public function boot(Application $app)
{
}
}
$app->register(new HelloService());
$app->register(new HalloService());
$app->get('/hello', function () use ($app) {
return $app['hello'];
});
# Hallo Peter
Darüber hinaus gibt es natürlich auch keine konkrete Schnittstellen für den Zugriff auf die einzelnen Services. D.h. keinerlei Unterstützung durch die IDE für sämtliche Services.
Nun drängt sich mir die Frage auf, ob Silex mit der akt. Implementierung des ServiceProvider-Konzepts nicht eine der elementarsten Regeln für gutes OOD, die Datenkapselung, derart stark verletzt , daß es sich damit selbst als (Micro)-Framework quasi komplett disqualifiziert?
vg
jack88
P.S.
Achtung: ich sehe gerade, daß die Backslashes in den Codebeispielen gefiltert werden:
PHP-Code:
use Silex\Application;
Kommentar