Rumah > Artikel > pembangunan bahagian belakang > Apakah penyongsangan kawalan dalam bahasa go
Dalam bahasa Go, Inversion of Control (IoC) ialah prinsip reka bentuk dalam pengaturcaraan berorientasikan objek Ia boleh digunakan untuk mengurangkan gandingan antara kod komputer, yang bermaksud kawalan kod "terbalik" daripada perniagaan kod. ” kepada kod rangka kerja. Kaedah penyongsangan kawalan biasa dipanggil suntikan pergantungan, dan kaedah lain dipanggil "pencarian pergantungan" melalui penyongsangan kawalan, apabila objek dicipta, entiti luaran yang mengawal semua objek dalam sistem merujuk kepada objek yang bergantung padanya. luluskannya.
Persekitaran pengendalian tutorial ini: sistem Windows 7, GO versi 1.18, komputer Dell G3.
Penyongsangan Kawalan (disingkat IoC) ialah prinsip reka bentuk dalam pengaturcaraan berorientasikan objek yang boleh digunakan Kurangkan gandingan antara kod komputer. Kaedah yang paling biasa dipanggil Dependency Injection (DI), dan kaedah lain dipanggil Dependency Lookup. Melalui penyongsangan kawalan, apabila objek dicipta, entiti luaran yang mengawal semua objek dalam sistem menghantar rujukan objek yang bergantung kepadanya. Ia juga boleh dikatakan bahawa kebergantungan disuntik ke dalam objek.
Secara lebih ringkas, jika saya mempunyai pengawal, UserController, ia boleh Code, Read dan Eat Sudah tentu, ia juga mempunyai __construct constructor dan __destruct destructor mencetuskan dirinya sendiri dalam situasi tertentu, seperti permulaan dan apabila sumber dikeluarkan pada penghujung kitaran hayat Tetapi jika kita menganggap bahawa fungsi ini sendiri tidak akan mencetuskan dirinya sendiri, maka bagaimana kita, sebagai pengarang, membiarkannya dilaksanakan. Malah, pengawal saya juga mempunyai ArticleController dan YouBadBadController Bagaimana saya harus mengendalikannya?
Setiap pengguna harus membina dirinya sendiri sebelum bekerja. Kelemahan situasi ini adalah jelas sebenarnya semua Pengawal Apabila berurusan dengan tingkah laku awam, kita sebenarnya boleh melaksanakan dan mengurusnya secara luaran. Kita tidak memerlukan fungsi ajaib lalai Mari kita perkenalkan senario tertentu Katakan saya kini memerlukan setiap pengawal untuk melaksanakan dan memanggil fungsi pemegang. Bagaimanakah kita boleh menyelesaikannya secara munasabah? Jika kita masih perlu melaksanakan kaedah larian sekarang, selepas menambah fungsi larian pada setiap pengawal, adakah kita masih perlu menulis jadual mereka? operasi? Anda boleh membiarkan Perkhidmatan Pengawal awam membantu mengendalikannya. Kami tidak mempertimbangkan warisan sekarang.
Tunggu sebentar, bagaimana Xiaozhi boleh pergi tanpa membaling Bola Poké Di manakah Xiaozhi? Kita perlu membawa pengawal ke atasclass ControllerService{ public functiondo(){ ->handle(); } //去吧比卡丘; } }supaya kawalan telah diterbalikkan kepada 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();
Mekanisme pantulan antara muka dalam bahasa Go juga merupakan pantulan Ioc
Aplikasi Golang Inversion of Control (IOC) dalam kejuruteraanReka BentukPerpustakaan pihak ketiga yang digunakan:
https://github.com/berkaroad/iocIa agak mudah digunakan, tidak lebih daripada RegisterTo dan Invoke, tetapi mana-mana perpustakaan perlu digabungkan dengan rangka kerja untuk menjadi bermakna.
Apabila bercakap tentang gandingan longgar, mudah untuk memikirkan
antara muka (antara muka)dalam GO, jadi kami menggunakan antara muka untuk mencapai gandingan longgar antara pelbagai lapisan. Menurut rangka kerja MVC tradisional, secara amnya terdapat beberapa lapisan pada bahagian pelayan, lapisan Pengawal, lapisan Perkhidmatan dan lapisan Modul Dari atas ke bawah, cara mengintegrasikan Ioc ke dalam rangka kerja adalah sesuatu yang patut diterokai.
DirektoriStruktur panggilan: Memandangkan tiada perkhidmatan, fungsi utama bertindak sebagai Pengawal, Perkhidmatan ialah lapisan perkhidmatan , dan Modul ialah Lapisan data, Sumber ialah lapisan storan dan apl ialah definisi pelbagai antara muka
utama-->Perkhidmatan-->Modul-->SumberUntuk menunjukkan panggilan antara perkhidmatan, kami mentakrifkan perkhidmatan1 dan perkhidmatan2 Dua perkhidmatan
melaksanakan
takrifan antara muka setiap lapisanpackage 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) }Inisialisasi 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) }Lapisan storan (bawah ke atas)
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) }lapisan data
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 }) }Lapisan perkhidmatan
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 }) }Utama
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") }Ujian
Berfikir 我们为什么要用到Ioc呢?个人感觉有几点好处 问题 难道就没有问题吗? 第一种写法就会崩溃,第二种正确 原因第一种module 的init 先执行,app.Resource的对象还没有注册。所以init的先后顺序很重要 但这个是凭借字节码进行的排序,有时IDE还不让我们改,所以需要一些控制器去处理这种情况。
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"
Atas ialah kandungan terperinci Apakah penyongsangan kawalan dalam bahasa go. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!