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

[소프트웨어공학] SOLID(2) : 개방 폐쇄 원칙 (Open-Closed Principle, OCP)

by webcodur 2024. 3. 29.
728x90

목차

     

    개방 폐쇄 원칙 (Open-Closed Principle, OCP)

    SOLID 원칙 중 "O"는 "개방-폐쇄 원칙(Open-Closed Principle, OCP)"을 의미한다. 이 원칙은 "소프트웨어 엔티티(클래스, 모듈, 함수 등)는 확장에는 열려 있어야 하고, 수정에는 닫혀 있어야 한다"는 것을 말한다. 즉, 기존의 코드를 변경하지 않으면서도, 시스템의 기능을 확장할 수 있어야 한다는 뜻이다.

     

    게임을 주제로 한 C# 예시를 들어, 이 원칙을 지키지 않은 코드와 지킨 코드를 비교해보겠다.

     

    OCP를 지키지 않은 코드 예시

    이 예시에서는 게임 내의 다양한 종류의 몬스터를 처리하는 방식을 구현한다. 이 경우, 새로운 몬스터 종류가 추가될 때마다 MonsterHandler 클래스를 수정해야 한다.

     

    using System;
    
    namespace GameExampleWithoutOCP
    {
        class Program
        {
            static void Main(string[] args)
            {
                MonsterHandler handler = new MonsterHandler();
                handler.HandleMonster("zombie");
                handler.HandleMonster("vampire");
            }
        }
    
        public class MonsterHandler
        {
            public void HandleMonster(string type)
            {
                if (type == "zombie")
                {
                    Console.WriteLine("Handling a zombie");
                }
                else if (type == "vampire")
                {
                    Console.WriteLine("Handling a vampire");
                }
                // 새로운 몬스터 종류가 추가될 때마다 이 부분을 수정해야 함
            }
        }
    }
    
    

     

     

    OCP를 지킨 코드 예시

    아래 코드는 개방-폐쇄 원칙을 준수하는 방식으로 구현된다. 새로운 몬스터 종류를 추가하고 싶을 때 IMonster 인터페이스를 구현하는 새로운 클래스를 만들기만 하면 되며, 기존 코드는 수정할 필요가 없다.

    using System;
    
    namespace GameExampleWithOCP
    {
        class Program
        {
            static void Main(string[] args)
            {
                MonsterHandler handler = new MonsterHandler();
                handler.HandleMonster(new Zombie());
                handler.HandleMonster(new Vampire());
            }
        }
    
        public interface IMonster
        {
            void Handle();
        }
    
        public class Zombie : IMonster
        {
            public void Handle()
            {
                Console.WriteLine("Handling a zombie");
            }
        }
    
        public class Vampire : IMonster
        {
            public void Handle()
            {
                Console.WriteLine("Handling a vampire");
            }
        }
    
        // 이 클래스는 새로운 몬스터 타입이 추가되어도 수정할 필요가 없음
        public class MonsterHandler
        {
            public void HandleMonster(IMonster monster)
            {
                monster.Handle();
            }
        }
    }
    

     

    이 예시에서 MonsterHandler 클래스는 확장에 열려 있으며 (새로운 IMonster 구현을 통해 쉽게 확장 가능), 수정에는 닫혀 있다 (새로운 몬스터 타입을 추가해도 MonsterHandler 클래스를 수정할 필요가 없다). 이로써, OCP 원칙을 준수하게 된다.