본문 바로가기

C#(ASP.NET)

C# Interface 활용의 단편적인 예


C# 에는 인터페이스라는 개념이 있습니다. (Java에도 있지만...)

MSDN에 명시되 있는 인터페이스 개요를 살펴 보면 다음과 같습니다.


하지만 평소에 공부 제대로 안한 저는 "인터페이스는 개발자간 표준 규악을 지키기 위해 존재하는 ..." 정도로만 알고 있습니다.

즉, 여러 명의 개발자가 어떤 클래스를 구현할 때 그 클래스들의 공통 성격(?) 정도를 인터페이스로 만들어서

지킬 건 반드시 지키게 만들어 주는 것...
이 정도 였습니다.

그런데 이것도 문제가 있는게 해당 개발자가 그 인터페이스를 상속 받지 않고 개발해 버리면 이것도 소용이 없습니다.

담당 팀장이나 책임자가 "너 왜 그 인터페이스 상속 안 받고 개발했어?" 라고 확인해 주지 않는 한 그냥 넘어가게 되는 거죠.

지금까지 제가 말씀 드린 건 인터페이스 활용이라는 측면에 있어서 극히 일부분 입니다.

그리고 제가 앞으로 말씀 드릴 내용도 극히 일부분일 것 입니다.

하지만 제가 위에서 말씀 드린 인터페이스의 첫번째 역할(?) 보다는 지금 말씀 드릴 내용이 생산성 측면에서는 유용하리라 생각 됩니다.

---[시나리오]------------------------------------------------------------------------

1. Panel과 유사한 사용자컨트롤을 만들어 놓고 런타임에 동적으로 Panel에 컨트롤을
   올려 놔야 하는 상황입니다.

2. Panel에 올라가야 하는 컨트롤은 Button일수도 있고, CheckBox일수도 있고,
   다른 어떤 것이 될 수도 있습니다.

3. 각각의 컨트롤들은 Price라는 속성(Property)를 가지고 있어서
    해당 컨트롤을 클릭하면 컨트롤의 이름과 Price를 화면에 표시해 줍니다.

---------------------------------------------------------------------------------------

시나리오 3번에 따라 Button과 CheckBox 클래스를 상속 받아 각각 Price라는 이름의 속성을 추가 했습니다.

 




아래 그림과 같이 시나리오 1번에 따라 Panel 형식의 사용자컨트롤에 이 두개의 컨트롤을 추가할 수 있는 메소드를 구현하였습니다. (AddButton, AddCheckBox)

그리고 각 컨트롤의 클릭 이벤트를 MyControl_EventHandler 메소드에 연결했습니다.


이번에는 System.Windows.Forms 계층에 포함 되지 않는 3rd Party 컨트롤인 DevExpress의 LabelControl을 추가해야 되는 상황이 생겼습니다.



그래서 Panel 쪽 소스가 아래처럼 추가 되었습니다.
AddDevLabel메소드와 MyControl_EventHandler에 else if 문이 추가 되었네요...



이렇게 하다 보니 컨트롤이 하나씩 추가 될 때마다 MyControl_EventHandler 메소드의 소스가 계속 늘어나게 됩니다.

개발자의 입장에서 보면 귀차니즘 100배, 짜증 100배 입니다.

MyControl_EventHandler에서 sender 객체를 타입캐스팅할 때 as 키워드를 사용했습니다.

MyButton button = (MyButton)sender; 처럼 할 수도 있으나 이때 sender 객체가 MyButton 형식으로 타입캐스팅이 안되는 경우
예외가 발생하게 됩니다. 하지만 as의 경우는 타입캐스팅이 안되면 null 을 리턴 하지요.

물론 try ~ catch 문을 사용하면 되지만 try ~ catch를 남발하는 건 좋지 못한 개발 습관이라고 생각합니다.

어쨌든 이제!! 드디어!! 인터페이스를 사용하려고 합니다. 아래 그림과 같이 PriceName과 Price 속성을 갖는 인터페이스입니다.

 

지금까지 위에서 만들었었던 MyButton, MyCheckBox, MyDevLael 클래스에 IPrice 인터페이스를 상속 받게 하고
각 내용의 PriceName, Price 속성을 구현
했습니다.



자.. 이제 위에 있었던 MyControl_EventHandler는 어떻게 바뀔 수 있을까요?



위 그림처럼 딱3줄로 끝나버립니다. 이후부터는 IPrice를 상속 받은 어떤 형식의 컨트롤이 추가 되더라도

MyControl_EventHandler를 고쳐야 하는 경우는 발생하지 않겠지요.

요약해 보면 인터페이스를 사용하게 되면 클래스의 형식이 뭐가 됐던 간에 인터페이스 형식으로

타입캐스팅이 가능해 지기 때문에 해당 클래스를 사용하는 입장에서 보면 소스가 단순해 지는 효과
가 있습니다.

인터페이스를 개발자간 지켜야 할 규약(?), 명세(?) 정도로만 이해하고 있으면 이것을 활용하기가 수월치 않습니다.

혼자 독고다이로 개발하는 경우에 인터페이스의 용도를 규약이나 명세 정도로만 알고 있으면 아예 쓸 일도 없겠지요.

C#에서 제공하는 각종 컬렉션 클래스들 역시 인터페이스를 사용함으로써 컬렉션에 포함된 각 객체의 형식이

무엇이든 foreach 문을 통해 접근 할 수 있는 것입니다.

이런 인터페이스를 제대로 활용하기 위해서는 OOP적인 입장에서 얼마만큼 객체를 효율적으로 추상화 할 수 있느냐가 관건이 될 것입니다.

어찌보면 너무나 당연한 내용을 뭔가 있는 것처럼 횡설수설 늘어놓자니 조금은 부끄럽습니다.

이상으로 인터페이스에 대한 얘기를 마치도록 하겠습니다.


[출처] youngmin77.pe.kr