Tim Corey의 레슨 16을 통한 C# 인터페이스 설명
"C# App Start to Finish" 과정의 레슨 16에서 Tim Corey는 Create Tournament form을 계속 구축하고 있습니다, 그러나 실제 학습 목표는 버튼과 목록 상자를 연결하는 것을 훨씬 초월합니다. Tim이 폼을 연결하는 과정을 통해, 그는 C#에서 느슨한 결합을 위해 사용되는 핵심 소프트웨어 디자인 개념인 인터페이스를 소개합니다. 이 수업은 인터페이스를 추상 아카데믹 개념이 아니라 WinForms 애플리케이션의 실제 문제를 해결하기 위한 실질적인 도구로 보여줍니다.
이 기사에서는 Tim Corey가 인터페이스를 설명하고, 그가 왜 이를 사용하는지, 긴밀한 결합을 피하는 방법을 심도 있게 살펴봅니다. 모든 설명, 이유, 결론은 Tim의 워크스루에서 직접 나오며, 그의 흐름, 용어, 예제를 대본에서 사용합니다.
폼 연결은 쉽다 — 이를 올바르게 연결하는 것은 쉽지 않다
1:18에, Tim은 Create Prize와 Create Team UI 요소를 연결하기 시작합니다. 그는 즉시 이 단계를 어렵게 느낄 수 있다고 지적합니다, 또 다른 폼을 호출하는 것이 hard이기 때문이 아니라, 데이터를 올바르게 가져오는 것이 보통 사람들이 잘못하는 부분이기 때문입니다.
Tim은 또 다른 폼을 여는 것이 도전이 아니라는 점을 설명합니다 — 그 부분은 쉽습니다. 도전은 한 폼이 다른 폼으로 데이터를 돌려보내는 방법입니다, 긴밀한 설계 문제를 일으키지 않고. 이것이 종속성이 아닌 계약을 정의하는 아이디어가 중요하기 시작하는 부분입니다.
긴밀한 결합의 유혹
1:34에, Tim은 일반적인 실수인 Create Tournament 폼을 Create Prize 폼에 직접 연결하는 것을 명시적으로 지적합니다. 이 접근 방식에서는 하나의 클래스가 어느 다른 클래스와 대화하고 있는지 정확히 알고 있습니다.
Tim은 이것이 긴밀한 결합을 생성한다고 설명합니다, 즉 그 폼들이 직접 서로에게 의존한다는 것입니다. 하나의 폼이 변경되면, 다른 폼이 영향을 받습니다. 프로그램의 다른 부분이 나중에 동일한 기능을 원할 경우, 이를 재사용할 수 없습니다.
그는 이것이 컴파일되고 작동할 수 있지만, 더 큰 시스템이나 전문 환경에서는 좋은 장기적인 설계 선택이 아니라고 강조합니다.
코드를 작성하기 전에 단계를 생각하기
2:02에, Tim은 멈추고 코드를 바로 작성하는 대신 단계를 적습니다. 그는 다음을 목록에 추가합니다:
Create Prize 폼 호출
PrizeModel 가져오기
- 선택된 상금 목록에 추가하기
Tim은 먼저 단계를 작성하면 논리 오류를 피하고 코드의 의도가 명확해진다고 설명합니다. 이 구조화된 사고는 인터페이스가 도입될 때 특히 중요해집니다, 왜냐하면 인터페이스는 무엇을 해야 하는지를 정의하지, 그것이 어떻게 이루어지는지를 정의하지 않기 때문입니다.
참조 유형 및 반환 값이 항상 필요하지 않은 이유
대략 4:56에서, 팀은 전달되는 모델에 대한 중요한 세부 사항을 설명합니다. 그는 시청자들에게 그들이 객체의 복사본이 아니라 주소를 전달하고 있음을 상기시킵니다.
데이터 커넥터를 통해 상이 저장될 때, 모델은 이미 ID가 채워져 있습니다. 팀은 인스턴스가 이미 수정되었기 때문에 모델을 다시 반환하는 것이 종종 불필요하다고 지적합니다.
이는 인터페이스가 맹목적으로 데이터를 이동시키기 위해 존재하는 것이 아니라, 완료와 책임을 신호하기 위해 존재하는 이유를 강화합니다.
모델을 먼저 전달하는 것이 나쁜 아이디어인 이유
6:42에, 팀은 형태 생성자에 PrizeModel을 전달하여 두 형태가 같은 인스턴스를 공유하도록 하는 아이디어를 논의합니다.
그는 사용자가 형태를 취소하면 목록에서 빈 혹은 잘못된 상을 얻게 되는 실제 사용 사례에서 실패하는 이유를 설명합니다. 팀은 두 클래스가 인스턴스 데이터를 공유할 수 있다고 해서 반드시 그래야 한다는 것을 의미하지 않는다고 보여줍니다.
이 순간은 인터페이스가 데이터를 저장하는 것이 아니라 행동을 정의한다는 생각을 강화합니다.
호출 형태를 직접 전달하는 것은 더 나쁜 생각입니다
7:46쯤, 팀은 또 다른 일반적인 접근 방식인 전체 생성 토너먼트 형태를 생성 상 형태에 전달하고 SavePrize 같은 공개 메소드를 호출하는 것에 대해 다룹니다.
팀은 이것이 더 나쁜 이유를 설명합니다:
상 형태는 이제 어떤 클래스가 그것을 호출하고 있는지 정확히 알고 있습니다.
다른 관련 없는 클래스는 상 형태를 재사용할 수 없습니다.
- 클래스는 단일 사용 사례에 고정되어 있습니다.
그는 이것을 타이트 커플링이라고 명시적으로 지칭하며, 우리가 피하고자 하는 것입니다.
계약으로서의 인터페이스 소개
9:01에 팀은 해결책인 인터페이스를 소개합니다.
그는 인터페이스 키워드를 사용하여 새로운 인터페이스를 만들고 IPrizeRequester라고 명명합니다. 팀은 시청자들에게 인터페이스가 다음과 같다고 상기시킵니다:
클래스가 아니다
구체적인 메소드를 포함하지 않는다
- 계약을 정의하기 위해 존재한다
인터페이스는 단일 메소드를 포함합니다:
- PrizeComplete(PrizeModel model)
팀은 이 메소드가 무엇이 일어나야 하는지를 정의하며, 어떻게 일어나야 하는지를 정의하지 않는다고 설명합니다.
인터페이스 멤버와 책임
9:40에 팀은 이 인터페이스를 구현하는 사람이 그 메소드를 지원할 것에 동의한다고 설명합니다. 인터페이스는 기본적으로 공개 멤버를 가지고 있으며 인스턴스 데이터를 선언하지 않습니다.
이것은 팀이 인터페이스는 능력을 정의하며, 스토리지를 정의하지 않는다는 것을 명확히 하는 부분입니다. 구현하는 클래스는 메소드가 호출될 때 무엇을 할지를 결정합니다.
클래스 대신 인터페이스 유형 전달
10:19에 팀은 생성 상 형태 생성자를 구체적인 형태 대신 IPrizeRequester를 수용하도록 수정합니다.
그는 이것이 의미하는 바는 다음과 같다고 설명합니다:
누군가가 형태를 호출할 것이다
그 형태는 그 사람이 누구인지 모른다
- 유일한 요구 사항은 호출자가 인터페이스를 구현해야 한다는 것이다
이것은 실천에서 느슨한 결합입니다. 상 형태는 구체적인 클래스가 아닌 인터페이스 유형에 의존합니다.
추후 사용을 위한 인터페이스 인스턴스 저장
11:06에 팀은 클래스 레벨에서 인터페이스 인스턴스를 저장합니다. 그는 생성자 파라미터가 저장되지 않는 한 생성자 내부에만 존재한다고 설명합니다.
이는 나중에 상 형태가 버튼 클릭 이벤트 내부에서 PrizeComplete를 호출할 수 있게 허용합니다.
구현한 클래스를 호출
11:49에 팀은 핵심 순간을 보여줍니다:
callingForm.PrizeComplete(model);그는 상 형태가 이제 인터페이스를 구현한 사람에게 다시 전화를 걸어 다음과 같이 말한다고 설명합니다:
"저는 끝났고, 여기에 완료된 모델입니다."
이 호출이 완료된 후에야 형태가 닫힙니다. 이는 생성이 성공적이었을 때만 상이 추가되도록 보장합니다.
토너먼트 형식에 인터페이스 구현
13:29에 팀은 토너먼트 생성 형태로 전환하고 인터페이스를 구현합니다.
그는 13:58에서 this 키워드를 설명하며, 이를 현재 인스턴스 — 메모리의 실제 객체라고 설명합니다. 이것을 전달함으로써, 형태는 자신의 주소를 전달하고 있지만 인터페이스 계약을 통해서만 전달합니다.
여러 인터페이스, 하나의 클래스
18:41에 팀은 두 번째 인터페이스인 ITeamRequester를 소개합니다.
그는 클래스가 한 베이스 클래스(예: Form)만 상속할 수 있는 반면, 여러 인터페이스를 구현할 수 있다고 설명합니다. 이는 단일 클래스가 여러 관련 없는 행동을 여러 상속 없이 지원할 수 있게 합니다.
팀은 인터페이스가 코드를 가져오지 않고, 필요한 메소드만 정의한다고 강조합니다.
패턴, 일관성 및 오류 감지
42:08 근처에서 팀은 패턴을 사용하는 것이 왜 중요한지에 대해 반성합니다. 같은 인터페이스 기반 구조를 반복하면 누락된 단계를 명확히 보이고 디버깅을 더 쉽게 만듭니다.
팀은 기록하고, 일관된 패턴을 사용하고, 모든 것을 머리에 담으려고 하지 말라고 격려합니다. 그에 따르면, 좋은 설계는 완벽함이 아니라 명확성, 구조 그리고 미래의 변경을 쉽게 만드는 것입니다.
결론
수업 16에서 팀 코리는 실제 WinForms 사용 사례를 통해 인터페이스가 어떻게 느슨한 결합을 가능하게 하는지를 보여줍니다. 추상적인 예에 의존하기보다는 인터페이스가 다음을 어떻게 하는지를 보여줍니다:
계약 정의
클래스 분리
단일 클래스에서 여러 인터페이스 지원
타이트한 결합 방지
- 장기적 유연성 향상
수업이 끝날 때쯤, 애플리케이션은 단지 작동하는 것이 아니라, 성장, 재사용, 명확성을 지원하는 방식으로 구조화됩니다. 팀의 접근 방식은 인터페이스를 실제 C# 개발에서 실용적이고, 목적이 있으며 필수적인 느낌으로 만듭니다.
이 인터페이스와 느슨한 결합 개념의 전체적인 애플리케이션을 실제로 보고 싶다면, 모든 단계가 구현되고, 테스트되고, 실제 C# 애플리케이션 내에서 세련된 수업 16의 전체 동영상을 시청하세요.

