私は先週ずっとこの質問を念頭に置いていました:サービスまたはユーティリティ関数をいつ作成するべきですか?
Drupalコアにはサービスとユーティリティ関数の両方がありますが、それらを区別できません(サービスを作成する必要があるとき、またはユーティリティ関数を作成する必要があるとき))。
Modules Weight モジュールの例として、 InternalFunctions クラスを使用します。
_<?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;
}
}
_
このクラスには2つの静的関数がありますが、どちらもユーティリティ関数であるか、prepareDelta()
はユーティリティ関数であり、modulesList()
は別のクラスにあり、サービスを持っている必要がありますか?
現時点で私が見つけた唯一の違いは、名前空間Drupal\Component\Utility(多くのユーティリティ機能が表示されます)内ではサービス内で使用せず、通常、サービスは内部で別のサービスを使用することです(私はしません)これを検証するためにすべてのサービスを確認してください)。
それで、サービスまたはユーティリティ関数をいつ作成する必要がありますか?
一般的な使用サービス。静的ユーティリティ関数を使用してもよい場合は、次のブログ投稿を参照してください。
だから静的を使用しないでください?
いいえ、有効なユースケースがあります。 1つは、事前定義された項目のリストがある場合、静的ではインスタンスレベルではなくクラスレベルになるため、メモリの削減に役立つことです。
その他のケースは、外部の依存関係を必要としないユーティリティメソッドです(slugifyメソッドなど)。
<?php class Util { public static function slug($string) { return strtolower(trim(preg_replace('/[^A-Za-z0-9-]+/', '_', $string))); } }
Slugメソッドは、非常に明確に定義された動作のみを実行します。単体テストで動作を考慮に入れるのは簡単で、この呼び出しを見てもそれほど心配する必要はありません。
これらのメソッドは初期化を必要としないため、ユニットテストを行うこともできます。
ソース: https://stovepipe.systems/post/avoiding-static-in-your-code
(Drupalに含まれる静的コードの量は、手続き型D7コードからの移行によるものであるため、例として現在の状態でDrupalを使用しないでください。 )
質問の例について、ユーティリティクラスの残りの部分(質問には表示されていません)
<?php
namespace Drupal\modules_weight\Utility;
/**
* Provides module internal helper methods.
*
* @ingroup utility
*/
class InternalFunctions {
...
/**
* Return the modules list ordered by the modules weight.
*
* @param bool $force
* Force to show the core modules.
*
* @return array
* The modules list.
*/
public static function modulesList($force = FALSE) {
// If we don't force we need to check the configuration variable.
if (!$force) {
// Getting the config to know if we should show or not the core modules.
$force = \Drupal::service('config.factory')->get('modules_weight.settings')->get('show_system_modules');
}
// Getting the modules list.
$modules = \Drupal::service('modules_weight')->getModulesList($force);
return $modules;
}
}
静的ラッパーでモジュール独自のサービスを呼び出します。
\Drupal::service('modules_weight')
これはおそらく、ユーティリティクラスが従来の手続き型コードで使用されているためです。 OOPコードではこれは必要ありません。ここではサービスを直接注入する必要があります。
SlackのKen Rickard Drupal #contributeチャネルは、次のように述べています。「他のモジュール(または他の開発者)がそのコードとやり取りすることを期待する場合、サービスを作成します。ユーティリティメソッドは、自分専用のショートカットです。 」
はい、サービスの優れた点は、誰でも上書きできることです。したがって、特定のコードをカスタマイズする機能を他の人に提供したい場合。 既存のサービスの変更、動的サービスの提供 を参照してください。
また、PHPユニットテストのモックテストを実行する必要がある場合は、サービスにする必要があります。 Drupal 8 、参照 より複雑なユニットテストDrupalクラス 。
Q&A: