메뉴 바로가기 검색 및 카테고리 바로가기 본문 바로가기

한빛출판네트워크

IT/모바일

부분 클래스(Partial class) 이해하기

한빛미디어

|

2004-11-25

|

by HANBIT

20,686

휘드비에서 마이크로소프트는 새로운 기능인 부분 클래스(partial class)를 제공한다. 부분 클래스를 이용하면 하나의 클래스를 여러 개의 파일에서 정의하는 것이 가능하다. 부분 클래스는 설계자 코드와 구현 코드를 분리하는 문제를 해결하기 위한 것으로 휘드비에서 부분 클래스는 한쪽 파일에는 디자이너 코드를 담고, 다른 쪽에는 유저 코드를 담아 이들을 분리시키는데 사용되고 있다. 컴파일 시간에 이들 파일은 하나로 합쳐진다. 그러나 부분 클래스의 유용함이 꼭 설계자 지원에만 있는 것은 아니다. 부분 클래스에 대해 살펴보고 자신의 프로젝트에서 얻을 수 있는 장점이 무엇인지 살펴볼 것이다.

부분 클래스 사용하기

부분 클래스의 동작은 매우 간단하다. 단순히 새로운 키워드 partial을 사용하면 된다. VB에서는 다음과 같다.

Partial Public Class SampleClassProperties

C#에서는 다음과 같다.

public partial class SampleClassProperties

프로젝트에서 다양한 클래스들이 컴파일 될 때 분리된 파일들은 하나로 합쳐지고, 클래스의 다양한 요소들도 컴파일을 수행할 때 하나로 통합된다. 하나 이상의 파일에 클래스를 정의하는 점을 제외하면 보통의 클래스와 다를 게 없다. 메서드 오버로딩 법칙도 여전히 유효하며 인텔리센스(다양한 요소들을 자동으로 완성시켜주는)도 여전히 동작한다. 한쪽 파일에서 선언된 변수는 인텔리센스에서 그 클래스를 구성하는 모든 파일에서 이용할 수 있게 인식한다. 클래스가 특정 인터페이스를 구현하고, 오직 한쪽 파일에서만 인터페이스가 구현된 경우 이 인터페이스 구현은 이 파일에만 국한되지 않고 클래스와 관련된 모든 파일에서 이용할 수 있다.

이러한 새 기능은 혼란을 야기할 가능성도 있다. 여기서는 새 기능이 야기할 혼란을 줄이기 위해 몇가지 파일 명명 규칙에 대해 살펴볼 것이다.

비주얼 스튜디오에서의 용례

웹 폼이나 윈도우 폼에서 컨트롤을 끌어다 놓을 때 해당 컨트롤을 자동으로 초기화하고 속성들을 설정하는 코드가 추가된다. 과거에는 이러한 코드가 "Windows Form Designer generated code" 또는 "Web Form Designer generated code." 영역에 들어갔었다. 개발자들은 이 영역을 무시해야하며, 이것에 대해 고려하지 않아도 되었지만 이러한 코드는 항상 거기에 있었다. 비주얼 스튜디오는 이러한 세부적인 것들을 숨기고 개발자가 이러한 코드를 건드리는 것을 보호하기 위해 부분 클래스를 사용한다.

윈도우 폼에서 분리된 파일은 "FormName.Designer.cs" 또는 "FormName.Designer.vb"와 같은 명명법을 따른다. 이들 파일은 솔루션 탐색기에서 숨겨져 있지만 솔루션 탐색기에서 "Show All Files" 버튼을 클릭하면 이들 파일을 볼 수 있다. 이 파일에서 볼만한 것은 없다. 이 파일은 단순히 윈도우 폼에 추가한 컨트롤에 대한 컨트롤 초기화 정보만 담고 있다.

웹 폼의 경우 비주얼 스튜디오의 설계자는 이 보다 한발짝 더 나아갔습니다. 설계자 클래스는 눈에 보이지 않게 내포되어 있으며 디스크로 작성되지 않습니다. 설계자 클래스에 들어갈 모든 정보는 .aspx 파일에 내포되어 있습니다.

비주얼 스튜디오 설계자가 취한 전략은 다음과 같은 장점을 제공하기 위한 것입니다:
  • 공유 개발 환경에서 파일 경쟁의 감소. 폼 디자이너와 개발자가 동시에 같은 파일을 변경하려 해서는 안된다.
  • 저수준 구현의 분리(Isolation). 각 컨트롤이 어떻게 초기화되고 인스턴스화 되는지 알 필요가 없다.
  • 변경사항에 따른 생성된 코드의 보호. 생성된 코드를 변경하는 경우가 보다 줄어들게 될 것이며, 추가한 어떤 코드도 디자이너 파일에 있지 않게 되며 보호할 수 있다
이러한 것들이 여러분의 설계에서 목표는 아니더라도 여전히 배울만한 것들이 있다.

팀에서의 사용

부분 클래스를 사용할 때 피할 수 있는 몇 가지 함정이 있다. 부분 클래스를 사용하는 것은 좋은 객체 지향 설계를 파괴하지 않으며, 여러 파일에 클래스를 정의하는 것은 디자이너가 리팩토링과 상속의 장점을 얻을 수 있게 해준다.

하나의 클래스를 여러 파일에 정의하는 것은 몇 가지 장점을 갖고 있으며, 코드를 작성할 수 있는 장소도 여러 곳이 될 수 있다는 것을 의미한다. 이것은 혼란을 야기할 수 있다. 분명히 말하자면, 부분 클래스 사용에 있어 새로운 파일 명명 규칙이 필요하다. 개발자들은 하나의 파일에 하나의 클래스를 정의하고, 클래스 이름과 같은 파일 이름을 부여하는 지침에 익숙하다. 부분 클래스가 유용하면서 혼동되지 않게 사용되려면 새로운 지침이 필요하다.

부분 클래스를 사용하는 경우 각 파일의 이름이 보다 더 중요해진다. 파일 이름은 클래스 이름뿐만 아니라 파일에 정의되는 클래스의 종류가 무엇인지까지 나타낼 수 있게 해야 한다. 비주얼 스튜디오 디자이너와 같이 Winform1.Designer.cs와 비슷한 명명 규칙을 따를 수 있다. 이 명명 규칙을 따르면 WinForm1에 대한 디자이너 생성 코드라는 것을 알 수 있으며, WinForm1에 대해 성성된 디자이너 코드는 반드시 이 파일에 들어가야 한다.

마찬가지로 BusinessLogicClass.Properties.vb와 같은 파일 이름을 부여하는 명명 규칙은 이 파일이 BusinessLogicClass에 대한 모든 속성들을 포함하고 있다는 것을 알려준다. 클래스를 Properties, Event, Methods와 같이 그룹으로 묶는 방법은 클래스 구조를 받아들이는데 보다 용이하다. 많은 개발자들이 이미 이러한 구조를 사용하기 위해 "영역(region)"을 사용하고 있다. 부분 클래스는 이러한 구조에서 한걸음 더 진전시킨 것이다. 게다가, 여러 파일에 클래스 구현을 분리함으로써 다수의 사람들이 동시에 하나의 클래스를 작업할 수 있으며, 이는 생산성을 향상시킬 수 있다. 또한, 상용 버전을 지원하면서 다른 버전을 제품화할 수 있으므로 환경 설정 문제도 단순화할 수 있다.

복잡한 부분이나 거의 사용되지 않는 부분을 격리하기 위해 클래스 구현을 개별 파일로 분리할 수 있다. 예를 들어, 클래스에서 다양한 인터페이스를 구현한 경우, 개별 파일에 이들 구현을 작성할 수 있다. 종종, 클래스는 클래스의 핵심 기능과 큰 관계가 없는 특정 프레임워크와 상호 작용하기 위해 필요한 인터페이스를 구현해야 하는 경우가 있다. 예를 들어, 입력된 데이터를 검증하고, 계산을 수행하는 비즈니스 로직이 있다고 하자. 이 클래스는 데이터를 저장할 수 있는 ISaveable 인터페이스를 구현해야 한다. 데이터를 저장하는 것은 이 클래스의 핵심 기능이 아니며, 핵심 기능은 검증과 계산이다. ISaveable 인터페이스의 구현을 별도의 파일에 작성함으로써 이러한 부수적인 기능을 분리할 수 있으며 핵심 기능과 혼재되지 않아도 된다. 뿐만 아니라, 이러한 종류의 분리는 리팩토링에도 도움이 된다. 미래에 이러한 구현들을 기본 클래스로 옮기기로 결정한 경우 구현 세부사항이 이미 분리되어 있기 때문에 리팩토링에도 도움이 된다.

BusinessLogicClass.ISaveable.vb나 BusinessLogicClass.IConable.cs와 같은 파일 이름 명명 규칙에서 이점을 얻을 수 있다. 이들 파일은 파일 이름에 있는 인터페이스를 구현을 담고 있다. 혼동을 줄이는 데 도움이 되는 명명규칙이 있다. 이것은 어렵고 빡빡한 규칙이 될 의도가 있는 것은 아니며, 항상 동작하는 것도 아니다. 클래스가 공통된 메서드나 속성을 갖고 있는 다양한 인터페이스를 구현하는 경우 공통된 부분을 어디에 넣을 것인가가 명확하지 않을 수 있다. 목적은 규칙에 지나치에 엄격하게 얽매이지 않는 것이다. 목적은 혼란을 줄이고 유지보수를 쉽게 하는 것이다.

코드 제너레이션에서의 용례

대부분의 사람들은 부분 클래스가 자동으로 생성되는 코드의 복잡함을 다소 덜어주기 위해서 소개된 것이라고 믿는다. 코드 제너레이션에 분명한 장점들이 있지만, 이것이 유일한 이유가 아니다. 부분 클래스 사용에는 더 큰 이유가 있다.

코드 제너레이터의 문제점은 생성된 코드에 변경을 가하면 코드 재생성을 못하게 되거나 재생성시에 변경 사항을 잃어버릴 수 있다는 것이다. 개발자들은 윈도우 폼이나 웹 폼에 생성된 영역에 추가된 코드가 디자이너에 의해 삭제되거나 제거된 경험이 있을 것이다. 왜냐하면 디자이너는 여러분의 변경사항을 인식하지 못하기 때문에 코드가 재생성될 때 이러한 변경사항이 보호받지 못한다. 추가된 코드를 보호하는 방법은 상속을 사용하거나 상속 레벨이나 생성 레벨을 만드는 것이다. 생성(generation) 레벨에서 사용자 지정 수준으로 상속하여 생성 레벨에 대한 코드 변경을 제한하는 것이다. 이 경우에 생성 레벨은 안전하게 재생성될 수 있다.

이러한 해결책의 문제점은 이러한 상속 계층을 추가하는 것이 불필요하게 복잡한 솔루션을 유발하는 경우가 많다는 것이다. 이러한 과잉 상속 계층은 불필요한 클래스들로 네임스페이스를 지저분하게 만들 수 있다. 부분 클래스는 상속이 필요하지 않을 때 보다 간단한 해결책을 제공할 수 있다.
선택된 데이터베이스 테이틀의 모든 컬럼에 대해서 Read/Write 속성과 Save 메서드를 제공해야 하며, 속성을 초기화하기 위해 두 개의 생성자를 제공하는 클래스를 생성해야 하는 경우를 생각해보자. 이러한 기능들은 쉽게 생성될 수 있으며, 변경없이 계속해서 재사용할 수 있는(boilerplate) 기능을 제공할 수 있다. 아마도 여러분은 생성된 Save 메서드가 사용자 지정 파일에 정의된 비공개 메서드를 호출하는 것을 원할 수도 있다. 이런 경우에도 여러분의 변경사항을 보호하면서 새로운 생성 표준(또는 새 컬럼이나 새 기능)을 이용해서 코드를 재생성할 수 있다.

이러한 경우에 TableObject.Generation.cs나 TableObject.Customization.cs와 같은 파일 이름 명명 규칙을 사용할 수 있다.

Nick Harrison은 노스 캐롤라이나 샬롯에서 일하고 있는 닷넷으로 전향한 유닉스 프로그래머로 주택 융자(mortgage) 분야의 흥미로운 문제들을 해결하기 위해 닷넷을 사용하고 있다.
TAG :
댓글 입력
자료실