制御の反転 (IOC)
まず、例を見てみましょう。
class Person { private $name = ''; private $age = 0; public function __construct(string $name, int $age) { $this->name = $name; $this->age = $age; } public function eat () { echo '吃东西' . PHP_EOL; } public function drink () { echo '喝水' . PHP_EOL; } public function sleep () { echo '睡觉' . PHP_EOL; } public function wakeup () { echo '起床' . PHP_EOL; } public function drive () { echo '开车' . PHP_EOL; } public function wash () { echo '洗漱' . PHP_EOL; } }
Xiao Ming は朝起きたら仕事に行く必要があるため、次のことを行う必要があります。
$person = new Person('小明', 24); $person->wakeup(); $person->wash(); $person->eat(); echo '带上车钥匙、手机、电脑' .PHP_EOL; $person->drive();
上記のプロセスはプログラマー自身によって制御されます。次に、フレームワークにプロセスを制御させる方法を見つけてみましょう。パーソン クラスに新しいメソッドを追加します。コードは次のとおりです:
public function work (callable $bring) { $this->wakeup(); $this->wash(); $this->eat(); $bring(); $this->drive(); }
Xiao Huang も仕事に行く必要があります。あとは、仕事に行くアクションを完了するためにフレームワークのガイダンスをインストールするだけです。
$person = new Person('小黄', 29); $person->work(function () { echo '带上手机、车钥匙、文件' . PHP_EOL; });
修正コードは制御の反転を完了しました。以前のコードでは、作業プロセス全体がプログラマによって制御されていましたが、修正コードでは、フレームワークが作業プロセスを制御します。プログラムのフロー制御は、プログラマからフレームワークへ「逆」に行われます。
これで制御の反転の定義を与えることができます:
実際、制御の反転は特定の実装方法ではなく、比較的一般的な設計アイデアであり、一般にガイダンスとして使用されます。レベルの設計。ここで言う「制御」とはプログラムの実行フローを制御することを指しますが、「反転」とはフレームワークを使用する前にプログラマーがプログラム全体の実行を制御することを指します。フレームワークを使用すると、プログラム全体の実行フローがフレームワークを通じて制御されます。プロセスの制御はプログラマからフレームワークに「逆転」されます。
依存性注入
制御の反転は設計上のアイデアですが、依存性注入は特定のコーディング手法であり、依存性注入は実装です。制御の反転のための最も一般的な手法。依存性注入は「ハイエンド」に見えますが、実際には理解して習得するのが非常に簡単です。
それでは、依存性注入とは正確には何でしょうか?これを 1 つの文に要約できます。 new() を使用してクラス内に依存クラス オブジェクトを作成するのではなく、依存クラス オブジェクトが外部で作成された後、コンストラクター、関数パラメーターなどを介して渡されます (または注入されます)。 。
例を見てみましょう:
interface Log { function write (string $msg); } class TextLog implements Log { public function __construct($dirname, $txtname) { $this->makeDir($dirname); $this->mkTxt($txtname); } private function makeDir (string $dirName) :void { // do something } private function mkTxt (string $txtName) :void { // do something } public function write (string $msg) { // do something } } class RedisLog implements Log { private $redis = null; private $key = ''; public function __construct(string $key) { $this->redis = '...'; // 获取redis实例 $this->key = $key; // ... } public function write (string $msg) { // do something } } class App { public function run () { // do something // 记录日志 (new RedisLog('log'))->write('框架运行信息记录'); } }
ご覧のとおり、App クラスは RedisLog クラスに依存しています。将来の日を記録するために Redis を使用しなくなり、代わりにテキストを使用するとします。ファイルがある場合は、実行時にコードを変更する必要があります。
ここで、依存関係注入手法を使用した書き換えに切り替えます。コードは次のとおりです。
class App { private $logHandle = null; public function __construct(Log $log) { $this->logHandle = $log; } public function run () { // do something // 记录日志 $this->logHandle->write('框架运行信息记录'); } }
書き換えられた App クラスは RedisLog クラスに依存しなくなり、他のクラスに置き換えることができます。クラスが write メソッドを実装している限り、いつでもクラスをログに記録します。ご覧のとおり、依存関係注入は依存クラスを柔軟に置き換えることができ、また、テスト可能なコードを作成する最も効果的な方法です。
Zhihu に依存性注入に関する記事があり、とても分かりやすいのでぜひ読んでみてください。リンクは次のとおりです:
制御の反転と依存関係の注入に関する簡単な説明 https://zhuanlan.zhihu.com/p/33492169
以上が制御原理の逆転、依存性注入との関係は何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。