[c#] 데코레이터 패턴과 의존성 주입

데코레이터 패턴과 의존성 주입은 객체 지향 프로그래밍에서 중요한 개념입니다. 이 블로그에서는 데코레이터 패턴과 의존성 주입에 대해 알아보고, C#에서 어떻게 사용되는지 살펴보겠습니다.

데코레이터 패턴

데코레이터 패턴은 객체에 동적으로 새로운 책임을 추가하는 구조적 디자인 패턴입니다. 이 패턴을 사용하면 상속을 통해 클래스를 확장하지 않고도 기능을 추가할 수 있습니다.

예를 들어, 여러 종류의 음료수 객체를 준비하는 커피 가게를 운영한다고 가정해보겠습니다. 데코레이터 패턴을 사용하여 각 음료에 샷을 추가하거나 휘핑 크림을 올리는 기능을 구현할 수 있습니다.

public interface IBeverage
{
    string GetDescription();
    double Cost();
}

public class Espresso : IBeverage
{
    public string GetDescription()
    {
        return "Espresso";
    }

    public double Cost()
    {
        return 1.99;
    }
}

public abstract class CondimentDecorator : IBeverage
{
    protected IBeverage beverage;

    public CondimentDecorator(IBeverage beverage)
    {
        this.beverage = beverage;
    }

    public abstract string GetDescription();

    public abstract double Cost();
}

public class Whip : CondimentDecorator
{
    public Whip(IBeverage beverage) : base(beverage)
    {
    }

    public override string GetDescription()
    {
        return $"{beverage.GetDescription()}, Whip";
    }

    public override double Cost()
    {
        return beverage.Cost() + 0.50;
    }
}

이 코드에서 IBeverage 인터페이스를 정의하고, Espresso 클래스를 구현합니다. 그리고 CondimentDecorator를 통해 데코레이터를 구현하고, Whip 클래스에서 실제 데코레이터를 추가합니다.

의존성 주입

의존성 주입은 객체 간의 의존 관계를 객체 자체가 해결하는 것이 아니라 외부에서 주입받는 방식을 말합니다.

의존성 주입은 코드의 테스트 용이성을 높이고, 느슨한 결합을 통해 유연하고 확장 가능한 코드를 작성하는 데 도움이 됩니다.

public class Client
{
    private readonly IService _service;

    public Client(IService service)
    {
        _service = service;
    }

    public void DoSomething()
    {
        _service.PerformAction();
    }
}

public interface IService
{
    void PerformAction();
}

public class ConcreteService : IService
{
    public void PerformAction()
    {
        // Implementation
    }
}

위의 코드에서 Client 클래스는 IService 의존성을 외부에서 주입받습니다. 이를 통해 Client 클래스는 어떠한 구체적인 IService 구현체에도 의존하지 않고, 다양한 IService 구현체를 주입받아 사용할 수 있습니다.

데코레이터 패턴과 의존성 주입은 유연하고 확장 가능한 코드 작성을 도와주는 중요한 개념이며, C#에서 이를 적절하게 활용함으로써 좀 더 모듈화되고 테스트 가능한 소프트웨어를 개발할 수 있습니다.

이러한 디자인 패턴과 개념을 잘 활용하여 코드를 작성하면 유지보수 및 확장이 쉬운 소프트웨어를 만들 수 있습니다.

참고 자료