본문 바로가기
컴퓨터 과학/소프트웨어공학

[소프트웨어공학] SOLID(5) : 의존성 역전 원칙(Dependency Inversion Principle, DIP)

by webcodur 2024. 3. 29.
728x90
반응형

목차

    의존성 역전 원칙(Dependency Inversion Principle, DIP)

    SOLID 원칙 중 'D'는 의존성 역전 원칙(Dependency Inversion Principle, DIP)을 의미한다.

    이 원칙은 두 가지 핵심 내용을 갖고 있다:

    1. 고수준 모듈은 저수준 모듈에 의존해서는 안 되며, 둘 다 추상화에 의존해야 한다.
    2. 추상화는 구체적인 사항에 의존해서는 안 되며, 구체적인 사항은 추상화에 의존해야 한다.

    이 원칙은 소프트웨어의 결합도를 낮추고, 유연성 및 재사용성을 높이기 위해 사용된다.

    게임을 주제로 한 C# 예시를 통해 의존성 역전 원칙을 지키지 않은 코드와 지킨 코드를 비교해보자.

     

     

    DIP을 지키지 않은 코드 예시

    public class Player {
        private Sword sword;
        private Bow bow;
        private string currentWeaponType;
    
        public Player() {
            this.sword = new Sword();
            this.bow = new Bow();
            this.currentWeaponType = "sword"; // 기본 무기 설정
        }
    
        public void Attack() {
            if (currentWeaponType == "sword") {
                sword.UseWeapon();
            } else if (currentWeaponType == "bow") {
                bow.UseWeapon();
            }
        }
    
        public void ChangeWeapon(string weaponType) {
            this.currentWeaponType = weaponType;
        }
    }
    
    public class Sword {
        public void UseWeapon() {
            Console.WriteLine("검으로 공격한다.");
        }
    }
    
    public class Bow {
        public void UseWeapon() {
            Console.WriteLine("활로 공격한다.");
        }
    }
    
    public class Program {
        public static void Main(string[] args) {
            Player player = new Player();
            player.Attack();
            player.ChangeWeapon("bow");
            player.Attack();
        }
    }

     

    이 코드에서 Player 클래스는 구체적인 SwordBow 클래스에 의존하고 있으며, 새로운 무기 타입을 추가하기 위해서는 Player 클래스 자체를 수정해야 한다.

     

     

    DIP을 지킨 코드 예시

    public interface IWeapon {
        void UseWeapon();
    }
    
    public class Sword : IWeapon {
        public void UseWeapon() {
            Console.WriteLine("검으로 공격한다.");
        }
    }
    
    public class Bow : IWeapon {
        public void UseWeapon() {
            Console.WriteLine("활로 공격한다.");
        }
    }
    
    public class Player {
        private IWeapon weapon;
    
        public Player(IWeapon weapon) {
            this.weapon = weapon;
        }
    
        public void Attack() {
            weapon.UseWeapon();
        }
    
        // 무기를 교체하는 메서드
        public void ChangeWeapon(IWeapon newWeapon) {
            this.weapon = newWeapon;
        }
    }
    
    public class Program {
        public static void Main(string[] args) {
            IWeapon sword = new Sword();
            Player player = new Player(sword);
            player.Attack();
    
            IWeapon bow = new Bow();
            player.ChangeWeapon(bow); // 무기를 활로 교체
            player.Attack();
        }
    }

     

    이 코드에서 Player 클래스는 IWeapon 이라는 인터페이스에 의존하고 있다. 이를 통해 Player 클래스는 Sword, Bow 와 같은 구체적인 무기 클래스의 변경이나 확장에 유연하게 대응할 수 있다. 즉, 의존성 역전 원칙을 통해 코드의 결합도를 낮추고 확장성을 높일 수 있다.

    반응형