目次
制御の反転とは
#の具体化です。 ## Golang Inversion of Control (IOC) がプロジェクトに適用されます
ディレクトリ
ホームページ バックエンド開発 Golang Go言語における制御の反転とは何ですか

Go言語における制御の反転とは何ですか

Jan 28, 2023 am 11:12 AM
golang 言語を移動

Go 言語では、制御の反転 (IoC) はオブジェクト指向プログラミングの設計原則であり、コンピューター コード間の結合を減らすために使用できます。つまり、コード制御がオブジェクト指向プログラミングから「逆転」されます。ビジネス コード。」をフレームワーク コードに追加します。制御の反転の一般的な方法は依存関係の注入と呼ばれ、別の方法は「依存関係のルックアップ」と呼ばれます。制御の反転により、オブジェクトの作成時に、システム内のすべてのオブジェクトを制御する外部エンティティが、依存するオブジェクトを参照します。渡してください。

Go言語における制御の反転とは何ですか

このチュートリアルの動作環境: Windows 7 システム、GO バージョン 1.18、Dell G3 コンピューター。

制御の反転とは

制御の反転 (Inversion of Control、略して IoC) は、結合を減らすために使用できるオブジェクト指向プログラミングの設計原則です。コンピューターコードの間。最も一般的な方法は依存関係注入 (DI) と呼ばれ、もう 1 つの方法は依存関係ルックアップと呼ばれます。制御の反転により、オブジェクトが作成されると、システム内のすべてのオブジェクトを制御する外部エンティティが、依存するオブジェクトの参照をそれに渡します。依存関係がオブジェクトに注入されるとも言えます。

もっと簡単に言うと、コントローラー UserController があれば、コーディング、読み取り、食べることができます。もちろん、暗黙的な __construct コンストラクターと __destruct デストラクターもあります。これらのデフォルト関数はわかっています。ライフサイクルの終わりにリソースが解放されるとき、初期化などの特定の状況で自動的にトリガーされますが、これらの関数自体が自動的にトリガーされないと仮定すると、作成者としてどうすればそれらを実行できるでしょうか。実は、私のコントローラーにも ArticleController と YouBadBadController があるんですが、どうやって扱えばいいのでしょうか?

各ユーザーは作業する前に自分自身をビルドする必要があります。記事も作業する前に自分自身をビルドする必要があります。この状況の欠点は明らかです。後で紹介するように、各コントローラーをビルドする必要があります。誰もが自分のことを行いますが、彼らはパブリックな動作を扱うときは、実際にそれらを外部で実装および管理できます。デフォルトのマジック関数は必要ありません。具体的なシナリオを紹介します。各コントローラーがハンドル関数を実装して呼び出す必要があるとします。どうすれば合理的に完了できますか? 各コントローラーに run 関数を追加した後、今でも run メソッドを実行する必要がある場合でも、そのスケジュールを記述する必要がありますか?

制御の反転は、制御の統合管理ですか?この操作は? パブリックの ControllerService に処理を任せることができますが、現在は継承を考慮していません。

class ControllerService{

public functiondo(){

->handle();

 } //去吧比卡丘; }

}
ログイン後にコピー

ちょっと待って、Xiaozhi はモンスターボールを投げずにどうやって行くことができますか? Xiaozhi はどこですか?コントロールがControllerServiceに反転されるように、コントローラを

class ControllerService{
public $handler;

public function __construct($handler){

    $this->handler=$handler ;

} //通过构造函数带入; }

//

public function setHandler($handler){

     $this->handler->handle();

 } //通过setter带入; }

public function do(){

     $this->handler->handle();

 } //去吧比卡丘; }

}

new ControllerService()->setHandler(new UserController())->do();
ログイン後にコピー

に渡す必要があります;

Go言語のインターフェース・リフレクション・メカニズムもIoc

#の具体化です。 ## Golang Inversion of Control (IOC) がプロジェクトに適用されます

設計

使用されるサードパーティ ライブラリ:

https: //github.com/berkaroad/ioc

使い方は比較的簡単で、RegisterTo と Invoke だけですが、意味のあるライブラリを使用するにはフレームワークと組み合わせる必要があります。

疎結合というと、GO では

interface(interface) を思い浮かべやすいため、インターフェイスを使用してさまざまなレイヤー間の疎結合を実現します。

従来の MVC フレームワークによると、通常、サーバー側にはコントローラー層、サービス層、モジュール層のいくつかの層があり、フレームワーク内で Ioc をどのように組み合わせるかが検討の価値があります。

ディレクトリ

Go言語における制御の反転とは何ですか

呼び出し構造: サービスがないため、メイン関数はコントローラーとして機能し、サービスはサービス層になります。 、モジュールはデータ層、リソースはストレージ層、アプリはさまざまなインターフェイスの定義です

main-->Service-->Module-->Resource
呼び出しをデモンストレーションするためにサービス間には、service1 と service2 を定義しました。 2 つのサービス

実装

各層のインターフェイス定義
package app

type Service1 interface {
	AddData(string)
	DelData(string)
}
type Service2 interface {
	AddData(string)
	DelData(string)
}
type Module interface {
	DataToSave(string)
	DataToRemove(string)
}
type Resource interface {
	Save(string)
	Remove(string)
}
ログイン後にコピー

IOC 初期化
package app

import (
	"github.com/berkaroad/ioc"
	"github.com/spf13/viper"
)

func GetOrCreateRootContainer() ioc.Container {
	v := viper.Get("runtime.container")
	if v == nil {
		v = ioc.NewContainer()
		viper.Set("runtime.container", v)
	}
	return v.(ioc.Container)
}
ログイン後にコピー

実際、どのように実装しても、それは単なる単一インスタンス NewContainer

ストレージ層 (ボトムアップ) )
package resource

import (
	"fmt"
	"github.com/berkaroad/ioc"
	"github.com/zhaoshoucheng/hodgepodge/IoC/app"
)

type ResourceObj struct {
	name string
}

func (r *ResourceObj) Save(str string) {
	fmt.Println(r.name, " Save ", str)
}
func (r *ResourceObj) Remove(str string) {
	fmt.Println(r.name, " Remove ", str)
}

func init() {
	mo := &ResourceObj{name: "mongo"}
	// static assert 静态断言类型检测
	func(t app.Resource) {}(mo)
	app.GetOrCreateRootContainer().RegisterTo(mo, (*app.Resource)(nil), ioc.Singleton)
        //rd := &ResourceObj{name: "redis"} 实现是用的map,所以mong会被覆盖
        //app.GetOrCreateRootContainer().RegisterTo(rd, (*app.Resource)(nil), ioc.Singleton)
}
ログイン後にコピー

RegisterTo は登録プロセスです。mo オブジェクトは、後で app.Resource インターフェイスの実装として使用されます。その基礎となる実装は、map

data です。 layer
package module

import (
	"fmt"
	"github.com/berkaroad/ioc"
	"github.com/zhaoshoucheng/hodgepodge/IoC/app"
)

var (
	rs app.Resource
)

type ModuleObj struct {
}

func (mo *ModuleObj) DataToSave(str string) {
	fmt.Println("ModuleObj DataToSave ", str)
	rs.Save(str)
}
func (mo *ModuleObj) DataToRemove(str string) {
	fmt.Println("ModuleObj DataToRemove ", str)
	rs.Remove(str)
}

func init() {
	mo := &ModuleObj{}
	// static assert 静态断言类型检测
	func(t app.Module) {}(mo)
	app.GetOrCreateRootContainer().RegisterTo(mo, (*app.Module)(nil), ioc.Singleton)

	app.GetOrCreateRootContainer().Invoke(func(r app.Resource) {
		rs = r
	})
}
ログイン後にコピー

すでに app.Resource を登録しているため、ここで呼び出すとこのインターフェイスを実装するオブジェクトを取得できます

サービス レイヤー
package service

import (
	"fmt"
	"github.com/berkaroad/ioc"
	"github.com/zhaoshoucheng/hodgepodge/IoC/app"
)

var (
	module app.Module

	service2 app.Service2
)

type Service1 struct {
}

func (s1 *Service1) AddData(str string) {
	service2.AddData(str)
	fmt.Println("Service1 AddData ", str)
	module.DataToSave(str)
}
func (s1 *Service1) DelData(str string) {
	service2.DelData(str)
	fmt.Println("Service1 DelData ", str)
	module.DataToRemove(str)
}

func init() {
	s1 := &Service1{}
	s2 := &Service2{}

	service2 = s2

	//static assert 静态断言做类型检查
	func(t app.Service1) {}(s1)
	func(t app.Service2) {}(s2)

	app.GetOrCreateRootContainer().RegisterTo(s1, (*app.Service1)(nil), ioc.Singleton)
	app.GetOrCreateRootContainer().RegisterTo(s2, (*app.Service2)(nil), ioc.Singleton)

	app.GetOrCreateRootContainer().Invoke(func(mod app.Module) {
		module = mod
	})
}
ログイン後にコピー

#メイン

package main

import (
	"github.com/zhaoshoucheng/hodgepodge/IoC/app"
        _ "github.com/zhaoshoucheng/hodgepodge/IoC/resource"
	_ "github.com/zhaoshoucheng/hodgepodge/IoC/module"
	_ "github.com/zhaoshoucheng/hodgepodge/IoC/service"
)

func main() {
	var s1 app.Service1
	app.GetOrCreateRootContainer().Invoke(func(service app.Service1) {
		s1 = service
	})
	s1.AddData("IOC Test")
}
ログイン後にコピー
#テスト

Go言語における制御の反転とは何ですか感想

我们为什么要用到Ioc呢?个人感觉有几点好处
1.解决各种依赖问题,写GO可能都遇到过循环引用问题,越是复杂的系统就越有可能出现这种混乱的调用现象。
2.实现了很好的扩展性,如果存储层想从redis切换到mongo,定义一个相同的对象,替换注册对象就可以轻松实现。
3.易使用,随时随地可以通过Invoke获取相应的接口对象。

问题

难道就没有问题吗?
当然有,就是引用顺序的问题,也就是先register 还是先invoke 这个在例子中感觉很简单,但是在工程中很容易出错

	_ "github.com/zhaoshoucheng/hodgepodge/IoC/module"
	_ "github.com/zhaoshoucheng/hodgepodge/IoC/resource"
	_ "github.com/zhaoshoucheng/hodgepodge/IoC/service"
ログイン後にコピー
        _ "github.com/zhaoshoucheng/hodgepodge/IoC/resource"
	_ "github.com/zhaoshoucheng/hodgepodge/IoC/module"
	_ "github.com/zhaoshoucheng/hodgepodge/IoC/service"
ログイン後にコピー

第一种写法就会崩溃,第二种正确

原因第一种module 的init 先执行,app.Resource的对象还没有注册。所以init的先后顺序很重要

但这个是凭借字节码进行的排序,有时IDE还不让我们改,所以需要一些控制器去处理这种情况。

【相关推荐:Go视频教程编程教学

以上がGo言語における制御の反転とは何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Golang を使用してファイルを安全に読み書きするにはどうすればよいですか? Golang を使用してファイルを安全に読み書きするにはどうすればよいですか? Jun 06, 2024 pm 05:14 PM

Go ではファイルを安全に読み書きすることが重要です。ガイドラインには以下が含まれます。 ファイル権限の確認 遅延を使用してファイルを閉じる ファイル パスの検証 コンテキスト タイムアウトの使用 これらのガイドラインに従うことで、データのセキュリティとアプリケーションの堅牢性が確保されます。

Golang データベース接続用の接続プールを構成するにはどうすればよいですか? Golang データベース接続用の接続プールを構成するにはどうすればよいですか? Jun 06, 2024 am 11:21 AM

Go データベース接続の接続プーリングを構成するにはどうすればよいですか?データベース接続を作成するには、database/sql パッケージの DB タイプを使用します。同時接続の最大数を制御するには、MaxOpenConns を設定します。アイドル状態の接続の最大数を設定するには、ConnMaxLifetime を設定します。

Golang と C++ の類似点と相違点 Golang と C++ の類似点と相違点 Jun 05, 2024 pm 06:12 PM

Golang と C++ は、それぞれガベージ コレクションと手動メモリ管理のプログラミング言語であり、構文と型システムが異なります。 Golang は Goroutine を通じて同時プログラミングを実装し、C++ はスレッドを通じて同時プログラミングを実装します。 Golang のメモリ管理はシンプルで、C++ の方がパフォーマンスが優れています。実際の場合、Golang コードはより簡潔であり、C++ には明らかにパフォーマンス上の利点があります。

Golang フレームワーク アーキテクチャの学習曲線はどれくらい急ですか? Golang フレームワーク アーキテクチャの学習曲線はどれくらい急ですか? Jun 05, 2024 pm 06:59 PM

Go フレームワーク アーキテクチャの学習曲線は、Go 言語とバックエンド開発への慣れ、選択したフレームワークの複雑さ、つまり Go 言語の基本の十分な理解によって決まります。バックエンドの開発経験があると役立ちます。フレームワークの複雑さが異なると、学習曲線も異なります。

Golangでリストからランダムな要素を生成するにはどうすればよいですか? Golangでリストからランダムな要素を生成するにはどうすればよいですか? Jun 05, 2024 pm 04:28 PM

Golang でリストのランダムな要素を生成する方法: rand.Intn(len(list)) を使用して、リストの長さの範囲内でランダムな整数を生成し、その整数をインデックスとして使用して、リストから対応する要素を取得します。

golangフレームワークの長所と短所の比較 golangフレームワークの長所と短所の比較 Jun 05, 2024 pm 09:32 PM

Go フレームワークは、その高いパフォーマンスと同時実行性の利点で際立っていますが、比較的新しい、開発者エコシステムが小さい、一部の機能が欠けているなどの欠点もあります。さらに、急速な変化と学習曲線はフレームワークごとに異なる場合があります。 Gin フレームワークは、効率的なルーティング、組み込みの JSON サポート、強力なエラー処理機能により、RESTful API を構築するための一般的な選択肢です。

Golang フレームワークでのエラー処理のベスト プラクティスは何ですか? Golang フレームワークでのエラー処理のベスト プラクティスは何ですか? Jun 05, 2024 pm 10:39 PM

ベスト プラクティス: 明確に定義されたエラー タイプ (エラー パッケージ) を使用してカスタム エラーを作成する 詳細を提供する エラーを適切にログに記録する エラーを正しく伝播し、非表示または抑制しないようにする コンテキストを追加するために必要に応じてエラーをラップする

golang フレームワークの利点は何ですか? golang フレームワークの利点は何ですか? Jun 06, 2024 am 10:26 AM

Golang フレームワークの利点 Golang は、マイクロサービスや分散システムに特に適した高性能の同時プログラミング言語です。 Golang フレームワークは、既製のコンポーネントとツールのセットを提供することで、これらのアプリケーションの開発を容易にします。 Golang フレームワークの主な利点の一部を次に示します。 1. 高いパフォーマンスと同時実行性: Golang 自体は、その高いパフォーマンスと同時実行性で知られています。コードの同時実行を可能にする軽量のスレッド メカニズムであるゴルーチンを使用することで、アプリケーションのスループットと応答性が向上します。 2. モジュール性と再利用性: Golang フレームワークは、モジュール性と再利用可能なコードを奨励します。アプリケーションを独立したモジュールに分割することで、コードを簡単に保守および更新できます。

See all articles