C#_14 Design Pattern

SeonggyuMin·2025년 4월 4일

CSharp

목록 보기
12/12

1. 디자인 패턴

디자인 패턴이란 자주 발생하는 소프트웨어 설계 문제를 해결하기 위한 재사용 가능한 설계의 모범 사례이다.

이는 이 분야의 사인방(Gang of Four, 줄여 GoF)으로 불리는 에리히 감마(Erich Gamma), 리처드 헬름(Richard Helm), 랄프 존슨(Ralph Johnson), 존 블리시데스(John Vlissides)가 소프트웨어 설계에 있어 공통된 문제들에 대한 표준적인 해법과 작명법을 제안한 책에서 널리 알려진 개념이다.

이러한 디자인패턴은 역할에 따라 생성 패턴, 구조 패턴, 행동 패턴으로 나뉜다.

디자인 패턴의 장점으로는 소프트웨어 품질 유지, 설계 가이드라인, 소통 효율 증대, 설계 시간 감소, 확장성 증가, 유지보수 용이 등 다양한 장점이 있다.
그러나 주의점으로는 디자인 패턴을 쓰지 않아도 될 만한 간단한 기능에는 사용하는 오버엔지니어링과 디자인 패턴을 사용하기 위해 프로그램을 만드는, 주객전도 상황에 유의해야 한다.

디자인 패턴은 게임에 특화된 개념은 아니다. 따라서 디자인 패턴이 내가 사용하고자 하는 상황에 딱 들어맞지 않을 수 있다. 이때는 장점과 원리를 내 프로그램에 녹여내는 것이 중요하다.

1. 팩토리 패턴

팩토리 패턴은 객체 생성 인터페이스 제공, 실제 생성은 서브클래스에 위임하는 것이다.

예시는 다음과 같다.

internal class Program
{
    static void Main(string[] args)
    {
        MonsterFactory level1Factory = new MonsterFactory();
        level1Factory.rate = 1;

        // 1. 처음 맵 만들어 졌을 때 -> 몬스터 3마리
        Monster monster11 = level1Factory.Create("슬라임");
        Monster monster33 = level1Factory.Create("슬라임");
        Monster monster55 = level1Factory.Create("슬라임");

        // 2. 다음 장소로 이동했을 때 -> 몬스터 5마리
        Monster monster1 = level1Factory.Create("슬라임");
        Monster monster2 = level1Factory.Create("슬라임");
        Monster monster3 = level1Factory.Create("슬라임");
        Monster monster4 = level1Factory.Create("고블린");
        Monster monster5 = level1Factory.Create("고블린");

        // 3. 보스룸 입장하면 -> 몬스터 2마리
        Monster bossMonster = level1Factory.Create("오크족장");
        Monster subMonster1 = level1Factory.Create("고블린");
        Monster subMonster2 = level1Factory.Create("고블린");


        // 스테이지 2-1
        MonsterFactory level2Factory = new MonsterFactory();
        level2Factory.rate = 1.1f;
        Monster level2monster1 = level2Factory.Create("슬라임");
        Monster level2monster2 = level2Factory.Create("슬라임");
    }
}

public class MonsterFactory
{
    public float rate;

    public Monster Create(string name)
    {
        Monster monster;
        switch (name)
        {
            case "슬라임": monster = new Monster("슬라임", 1, 100); break;
            case "고블린": monster = new Monster("고블린", 3, 200); break;
            case "오크족장": monster = new Monster("오크족장", 10, 2000); break;
            default: return null;
        }

        monster.hp = (int)(monster.hp * rate);
        return monster;
    }
}

public class Monster
{
    public string name;
    public int level;
    public int hp;

    public Monster(string name, int level, int hp)
    {
        this.name = name;
        this.level = level;
        this.hp = hp;
    }
}

유의할 점은 디자인 패턴은 소스코드를 특정 형태로 짜야 한다는 등 구체적인 개념이 아니다. 문제를 해결하기 위해 마치 청사진 같이 구조와 원리를 사용하는 것이다.

2. 빌더 패턴

먼저 빌더 패턴을 알기 전에 메서드 체이닝을 알아야 한다. 메서드 체이닝은 문법은 아닌 재귀처럼 기법 중 하나이다.

1. 메서드 체이닝

체인 메서드 - 자기 자신 반환 혹은

메서드 체이닝이란, 메서드 호출이 끝난 뒤 반환된 객체를 통해 연속적으로 메서드를 호출하는 프로그래밍 기법이다. 이 때 자기 자신 혹은 앞에서 반환된 객체를 사용할 수 있는 메서드를 연결하여 연속적으로 메서드를 호출한다.

사용 예시

class Player
{
    private int hp = 100;

    public Player Heal(int amount)
    {
        hp += amount;
        return this;
    }

    public Player Damage(int amount)
    {
        hp -= amount;
        return this;
    }

    public void ShowStatus()
    {
        Console.WriteLine($"현재 HP: {hp}");
    }
}
Player player = new Player();
player.Heal(20).Damage(10).ShowStatus();
2. 빌더 패턴
internal class Program
{
    static void Main(string[] args)
    {
        MonsterBuilder orcArcherBuilder = new MonsterBuilder();
        orcArcherBuilder
            .SetName("오크 궁수")
            .SetWeapon("나무 활")
            .SetArmor("가죽 갑옷");

        MonsterBuilder orcWarriorBuilder = new MonsterBuilder();
        orcWarriorBuilder
            .SetName("오크 전사")
            .SetWeapon("나무 몽둥이")
            .SetArmor("철 갑옷");

        MonsterBuilder orcEliteWarriorBuilder = new MonsterBuilder();
        orcWarriorBuilder
            .SetName("오크 전사")
            .SetWeapon("철 검")
            .SetArmor("철 갑옷");

        Monster monster0 = orcArcherBuilder.Build();
        Console.WriteLine("이름 : {0}, 무기 : {1}, 갑옷 : {2}", monster0.name, monster0.weapon, monster0.armor);

        Monster monster1 = orcWarriorBuilder.Build();
        Console.WriteLine("이름 : {0}, 무기 : {1}, 갑옷 : {2}", monster1.name, monster1.weapon, monster1.armor);

        Monster monster2 = orcEliteWarriorBuilder.Build();
    }
}

public class MonsterBuilder
{
    public string name;
    public string weapon;
    public string armor;

    public MonsterBuilder()
    {
        name = "몬스터";
        weapon = "기본무기";
        armor = "기본갑옷";
    }

    public Monster Build()
    {
        Monster monster = new Monster();
        monster.name = name;
        monster.weapon = weapon;
        monster.armor = armor;

        return monster;
    }

    public MonsterBuilder SetName(string name)
    {
        this.name = name;
        return this;
    }

    public MonsterBuilder SetWeapon(string weapon)
    {
        this.weapon = weapon;
        return this;
    }

    public MonsterBuilder SetArmor(string armor)
    {
        this.armor = armor;
        return this;
    }
}
public class Monster
{
    public string name;
    public string weapon;
    public string armor;
}

빌더 패턴은 위와 같이 복잡한 객체를 단계별로 생성하여 단계적으로 메서드를 통해 조립하는 방법이다.

이외에도 다양한 패턴이 있으며 특히 게임에서 자주 쓰이는 패턴 또한 존재한다.


메모

더욱 다양한 디자인 패턴

0개의 댓글