백엔드 개발 Golang Go 언어 의존성 주입이란 무엇입니까?

Go 언어 의존성 주입이란 무엇입니까?

Jan 18, 2023 pm 04:41 PM
golang 언어로 가다 의존성 주입

Go 언어에서 DI(종속성 주입)는 필요할 때 구성 요소 간의 종속성을 분리하는 디자인 패턴입니다. 서로 다른 구성 요소는 통합 인터페이스를 통해 다른 구성 요소의 객체와 상태를 얻을 수 있습니다. 종속성 주입의 이점은 분리이며, 분리는 향상된 코드 확장성, 향상된 코드 유지 관리, 보다 쉬운 단위 테스트 등 더 많은 이점을 가져올 수 있습니다.

Go 언어 의존성 주입이란 무엇입니까?

이 튜토리얼의 운영 환경: Windows 7 시스템, GO 버전 1.18, Dell G3 컴퓨터.

의존성 주입이란 무엇인가요?

이 단어를 처음 들었을 때 발음하기가 어려웠습니다. 아마도 봄철을 공부한 많은 학생들이 이것이 매우 기본적이고 이해하기 쉬운 지식이라고 생각하지만, 저는 이 단어를 한번도 배운 적이 없기 때문입니다. Java와 Spring이라 처음 이 단어를 접했을 때 매우 혼란스러웠습니다.

Dependency Injection, 영어 이름은 의존성 주입, 줄여서 DI입니다. 종속성이라는 단어는 이해하기 쉽습니다. 소프트웨어 설계에는 아키텍처 모듈에서 기능적 방법에 이르기까지 크고 작은 종속성이 있습니다.

예를 들어, 새로운 A보다 새로운 B가 생성되어야 하고, A는 B에 종속됩니다. 이때 B는 A의 종속성이고, A는 B를 제어하며, AB와 B 사이에는 결합 관계가 있다고 말할 수 있습니다. 코드 디자인 아이디어는 최고의 느슨한 결합을 달성할 수 있습니다. 어느 날 B를 변환해야 한다면 A도 변환해야 합니다. 이것이 종속성이라면 문제가 없을 수 있지만 A->B->C->D->E->F 사이에 일련의 종속성이 있는 경우 변환하는 것이 매우 번거로울 것입니다.

이때, 그들 사이의 강력한 결합을 분리할 무언가가 필요합니다. 어떻게 분리할 수 있을까요? 우리는 A에서 B까지의 통제권을 제3자에게 넘겨줄 수 밖에 없습니다. 이런 아이디어를 Inversion of Control(IOC Inversion Of Control)이라고 하며, 이 제3자를 IOC 컨테이너라고 합니다. IOC 컨테이너가 해야 할 일은 새로운 B를 생성한 다음 이 B의 인스턴스를 A에 주입하는 것입니다. 그러면 A는 일반적으로 B 기반 메서드를 사용할 수 있습니다. 이 프로세스를 종속성 주입이라고 하며 IOC 기반 이 메서드를 호출합니다. 의존성 주입.

간단히 말하면 DI(종속성 주입)는 구성 요소 간의 종속성을 분리하는 디자인 패턴입니다. 필요한 경우 다양한 구성 요소가 통합 인터페이스를 통해 다른 구성 요소의 개체와 상태를 얻을 수 있습니다. Go 언어의 인터페이스 디자인은 타사 종속성 주입 프레임워크(예: Java 등)를 사용해야 하는 많은 상황을 방지합니다. 우리의 주입 솔루션은 Dager 또는 Guice와 유사한 주입 솔루션을 거의 제공하지 않으며 개체와 구성 요소 간의 종속성을 수동으로 구성하지 않는 데 중점을 둡니다.

의존성 주입의 이점

의존성 주입의 개념을 이해하려면 이것이 가져오는 가장 큰 이점인 디커플링도 이해해야 합니다.

그리고 분리는 향상된 코드 확장성, 향상된 코드 유지 관리, 보다 쉬운 단위 테스트 등 더 많은 이점을 가져올 수 있습니다.

그럼 종속성 주입을 구현하는 방법은 무엇입니까?

Java에는 다음과 같은 메소드가 있습니다.

  • setter 메소드 주입: 외부 컨테이너가 종속 유형의 객체를 호출할 수 있도록 특정 속성의 공개 설정 메소드를 구현합니다.

  • 인터페이스 기반 주입: 종속 유형의 개체를 주입하기 위해 외부 컨테이너에 대한 특정 인터페이스를 구현합니다.

  • 생성자 기반 주입: 특정 매개변수로 생성자를 구현하고 새 객체를 생성할 때 종속 유형의 객체를 전달합니다.

  • 주석 기반 주입: 코드에 특정 키워드를 추가하여 주입을 수행합니다.

주석은 주석과 마찬가지로 코드로 실행되지 않고 특별히 다른 사람들이 읽을 수 있도록 하는 가장 일반적인 방법입니다. 그러나 주석을 읽는 사람은 전적으로 사람이고, 사람 이외의 주석을 읽는 주요 독자는 프레임워크나 프리컴파일러입니다.

Go 의존성 주입-와이어

wire는 주석 기반 의존성 주입 방법입니다. wire는 Google의 오픈 소스 종속성 주입 도구로, 특수 go 파일에서 유형 간의 종속성을 wire에 알려 주기만 ​​하면 됩니다. 자동으로 코드를 생성하고, 지정된 유형의 객체를 생성하고, 해당 종속성을 조합하는 데 도움을 줍니다. wire是 Google 开源的一个依赖注入工具,我们只需要在一个特殊的go文件中告诉wire类型之间的依赖关系,它会自动帮我们生成代码,帮助我们创建指定类型的对象,并组装它的依赖。

wire有两个基础概念,Provider(构造器)和Injector(注入器)。

通过提供provider函数,让wire知道如何产生这些依赖对象。wire根据我们定义的injector函数签名,生成完整的injector函数,injector函数是最终我们需要的函数,它将按依赖顺序调用provider

wire的要求很简单,新建一个wire.go文件(文件名可以随意),创建我们的初始化函数。比如,我们要创建并初始化一个Mission

wire에는 Provider(생성자)와 Injector(인젝터)라는 두 가지 기본 개념이 있습니다. 🎜🎜 provider 기능을 제공하여 wire에 이러한 종속 개체를 생성하는 방법을 알립니다. wire는 우리가 정의한 injector 함수 서명을 기반으로 완전한 injector 함수를 생성합니다. need. 의존성 순서에 따라 provider를 호출하는 함수입니다. 🎜🎜wire에 대한 요구 사항은 매우 간단합니다. 새 wire.go 파일(파일 이름은 임의적일 수 있음)을 만들고 초기화 기능을 만듭니다. 예를 들어 Mission 객체를 생성하고 초기화하려는 경우 다음과 같이 할 수 있습니다. 🎜
//+build wireinject

package main

import "github.com/google/wire"

func InitMission(name string) Mission {
  wire.Build(NewMonster, NewPlayer, NewMission)
  return Mission{}
}
로그인 후 복사

첫 번째 줄에서 +build wireinject라는 주석을 볼 수 있는데, 이는 이것이 인젝터임을 나타냅니다. +build는 실제로 Go 언어의 기능입니다. C/C++의 조건부 컴파일과 마찬가지로 go build 실행 시 일부 옵션을 전달할 수 있으며, 이러한 옵션에 따라 특정 파일의 컴파일 여부가 결정됩니다. wire 도구는 wireinject를 사용하는 파일만 처리하므로 wire.go 파일에 이를 추가해야 합니다. +build其实是 Go 语言的一个特性。类似 C/C++ 的条件编译,在执行go build时可传入一些选项,根据这个选项决定某些文件是否编译。wire工具只会处理有wireinject的文件,所以我们的wire.go文件要加上这个。

在函数中,我们调用wire.Build()将创建Mission所依赖的类型的构造器传进去。例如,需要调用NewMission()创建Mission类型,NewMission()接受两个参数一个Monster类型,一个Player类型。Monster类型对象需要调用NewMonster()创建,Player类型对象需要调用NewPlayer()创建。所以NewMonster()NewPlayer()我们也需要传给wire

함수에서는 wire.Build()를 호출하여 Mission이 의존하는 유형의 생성자를 전달합니다. 예를 들어, Mission 유형을 생성하려면 NewMission()을 호출해야 합니다. NewMission()은 두 개의 매개변수와 Monster<를 허용합니다. /code> 유형입니다. <code>Monster 유형의 객체는 NewMonster()를 호출하여 생성해야 하고, Player 유형의 객체는 NewPlayer()를 호출하여 생성해야 합니다. . 따라서 NewMonster()NewPlayer()wire에 전달해야 합니다.

wire.go 파일을 작성하고 wire 명령어를 실행하면 wire_gen.go 파일이 자동으로 생성됩니다.

// Code generated by Wire. DO NOT EDIT.

//go:generate wire
//+build !wireinject

package main

// Injectors from wire.go:

func InitMission(name string) Mission {
  player := NewPlayer(name)
  monster := NewMonster()
  mission := NewMission(player, monster)
  return mission
}
로그인 후 복사

와이어가 자동으로 InitMission 메서드를 생성하는 것을 볼 수 있습니다. 이 메서드에서는 플레이어, 몬스터, 미션이 순차적으로 초기화됩니다. 그런 다음 주 함수에서 이 InitMission만 호출하면 됩니다.

func main() {
  mission := InitMission("dj")

  mission.Start()
}
로그인 후 복사

종속성 주입 이전의 코드는 다음과 같았습니다.

func main() {
  monster := NewMonster()
  player := NewPlayer("dj")
  mission := NewMission(player, monster)

  mission.Start()
}
로그인 후 복사

훨씬 더 간단하지 않나요? 여기에는 개체 초기화가 세 개만 있습니다. 그 이상이면 종속성 주입의 이점을 깨닫지 못할 수도 있습니다.

예:

wire.go文件:
// +build wireinject
// The build tag makes sure the stub is not built in the final build.

package di

import (
	"github.com/google/wire"
)

//go:generate kratos t wire
func InitApp() (*App, func(), error) {
	panic(wire.Build(dao.Provider, service.Provider, http.New, grpc.New, NewApp))
}

实现文件:
//dao
var Provider = wire.NewSet(New, NewDB, NewRedis)
//service
var Provider = wire.NewSet(New, wire.Bind(new(pb.Server), new(*Service)))


生成的wire_gen.go 文件:
func InitApp() (*App, func(), error) {
	redis, cleanup, err := dao.NewRedis()
	if err != nil {
		return nil, nil, err
	}
	db, cleanup2, err := dao.NewDB()
	if err != nil {
		cleanup()
		return nil, nil, err
	}
	daoDao, cleanup3, err := dao.New(redis, db)
	if err != nil {
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	serviceService, cleanup4, err := service.New(daoDao)
	if err != nil {
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	engine, err := http.New(serviceService)
	if err != nil {
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	server, err := grpc.New(serviceService)
	if err != nil {
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	app, cleanup5, err := NewApp(serviceService, engine, server)
	if err != nil {
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
		return nil, nil, err
	}
	return app, func() {
		cleanup5()
		cleanup4()
		cleanup3()
		cleanup2()
		cleanup()
	}, nil
}
로그인 후 복사
그렇다면 종속성 주입이란 정확히 무엇입니까?

그냥 캡슐화와 디커플링일 뿐입니다.

【관련 추천: Go 비디오 튜토리얼, 프로그래밍 교육

】🎜

위 내용은 Go 언어 의존성 주입이란 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 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 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Redis Stream을 사용하여 GO Language에서 메시지 대기열을 구현할 때 User_ID 유형 변환 문제를 해결하는 방법은 무엇입니까? Redis Stream을 사용하여 GO Language에서 메시지 대기열을 구현할 때 User_ID 유형 변환 문제를 해결하는 방법은 무엇입니까? Apr 02, 2025 pm 04:54 PM

Go Language에서 메시지 대기열을 구현하기 위해 Redisstream을 사용하는 문제는 Go Language와 Redis를 사용하는 것입니다 ...

골란드의 사용자 정의 구조 레이블이 표시되지 않으면 어떻게해야합니까? 골란드의 사용자 정의 구조 레이블이 표시되지 않으면 어떻게해야합니까? Apr 02, 2025 pm 05:09 PM

골란드의 사용자 정의 구조 레이블이 표시되지 않으면 어떻게해야합니까? Go Language 개발을 위해 Goland를 사용할 때 많은 개발자가 사용자 정의 구조 태그를 만날 것입니다 ...

GO에서 플로팅 포인트 번호 작업에 어떤 라이브러리가 사용됩니까? GO에서 플로팅 포인트 번호 작업에 어떤 라이브러리가 사용됩니까? Apr 02, 2025 pm 02:06 PM

Go Language의 부동 소수점 번호 작동에 사용되는 라이브러리는 정확도를 보장하는 방법을 소개합니다.

Go 's Crawler Colly의 큐 스레드의 문제는 무엇입니까? Go 's Crawler Colly의 큐 스레드의 문제는 무엇입니까? Apr 02, 2025 pm 02:09 PM

Go Crawler Colly의 대기열 스레딩 문제는 Colly Crawler 라이브러리를 GO 언어로 사용하는 문제를 탐구합니다. � ...

PHP에서 의존성 주입 (DI)의 개념을 설명하십시오. PHP에서 의존성 주입 (DI)의 개념을 설명하십시오. Apr 05, 2025 am 12:07 AM

PHP에서 의존성 주입 (DI)을 사용하는 핵심 값은 느슨하게 결합 된 시스템 아키텍처의 구현에 있습니다. DI는 외부 적으로 종속성을 제공하여 코드 테스트 성과 유연성을 향상시켜 클래스 간의 직접 종속성을 줄입니다. DI를 사용하는 경우 생성자, 설정 포인트 메소드 또는 인터페이스를 통해 종속성을 주입하고 IOC 컨테이너와 함께 객체 라이프 사이클 및 종속성을 관리 할 수 ​​있습니다.

GO의 어떤 라이브러리가 대기업에서 개발하거나 잘 알려진 오픈 소스 프로젝트에서 제공합니까? GO의 어떤 라이브러리가 대기업에서 개발하거나 잘 알려진 오픈 소스 프로젝트에서 제공합니까? Apr 02, 2025 pm 04:12 PM

GO의 어떤 라이브러리가 대기업이나 잘 알려진 오픈 소스 프로젝트에서 개발 했습니까? GO에 프로그래밍 할 때 개발자는 종종 몇 가지 일반적인 요구를 만납니다.

GO 프로그래밍에서 MySQL과 Redis 간의 연결을 올바르게 관리하고 릴리스하는 방법은 무엇입니까? GO 프로그래밍에서 MySQL과 Redis 간의 연결을 올바르게 관리하고 릴리스하는 방법은 무엇입니까? Apr 02, 2025 pm 05:03 PM

GO 프로그래밍의 자원 관리 : MySQL 및 Redis는 특히 데이터베이스 및 캐시를 통해 리소스를 올바르게 관리하는 방법을 배우는 데 연결 및 릴리스 ...

Golang의 목적 : 효율적이고 확장 가능한 시스템 구축 Golang의 목적 : 효율적이고 확장 가능한 시스템 구축 Apr 09, 2025 pm 05:17 PM

Go Language는 효율적이고 확장 가능한 시스템을 구축하는 데 잘 작동합니다. 장점은 다음과 같습니다. 1. 고성능 : 기계 코드로 컴파일, 빠른 달리기 속도; 2. 동시 프로그래밍 : 고어 라틴 및 채널을 통한 멀티 태스킹 단순화; 3. 단순성 : 간결한 구문, 학습 및 유지 보수 비용 절감; 4. 크로스 플랫폼 : 크로스 플랫폼 컴파일, 쉬운 배포를 지원합니다.

See all articles