Ich hatte die ganze letzte Woche diese Frage im Kopf: Wann sollte ich einen Dienst oder eine Dienstprogrammfunktion erstellen?
Im Drupal Core haben wir sowohl Dienste- als auch Dienstprogrammfunktionen, aber ich kann keinen Unterschied zwischen ihnen finden (wenn ich einen Dienst erstellen muss oder wenn ich eine Dienstprogrammfunktion erstellen muss).
Ich werde als Beispiel das Modul Modules Weight nehmen, in dem ich die InternalFunctions- Klasse habe.
<?php
namespace Drupal\modules_weight\Utility;
class InternalFunctions {
public static function prepareDelta($weight) {
$delta = 100;
$weight = (int) $weight;
if ($weight > $delta) {
return $weight;
}
if ($weight < -100) {
return $weight * -1;
}
return $delta;
}
public static function modulesList($force = FALSE) {
$modules = [];
$installed_modules = system_get_info('module');
$config_factory = \Drupal::service('config.factory');
if ($force) {
$show_system_modules = TRUE;
}
else {
modules.
$show_system_modules = $config_factory->get('modules_weight.settings')->get('show_system_modules');
}
$modules_weight = $config_factory->get('core.extension')->get('module');
foreach ($installed_modules as $filename => $module_info) {
if (!isset($module_info['hidden']) && ($show_system_modules || $module_info['package'] != 'Core')) {
$modules[$filename]['name'] = $module_info['name'];
$modules[$filename]['description'] = $module_info['description'];
$modules[$filename]['weight'] = $modules_weight[$filename];
$modules[$filename]['package'] = $module_info['package'];
}
}
uasort($modules, ['Drupal\Component\Utility\SortArray', 'sortByWeightElement']);
return $modules;
}
}
In dieser Klasse habe ich zwei statische Funktionen, aber beide sind Dienstprogrammfunktionen oder prepareDelta()
ist eine Dienstprogrammfunktion und modulesList()
sollte in einer anderen Klasse sein und einen Dienst haben?
Der einzige Unterschied, den ich zu diesem Zeitpunkt festgestellt habe, besteht darin, dass im Namespace Drupal \ Component \ Utility (wo Sie viele Dienstprogrammfunktionen sehen) keiner von ihnen innerhalb eines Dienstes verwendet wird und normalerweise ein Dienst einen anderen Dienst darin verwendet (ich nicht habe alle Dienste überprüft, um dies zu validieren).
Wann sollte ich also einen Dienst oder eine Dienstprogrammfunktion erstellen?
quelle
Unicode
Klasse im Kern - das ist eine statische Dienstprogrammklasse, kein Dienst, da sie keine Abhängigkeiten aufweist und keinen Status beibehalten muss. Wenn eine Dienstabhängigkeit erforderlich wäre, müsste diese nach dem DI-Muster in einen Dienst konvertiert werden, und Sie würden die Singleton-Instanz (oder die werkseitig generierte Instanz) aus dem Container verwenden, wenn Sie sie benötigen. Ansonsten können Sie es nuruse
der statischen Klasse geben, wenn es Sinn macht.Unicode
wäre , wäre dies ein Service von Natur aus, und das muss nicht wirklich sein. Vergessen Sie nicht, dass Utility-Klassen genauso einfach und in gewisser Hinsicht einfacher von anderen Modulen und anderem Code in Ihrem eigenen Modul verwendet werden können. Aber das hängt alles von Ihrer eigenen Perspektive / Erfahrung als Entwickler ab. Meistens kommt es auf den gesunden Menschenverstand an, der auf die harteUnicode
ist eine Drupal-Klasse, die nur statische Methoden enthält! Die Tatsache, dass die Kernentwickler es als statische Klasse und nicht als Service implementiert haben, bedeutet wahrscheinlich etwas, was Sie nicht denken? Eine Utility-Klasse muss von Natur aus nicht wirklich überschrieben werden. Sie erledigt einige Dinge. Wenn diese Dinge nicht Ihren Wünschen entsprechen, schreiben Sie stattdessen Ihre eigene Klasse. Denken Sie daran, dass die Art von Dingen, die traditionell in Utility-Klassen leben, einmalige Methoden sind: "Ich mache das und nichts anderes", die nur eine Reihe von ParameternAntworten:
Im Allgemeinen Dienste verwenden. Lesen Sie den folgenden Blog-Beitrag, wenn die Verwendung statischer Dienstprogrammfunktionen in Ordnung ist:
Quelle: https://stovepipe.systems/post/avoiding-static-in-your-code
(Die Menge an statischem Code, die jetzt in Drupal vorhanden ist, ist auf den Übergang vom prozeduralen D7-Code zurückzuführen. Verwenden Sie Drupal daher im aktuellen Status nicht als Beispiel.)
Über das Beispiel aus der Frage, den Rest der Utility-Klasse (in der Frage nicht gezeigt)
Ruft den moduleigenen Dienst in einem statischen Wrapper auf:
Dies liegt wahrscheinlich daran, dass die Utility-Klasse im alten prozeduralen Code verwendet wird. Im OOP-Code ist dies nicht erforderlich, hier sollten Sie den Dienst direkt einspeisen.
quelle
$force = NULL
, damit Sie wissen, ob jemand den Konfigurationswert mit FALSE überschreiben möchte.Ja, eine coole Sache an Diensten ist, dass jeder sie überschreiben kann. Wenn Sie also anderen Personen die Möglichkeit geben möchten, einen bestimmten Code anzupassen. Siehe Ändern vorhandener Dienste, Bereitstellen dynamischer Dienste .
Darüber hinaus sollten Sie es zu einem Dienst machen, wenn Sie einen Mock-Test für PHP-Unit-Tests durchführen müssen. Siehe Dienste und Abhängigkeitsinjektion in Drupal 8 , siehe Unit-Test komplizierterer Drupal-Klassen .
Fragen und Antworten:
Test der Serviceeinheit
Schreiben von Komponententests für eine Methode, die statische Methoden aus einer anderen Klasse aufruft
quelle