의존성주입(Dependency Injection)

장상희·2024년 12월 19일

DI (Dependency Injection)

  • 의존성 (의존관계, 의존)

-의존성이란??

-개체가 자신의 기능을 수행하기 위해 필요한 다른 객체나 구성요소

  • 주입

-주입??

-객체가 필요한 위의존성을 외부에서 제공 받는 과정

  • 의존성 주입

-의존성 주입

-객체가 자신의 기능을 수행하기 위해 필요한 다른 객체나 구성 요소를 외부에서 제공 받는 과정

컴포넌트를 드래그 드롭으로 스크립트에 연결하는 것도 넓은 의미에서 의존성 주입

public void Start()

public void Attack()//어택메소드는
{
	BaseAttack();//이 베이스어택메소드를 의존하고 있다 //의존성 (의존 관계, 의존): 객체가 자신의 기능을 수행하기 위해 필요한 다른 객체나 구성요소
}

public void BaseAttack() {Debug.Log("BaseAttack"); }

만약에 위 코드에 다른 메소드를 추가 한다고 가정을 하면

public  enum AttackType//이넘 생성
{
	BaseAttack,
	SpecialAttack,
}

AttackType attackType;//이넘 필드 생성ㅇ

public void Start()
{
	attackType = AttackType.SpecialAttack;
	Attack();
}

public void Attack()
{
	if(attackType == AttckTpye.BaseAttck)//만약 베이스 어택이면 이걸 실행하고
		BaseAttack();
	else if (attackType == AttackType.SpecialAttack)//만약 스페셜 어택이면 이걸 실행한다
		SpecialAttack();
}

public void BaseAttack() {Debug.Log("BaseAttack");}
public void SpecialAttack() {Debug,Log("SpecialAttack");}

만약 다른게 더 추가가 된다면

//Player3 class
public  enum AttackType
{
	BaseAttack,
	SpecialAttack,
	MagicAttack,
}

AttackType attackType;

public void Start()
{
	attackType = AttackType.SpecialAttack;
	Attack();
}

public void Attack()
{
	swich(attackType)
	{
		case AttackType.BaseAttack:     BaseAttack(); break;
		case AttackType.SpecialAttack:    SpecialAttack(); break;
		case AttackType.MagicAttack:    MagicAttack(); break;
	}
}

public void BaseAttack() {Debug.Log("BaseAttack");}
public void SpecialAttack() {Debug.Log("SpecialAttack");}
public void MagicAttack() {Debug.Log("MagicAttack");}

하지만 이런식으로 코드가 계속 작성되면 기능이 추가 될 때 마다 의존하는 코드가 계속 늘어나고 그러면 코드 변경이 계속 추가로 일어나서 유지 보수가 상당히 어려워진다 물론 당장은 몇 개 안되서 문제가 없지만 늘어나면 유지 보수가 쉽지 않을 꺼다

의존성 주입 (예시 코드)

public interface IAttckType//인터페이스 생성
{
	public void Attack();//attack 메소드를 가지고 있는 인터페이스
}
//Player4 class
private void SetAttackType attackType;//인터페이스 필드로 만들고

public void SetAttackType(IAttackType _attackType)//인터페이스를 매개변수로 받는 메소드 하나 생성(SetAttackType)
{                                                 //그래서 이메소드를 호출하면 어찌되었건 매개변수로 IAttackType이 있을 테니깐 그 IAttackType 인터페이스를 받아서 필드에 넣을꺼다
	attackType = _attackType;
}
public void Attack()//IAttackType의 인터페이스는 퍼블릭 보이드 메소드를 무조건 구현화 할테니깐 당연히 이 인터페이스는 내부에 있는 어택을 사용할 수 있을 것이다
{
	attackType.Attack();
}

위에 있는 여러 어택을 넣은 코드와 비교하자면 확연히 줄여든게 보인다 기존 코드는 무엇인가 증가하면 계속 같이 늘었는데 이코드는 이게 끝이다 나머지 코드들은 따로 구현을 해줘야 하는데 어떤식으로 하냐면 이런식으로 하면 된다

public class BaseAttack : MonoBehaviour , IAttackType//아까 만든 인터페이스를 상속 받아서 구현을 해주는 것이다
{
	public void Attack() { Debug.Log("BaseAttack"); }
}
public class BaseAttack : MonoBehaviour , IAttackType//아까 만든 인터페이스를 상속 받아서 구현을 해주는 것이다
{
	public void Attack() { Debug.Log("SpecialAttack"); }
}
public class BaseAttack : MonoBehaviour , IAttackType//아까 만든 인터페이스를 상속 받아서 구현을 해주는 것이다
{
	public void Attack() { Debug.Log("MagicAttack"); }
}

위와 같이 스페셜 어택과 매직 어택 또한 똑같이 구현이 가능하다

의존성 주입해서 써보기

public class AttackDependencyinjection : MonoBehavior
{
	//아래 어택타입들은 IAttackType을 상속 받았기 때문에 애네들중 하나를 아래에 넣을 수 있다
	public BaseAttack baseAttack;
	public MagicAttack magicAttack;
	public SpecialAttack specialAttack;
	public Player4 player;
}
	public void Start()
	{
		player.SetAttackType(baseAttack);//Player4 클래스에 있는 SetAttackType을 호출한다
		player.Attack();//baseAttack을 실행한다
	}

출처:게이머 TV

profile
프로그래머 꿈나무

0개의 댓글