真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

go語(yǔ)言控制反轉(zhuǎn)指的是什么

這篇文章主要介紹了go語(yǔ)言控制反轉(zhuǎn)指的是什么的相關(guān)知識(shí),內(nèi)容詳細(xì)易懂,操作簡(jiǎn)單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇go語(yǔ)言控制反轉(zhuǎn)指的是什么文章都會(huì)有所收獲,下面我們一起來(lái)看看吧。

創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),惠民企業(yè)網(wǎng)站建設(shè),惠民品牌網(wǎng)站建設(shè),網(wǎng)站定制,惠民網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營(yíng)銷,網(wǎng)絡(luò)優(yōu)化,惠民網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競(jìng)爭(zhēng)力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶成長(zhǎng)自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。

在go語(yǔ)言中,控制反轉(zhuǎn)(IoC)是面向?qū)ο缶幊讨械囊环N設(shè)計(jì)原則,可以用來(lái)減低計(jì)算機(jī)代碼之間的耦合度,就是代碼控制權(quán)從業(yè)務(wù)代碼“反轉(zhuǎn)”到框架代碼。常見(jiàn)的控制反轉(zhuǎn)方式叫做依賴注入,還有一種方式叫“依賴查找”;通過(guò)控制反轉(zhuǎn),對(duì)象在被創(chuàng)建的時(shí)候,由一個(gè)調(diào)控系統(tǒng)內(nèi)所有對(duì)象的外界實(shí)體將其所依賴的對(duì)象的引用傳遞給它。

控制反轉(zhuǎn)是什么

控制反轉(zhuǎn)(Inversion of Control,縮寫為IoC),是面向?qū)ο缶幊讨械囊环N設(shè)計(jì)原則,可以用來(lái)減低計(jì)算機(jī)代碼之間的耦合度。其中最常見(jiàn)的方式叫做依賴注入(Dependency Injection,簡(jiǎn)稱DI),還有一種方式叫“依賴查找”(Dependency Lookup)。通過(guò)控制反轉(zhuǎn),對(duì)象在被創(chuàng)建的時(shí)候,由一個(gè)調(diào)控系統(tǒng)內(nèi)所有對(duì)象的外界實(shí)體將其所依賴的對(duì)象的引用傳遞給它。也可以說(shuō),依賴被注入到對(duì)象中。

講得通俗一點(diǎn),假如我有一個(gè)控制器,UserController,它可以Code,Read,Eat ,當(dāng)然它還有隱式的__construct構(gòu)造函數(shù),__destruct析構(gòu)函數(shù),我們知道這些默認(rèn)函數(shù)在特定的情景會(huì)自己觸發(fā),比如初始化的時(shí)候,生命周期結(jié)束釋放資源的時(shí)候,但是我們?nèi)绻偃邕@些函數(shù)本身都不會(huì)自己觸發(fā),那么我們作為作者怎么去讓他執(zhí)行。實(shí)際上我的控制器還有ArticleController ,YouBadBadController,我怎么去處理。

各干各的 User你干活之前先去構(gòu)建一下自己,Article你干活之前也去構(gòu)建一下自己 這個(gè)情況短板就很明顯了,后面介紹,每個(gè)控制器都要去各干各的,實(shí)際上都是Controller ,在處理公共行為的時(shí)候,其實(shí)我們可以借組外部實(shí)現(xiàn)和管理。 我們不用默認(rèn)的魔法函數(shù)了,介紹一個(gè)具體場(chǎng)景,假如我現(xiàn)在需要每個(gè)控制器都要實(shí)現(xiàn)并調(diào)用一個(gè)handle函數(shù)。我們?cè)趺春侠砣ネ瓿桑偃绗F(xiàn)在還要執(zhí)行一個(gè)run 方法 ,每個(gè)控制器添加完run函數(shù)之后,我們是不是還要寫他們的調(diào)度;

控制反轉(zhuǎn)統(tǒng)一管理 這個(gè)操作是不是可以讓一個(gè)公共的ControllerService幫忙handle就行了,我們現(xiàn)在不考慮繼承。

class ControllerService{

public functiondo(){

->handle();

 } //去吧比卡丘; }

}

等等,小智不投精靈球怎么去吧,小智呢? 我們需要把控制方帶過(guò)來(lái)

class ControllerService{
public $handler;

public function __construct($handler){

    $this->handler=$handler ;

} //通過(guò)構(gòu)造函數(shù)帶入; }

//

public function setHandler($handler){

     $this->handler->handle();

 } //通過(guò)setter帶入; }

public function do(){

     $this->handler->handle();

 } //去吧比卡丘; }

}

new ControllerService()->setHandler(new UserController())->do();

這樣控制權(quán)已經(jīng)反轉(zhuǎn)給ControllerService了;

Go語(yǔ)言中的interface 反射機(jī)制也是Ioc的體現(xiàn)

Golang 控制反轉(zhuǎn) (IOC)在工程中應(yīng)用

設(shè)計(jì)

采用的第三方庫(kù)

使用起來(lái)還是比較簡(jiǎn)單的,無(wú)非就是RegisterTo, Invoke,但是任何的庫(kù)都需要結(jié)合框架起來(lái)才有意義。

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

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

目錄

go語(yǔ)言控制反轉(zhuǎn)指的是什么

調(diào)用結(jié)構(gòu):由于沒(méi)有服務(wù),main函數(shù)充當(dāng)?shù)氖荂ontroler、Service是服務(wù)層、Module是數(shù)據(jù)層、Resource是存儲(chǔ)層、app是各種接口的定義
main-->Service-->Module-->Resource
為了演示服務(wù)之間的調(diào)用,我們定義了service1和service2兩種服務(wù)

實(shí)現(xiàn)

各層的接口定義

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

這里其實(shí)怎么實(shí)現(xiàn)都行,只是一個(gè)單例NewContainer就可以

存儲(chǔ)層(自下而上)

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 靜態(tài)斷言類型檢測(cè)
	func(t app.Resource) {}(mo)
	app.GetOrCreateRootContainer().RegisterTo(mo, (*app.Resource)(nil), ioc.Singleton)
        //rd := &ResourceObj{name: "redis"} 實(shí)現(xiàn)是用的map,所以mong會(huì)被覆蓋
        //app.GetOrCreateRootContainer().RegisterTo(rd, (*app.Resource)(nil), ioc.Singleton)
}

RegisterTo是注冊(cè)過(guò)程,在mo對(duì)象后續(xù)會(huì)當(dāng)作app.Resource接口的實(shí)現(xiàn)來(lái)使用,其底層實(shí)現(xiàn)是一個(gè)map

數(shù)據(jù)層

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 靜態(tài)斷言類型檢測(cè)
	func(t app.Module) {}(mo)
	app.GetOrCreateRootContainer().RegisterTo(mo, (*app.Module)(nil), ioc.Singleton)

	app.GetOrCreateRootContainer().Invoke(func(r app.Resource) {
		rs = r
	})
}

因?yàn)槲覀冎癮pp.Resource已經(jīng)注冊(cè)過(guò),所以這里Invoke的時(shí)候就可以獲取到實(shí)現(xiàn)該接口的對(duì)象

服務(wù)層

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 靜態(tài)斷言做類型檢查
	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")
}

測(cè)試

go語(yǔ)言控制反轉(zhuǎn)指的是什么

思考

我們?yōu)槭裁匆玫絀oc呢?個(gè)人感覺(jué)有幾點(diǎn)好處
1.解決各種依賴問(wèn)題,寫GO可能都遇到過(guò)循環(huán)引用問(wèn)題,越是復(fù)雜的系統(tǒng)就越有可能出現(xiàn)這種混亂的調(diào)用現(xiàn)象。
2.實(shí)現(xiàn)了很好的擴(kuò)展性,如果存儲(chǔ)層想從redis切換到mongo,定義一個(gè)相同的對(duì)象,替換注冊(cè)對(duì)象就可以輕松實(shí)現(xiàn)。
3.易使用,隨時(shí)隨地可以通過(guò)Invoke獲取相應(yīng)的接口對(duì)象。

問(wèn)題

難道就沒(méi)有問(wèn)題嗎?
當(dāng)然有,就是引用順序的問(wèn)題,也就是先register 還是先invoke 這個(gè)在例子中感覺(jué)很簡(jiǎn)單,但是在工程中很容易出錯(cuò)

	_ "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"

第一種寫法就會(huì)崩潰,第二種正確

原因第一種module 的init 先執(zhí)行,app.Resource的對(duì)象還沒(méi)有注冊(cè)。所以init的先后順序很重要

但這個(gè)是憑借字節(jié)碼進(jìn)行的排序,有時(shí)IDE還不讓我們改,所以需要一些控制器去處理這種情況。

關(guān)于“go語(yǔ)言控制反轉(zhuǎn)指的是什么”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對(duì)“go語(yǔ)言控制反轉(zhuǎn)指的是什么”知識(shí)都有一定的了解,大家如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。


分享文章:go語(yǔ)言控制反轉(zhuǎn)指的是什么
新聞來(lái)源:http://weahome.cn/article/gsghig.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部