中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

go語言控制反轉指的是什么

發布時間:2023-01-31 09:18:11 來源:億速云 閱讀:145 作者:iii 欄目:編程語言

這篇文章主要介紹了go語言控制反轉指的是什么的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇go語言控制反轉指的是什么文章都會有所收獲,下面我們一起來看看吧。

在go語言中,控制反轉(IoC)是面向對象編程中的一種設計原則,可以用來減低計算機代碼之間的耦合度,就是代碼控制權從業務代碼“反轉”到框架代碼。常見的控制反轉方式叫做依賴注入,還有一種方式叫“依賴查找”;通過控制反轉,對象在被創建的時候,由一個調控系統內所有對象的外界實體將其所依賴的對象的引用傳遞給它。

控制反轉是什么

控制反轉(Inversion of Control,縮寫為IoC),是面向對象編程中的一種設計原則,可以用來減低計算機代碼之間的耦合度。其中最常見的方式叫做依賴注入(Dependency Injection,簡稱DI),還有一種方式叫“依賴查找”(Dependency Lookup)。通過控制反轉,對象在被創建的時候,由一個調控系統內所有對象的外界實體將其所依賴的對象的引用傳遞給它。也可以說,依賴被注入到對象中。

講得通俗一點,假如我有一個控制器,UserController,它可以Code,Read,Eat ,當然它還有隱式的__construct構造函數,__destruct析構函數,我們知道這些默認函數在特定的情景會自己觸發,比如初始化的時候,生命周期結束釋放資源的時候,但是我們如果假如這些函數本身都不會自己觸發,那么我們作為作者怎么去讓他執行。實際上我的控制器還有ArticleController ,YouBadBadController,我怎么去處理。

各干各的 User你干活之前先去構建一下自己,Article你干活之前也去構建一下自己 這個情況短板就很明顯了,后面介紹,每個控制器都要去各干各的,實際上都是Controller ,在處理公共行為的時候,其實我們可以借組外部實現和管理。 我們不用默認的魔法函數了,介紹一個具體場景,假如我現在需要每個控制器都要實現并調用一個handle函數。我們怎么合理去完成,假如現在還要執行一個run 方法 ,每個控制器添加完run函數之后,我們是不是還要寫他們的調度;

控制反轉統一管理 這個操作是不是可以讓一個公共的ControllerService幫忙handle就行了,我們現在不考慮繼承。

class ControllerService{

public functiondo(){

->handle();

 } //去吧比卡丘; }

}

等等,小智不投精靈球怎么去吧,小智呢? 我們需要把控制方帶過來

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();

這樣控制權已經反轉給ControllerService了;

Go語言中的interface 反射機制也是Ioc的體現

Golang 控制反轉 (IOC)在工程中應用

設計

采用的第三方庫

使用起來還是比較簡單的,無非就是RegisterTo, Invoke,但是任何的庫都需要結合框架起來才有意義。

一提到松耦合,在GO中很容易就想到接口(interface),所以我們用接口實現的各個層之間的松耦合。

按照傳統的MVC框架,一般服務端會有幾種分層,Controler層、Service層、Module層 從上到下,如何將Ioc結合在框架中才是值得探討的事情。

目錄

go語言控制反轉指的是什么

調用結構:由于沒有服務,main函數充當的是Controler、Service是服務層、Module是數據層、Resource是存儲層、app是各種接口的定義
main-->Service-->Module-->Resource
為了演示服務之間的調用,我們定義了service1和service2兩種服務

實現

各層的接口定義

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

數據層

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已經注冊過,所以這里Invoke的時候就可以獲取到實現該接口的對象

服務層

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
	})
}

Main

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語言控制反轉指的是什么”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

元阳县| 灵川县| 马尔康县| 广西| 金乡县| 宁河县| 苍南县| 淄博市| 安多县| 高台县| 怀化市| 丹棱县| 肇州县| 丰台区| 岑巩县| 招远市| 古浪县| 抚州市| 金平| 五华县| 且末县| 五指山市| 名山县| 辽阳县| 华容县| 湘潭县| 青海省| 桑植县| 东兰县| 昌乐县| 宁陵县| 岳池县| 吴川市| 绵竹市| 濉溪县| 万载县| 广元市| 宜春市| 句容市| 阜平县| 叙永县|