[Effective C# 개정판 3판] Item : 27장 인터페이스는 간략히 정의하고 기능의 확장은 확장 메서드를 사용하라

참조

소개

  • 확장 메서드를 이용하면 인터페이스에 새로운 동작을 추가할 수 있습니다.
  • 인터페이스에는 가능한 한 최소한의 기능만을 정의하고, 확장 메서드를 세트로 함께 구현하면 손쉽게 기능을 확장할 수 있습니다.
  • 특히 API를 추가적으로 정의하지 않고도 새로운 기능을 추가할 수 있습니다.

System.Linq.Enumerable 클래스 예시

  • System.Linq.Enumerable 클래스가 이 기법을 활용한 대표적인 예 입니다.
  • System.Enumerable dpsms IEnumerable<T> 에 정의된 50개 이상의 확장 메서드가 포함되어 있습니다.
  • Where, OrderBy, GroupInfo 등이 있습니다.
  • 이처럼 IEnumerable<T> 에 대해 확장 메서드를 정의하면 이미 IEnumerable<T> 를 구현하고 있는 클래스를 수정할 필요가 없습니다.

새로운 인터페이스 작성할 때도 적용

  • 새로운 인터페이스를 작성할 때도 동일한 패턴을 사용할 수 있습니다.
  • 인터페이스는 정말 딱 필요한 기능만 포함하도록 하고 다양한 기능을 제공하는 메서드는 전부 확장 메서드로 돌리는 것입니다.
  • 이런 패턴을 적용하면 필수로 작성해야 하는 메서드의 수도 줄일 수 있고 사용자에게 더 풍부한 기능을 제공할 수 있습니다.
  • 약간 엉뚱하긴 하지만, 한가지 예를 살펴 보도록 하겠습니다. 다음에 Marker라는 속성을 정의하고 있는 인터페이스가 있습니다.
public interface IFoo
{
    int Marker { get; set; }
}
  • 이제 이 인터페이스에 대해 Marker 값을 1 증가시키는 확장 메서드를 다음과 같이 작성합니다.
public static class FooExtensions
{
    public static void NextMarker(this IFoo thing) =>
        thing.Marker += 1;
}
  • 이제 어디서든 이 확장 메서드를 사용할 수 있습니다.
static class Program
{
    static void Main(string[] args)
    {
        MyType myType = new MyType();
        myType.NextMarker();
        Console.WriteLine($"{myType.Marker}");
    }
}
public class MyType : IFoo
{
    public int Marker { get; set; }
}
  • 만약, 유지보수 단계에서 다른 개발자가 MyType의 내용을 수정했다고 가정해봅니다.
  • NextMarker()의 내용을 수정해 보았습니다.
// 수정된 클래스
public class MyType : IFoo
{
    public int Marker{ get; set; }
    public void NextMarker() => Marker += 5;
}
  • 코드를 위와 같이 수정하면 이제 응용프로그램이 이전과 다르게 동작하게 됩니다.
  • 다음 코드를 수행하면 Marker 값이 5가 됩니다.
MyType myType = new MyType();
myType.NextMarker();
  • 위와 같은 문제를 완전히 피할 수는 없지만 영향을 최소화 할 수는 있습니다.
  • 이 예제는 적절하지 않게 동작하도록 고안되었지만, 실제 코드를 작성할 때는 클래스 내에 구현한 메서드와 확장 메서로 구현한 메서드가 동일한 원형일 경우 의미적으로 완전히 동일한 작업을 수행하도록 작성해야 합니다.
  • 그렇게 작성해야만 프로그램이 오동작할 가능성을 줄일 수 있습니다.

정리

  • 여러 클래스에서 반드시 구현해야 하는 인터페이스를 정의하는 경우, 인터페이스 내에 정의하는 멤버의 수를 최소한으로 하기 위해 노력해야 합니다.
  • 사용자 편의를 위해서 추가적으로 제공하려는 메서드는 확장 메서드의 형태로 구현하는 것이 좋습니다.
  • 이러한 방법을 활용하면 인터페이스를 구현할 때 반드시 작성해야 하는 코드의 양을 줄일 수 있고, 확장 메서드를 통해 풍부한 기능을 제공할 수 있습니다.
728x90

이 글을 공유하기

댓글

Designed by JB FACTORY