Section 48.12: 인터페이스와 확장 메소드를 활용한 DRY 원칙 기반의 코드 및 mix-in 과 유사한 기능 제공하기

확장 메소드를 이용하면, 인터페이스 자체에는 반드시 필요한 핵심 기능만을 포함시키고, 편의를 위한 메소드나 오버로드된 메소드는 확장 메소드를 별도로 선언함으로써 인터페이스를 간결하게 정의할 수 있다.

더 적은 수의 메소드를 갖는 인터페이스는 새로운 클래스에서 더욱 쉽게 구현 (implement) 할 수 있다. 오버로드된 메소드들을 인터페이스에 직접 포함하기보다는 확장 메소드로 별도 유지함을 통해, 모든 인터페이스 구현물 (implementation) 들에 표준 문안 (boilerplate) 코드를 복사해 넣을 필요를 없앨 수 있어 사용자의 코드가 DRY 원칙을 따를 수 있도록 한다. 이는 실제적으로 C# 에서 지원을 하지 않는 mix-in 패턴 과 유사하다.

System.Linq.Enumerable 내에 존재하는 IEnumerable<T> 에 대한 확장 메소드들이 이에 대한 훌륭한 예제이다. IEnumerable<T> 를 구현 (implement) 하는 클래스들은 오직 두가지 메소드를 구현하기만 하면 된다: generic 과 non-generic 버전의 GetEnumerator() 가 바로 그것이다. 하지만 System.Linq.Enumerable 에는 IEnumerable<T> 을 간결하고 명료하게 사용할 수 있도록 해주는 수많은 유용한 확장 메소드들이 제공된다.

아래 예제에서는 오버로드 (overload) 된 편의를 위한 확장메소드들이 제공되는 매우 간단한 인터페이스를 보여주고 있다.

public interface ITimeFormatter { string Format(TimeSpan span); } public static class TimeFormatter { // ITimeFormatter 를 구현하는 클래스들 모두에 대해 제공되는 오버로드된 메소드. public static string Format( this ITimeFormatter formatter, int millisecondsSpan) => formatter.Format(TimeSpan.FromMilliseconds(millisecondsSpan)); } // 해당 인터페이스를 구현자고자 할 때는 하나의 메소드만 제공하면 되므로 // 추가적인 구현물 (implementation) 을 작성하기가 매우 용이하다. public class SecondsTimeFormatter: ITimeFormatter { public string Format(TimeSpan span) { return $ "{(int)span.TotalSeconds}s"; } } class Program { static void Main(string[] args) { var formatter = new SecondsTimeFormatter(); // 호출자는 두가지의 오버로드된 메소드를 사용할 수 있다 Console.WriteLine($"4500ms is rougly {formatter.Format(4500)}"); var span = TimeSpan.FromSeconds(5); Console.WriteLine($"{span} is formatted as {formatter.Format(span)}"); } }
본 문서는 C# Notes for Professionals (라이센스:CC-BY-SA) 를 한글로 번역한 문서입니다. 번역상 오류가 있을 수 있으므로 정확한 내용은 원본 문서를 참고하세요.

[출처] https://books.goalkicker.com/CSharpBook/

반응형

+ Recent posts