ITEM 33 :: EFFECTIVE C#
안녕하세요, 33번째 시간입니다.
이번 챕터는 함수를 매개변수로 사용하여 결합도를 낮추라, 입니다. 이 책은 결합도에 대해 굉장히 강조하는 편입니다. 결국 사용자의 입장보다는 그것을 개발하는 개발자에 대한 중요한 팁이네요.
설명
-
클래스 내의 메서드를 정의하기 위해서 베이스 클래스나 인터페이스를 정의하고 이렇게 정의된 내용을 기반으로 코딩을 한다, 라는 방식도 유효한 접근 방법이지만, 함수를 매개변수로 취하는 방식을 활용하면 기존의 컴포넌트나 라이브러리와 함께 사용해야하는 코드를 개발해야할 때 상당히 큰 도움이 된다.
-
인터페이스와 클래스를 구분하는 것은 중요하나, 때로는 인터페이스를 정의하고 구현하는 것 조차 힘든 상황이 있고, 그러한 상황에서는 델리게이트를 사용하여 컴포넌트의 제약을 기술하면 클라이언트측에서 코드를 사용하기가 더 쉬워진다.
(인터페이스를 정의한다는 것은 결합도가 올라간다는 것이고, 델리게이트를 정의하는 것은 결합도를 낮춘다)
-
여기서, 의존성이 높아지면 높아질수록 컴파일러의 기능을 제대로 사용할 수는 있으나 그에 대한 구현이나 제약조건은 계속해서 커지게 된다. 반대로 의존성, 혹은 결합도를 낮추면 코드 복잡도를 낮출 수 있고, 유연함이 늘어나며, API와 같은 곳에서 사용하기 쉽게 코드를 개발할 수 있지만, 컴파일러가 제공하는 다양한 검사 기능을 활용하기가 어려워진다. 이 둘 사이의 균형을 적절하게 맞추는 것이 개발자의 과제이다.
-
3번의 경우에 대한 대안책으로는 새로운 클래스를 개발할 때에 베이스 클래스를 작성하여 이를 상속하게 하는 방식이 있다. 이를 사용하면 최종 사용자는 누군가가 개발한 컴포넌트를 쉽게 사용할 수 있다. 또한 계약 사항도 명확여 특정 베이스 클래스를 상속하여 새로운 클래스를 작성하고 추상 메서드(혹은 가상)를 구현해 주기만 하면 된다.
결론
결론으로 개발한 컴포넌트와 이를 사용하는 클라이언트 코드 간의 계약 관계를 정의하는 가장 핵심적인 방법은 여전히 인터페이스를 이용하는 것이다. 추상 베이스 클래스를 사용하면 클라이언트 측에서 자주 사용할 법한 코드를 미리 구현해서 제공할 수도 있다. 예측할 수 있는 수준에서 델리게이트를 잘 활용하면 유연성을 매우 높일 수도 있다. 하지만 도구의 지원(컴파일러 등)을 많은 부분 포기해야 할 수도 있다. 대신 유연성이라는 선물을 얻게 된다. 즉, 적절한 두 사이의 조절이 필요한 부분이다.