의존성 주입(DI), Koin

jeunguri·2022년 5월 4일
0

android

목록 보기
4/13


의존성 주입(DI)


앱의 크래스는 올바른 작동을 위해 다른 클래스에 종속된다. 특정 클래스의 종속 항목을 수집하는 데 다음 디자인 패턴 중 하나를 사용할 수 있다.

이 패턴은 코드를 중복하거나 복잡성을 추가하지 않아도 종속 항목을 관리하기 위한 명확한 패턴을 제공하므로 코드를 확장할 수 있다. 또한 테스트와 프로덕션 구현 간 신속하게 전환할 수 있다.

class Person {
	private Coffee coffee;
    
    public Person() {
    	this.coffee = new Coffee();
    }
    
    public startDrink() {
    	this.coffee.drink();
    }
}

위의 코드를 보면 Person 클래스 에서 startDrink 함수가 호출되기 위해서는 Coffee 클래스를 필요로 한다. 이것을 Person 클래스는 Coffee 클래스의 의존성을 가진다 라고 한다.

이렇게 코드를 작성하면, 코드의 재활용성이 떨어지고, Coffee 클래스가 수정될 경우 Person 클래스도 함께 수정해줘야 하는 문제가 발생한다. 즉, 결합도가 높아진다.


의존성을 주입하면 아래와 같은 코드로 작성할 수 있다.

class Person {
	private Coffee coffe;
    
    public Person(Coffee coffee) {
    	this.coffee = coffee;
    }
    
    public startDrink() {
		this.coffee.drink();
    }
}

위와 같이 필요한(의존하는) 클래스를 주입해주면 객체 간 결합도를 줄이고 좀 더 유연한 코드를 작성할 수 있게 된다.

즉, 한 클래스를 수정하였을 때 다른 클래스도 수정해야 하는 상황을 막아줄 수 있다.



의존성 주입을 해야 하는 이유

  • 코드의 가독성을 높여준다.
  • Unit Test가 쉬워진다.
  • 코드의 재활용성을 높인다.
  • 객체 간 의존성을 직접 설정해 줄이거나 없앨 수 있다.
  • 객체 간 결합도를 낮추면서 유연하게 만들 수 있다.



Koin을 이용한 의존성 주입


  1. Repository 클래스와 이 클래스 객체를 파라미터로 받는 Controller, ViewModel 클래스를 만든다.

  2. module 키워드로 주입받은 객체를 모듈로 만들어 선언한다.

  3. 생성한 모듈을 Application 클래스의 onCreate() 에서 startKoin을 호출해 넘겨준다. (Application 클래스 새로 생성한 경우, manifest.xml에 등록해줘야 한다.)

  • single : 앱이 실행되는 동안 계속 유지되는 싱글톤 객체를 생성

  • factory : 요청할때마다 매번 새로운 객체를 생성

  • get() : 컴포넌트 내에서 이미 생성된 의존성을 주입받을 수 있음
    (이미 생성된 객체 중 해당 타입에 알맞은 객체를 koin이 주입해준다.)

  • androidLogger : AndroidLogger를 Koin Logger로 사용함

  • androidContext : 해당 안드로이드의 application Context를 사용함

  • modules : 사용할 모듈을 등록



1. 모듈 생성

class MyModule(private val context: Context) {
	fun showToast() {
    	Toast.makeText(
        	context, 
            "실행",
            Toast.LENGTH_SHORT
        )
        .show()
     }
}

val appModule = module {
	single { MyModule( get() ) }
}

context를 필요로 하는 MyModule 클래스를 생성해주고, appModule이라는 module을 생성해준다.
module에서는 singleton 형태로 MyModule 객체를 만들어줄 것이다.

이때 MyModule은 context를 전달받아야 하는데, get()을 적어주면 의존성이 부여된다.


2. Application 클래스에서 startKoin()으로 실행

class MyApplication : Application() {

	override fun onCreate() {
    	super.onCreate()
        
        startKoin {
        	androidContext(this@MyApplication)
            modules(appModule)
        }
     }
}

Application()을 상속받는 클래스를 만들고 onCreate()를 재정의한다. 여기에 startKoin을 작성해 모듈을 추가해준다. (module 안에는 여러 module이 들어갈 수 있다.)

3. 의존성 주입

class MainActivity : AppCompatActivity() {
	private val myModule : MyModule by inject()
    
    override fun onCreate(saedInstanceState: Bundle?) {
    	super.onCreate(savedInstanceState)
    	setContentView(R.layout.activity_main)
    
    	myModule.showToast()
    }
}

변수를 선언해주고 by inject() 해주면 의존성이 주입된다. 이 변수를 통해 MyModule 클래스showToast()에 접근할 수 있다.

이렇게 하고 실행해주면 "실행"이라는 Toast가 호출된다.



참고

0개의 댓글