Marco Cantu의 블로그에서 흥미로운 주제가 있어서 번역하였습니다. 본문에는 해당 요소들에 대한 링크가 있어서 더 깊이있게 이해할 수 있습니다.

제네릭 타입은 델파이 2009 버전에 추가되었습니다. 델파이의 런타임 라이브러리 (RTL)에는 제네릭 컬렉션 유닛이 들어간 것도 이때부터입니다. 하지만 RTL에는 제네릭 컬렉션 뿐만 아니라 기존에 있던 클래식 컬렉션도 여전히 남아 있습니다. 최근에 저는 예전 컬렉션과 새 컬렉션 중 어느 것을 사용하면 더 좋은 지에 대한 질문을 받고 심도있는 토론을 이어갔습니다. 이 토론의 개요를 이 글로 정리합니다.

 

클래식 컨테이너 클래스

RTL에 있는 가장 기본적인 컬렉션 클래스는 (System.Classes 유닛에 있는) TList 클래스입니다. 이것은 포인터들 (또는 개체의 참조들)을 담는 일반적인 리스트입니다. 같은 계열인(System.Contnrs 유닛에 있는) 클래식 컨테이너 클래스(들)로는 다음과 같은 것들이 있습니다:

  • TObjectList는 TObject의 참조들을 담는 TList로, 객체에 대한 소유권(Ownership)* 지원을 포함
  • TComponentList 또한 소유권을 가지며, 컴포넌트 알림(Notification: 생성 및 해제 알림)**을 지원
  • TClassList
  • TOrderedList
  • TStack과 TQueue, TObjectStack과 TObjectQueue
  • 다양한 BucketList(해시 테이블)

위 컨테이너들을 사용할 때에는 종종 여러분이 다루고 있는 개체의 타입을 변환(cast)하여 해당 리스트가 지원해주는 타입에 맞추게 되기 때문에 오류가 생길 가능성이 발생합니다. 만약 여러분이 해당 리스트에서 꺼낸 개체의 타입을 계속 확인하기 위해 “as” 와 같이 동적 변환(dynamic cast)을 사용한다면 프로그램 실행이 느려지는 원인이 되기도 합니다.

myList: TList;
myList.Get(3) as TMyObject

소유권(Ownership)*: 소유권을 위임하면 소유주(Owner) 객체 해재시 소유권을 위임한 객체를 함께 해제합니다. 즉 TObjectList에 소유권 위임 설정(OwnsObjects := True)하면 TObjectList 해제 시 등록된 객체를 함께 해제합니다.

컴포넌트 알림(Notification)**: TComponent는 Notification 메소드를 제공합니다. Notification 메소드는 소유하고 있는 모든 컴포넌트에 소유권 추가와 삭제 메시지를 전달합니다.

 

제네릭 컬렉션 클래스

언어에 제네릭 타입(들)이 추가되면서 델파이에는 제네릭 컬렉션(들) 기본 세트가 추가되었습니다. 이 세트는 System.Generics.Collections 유닛에 있으며, 컨테이너에 담고 싶은 데이터 타입을 여러분이 직접 지정할 있도록, 제네릭한 (, 컨테이너에 담길 타입이 사전에 특정되지 않은) 컨테이너의 밑그림을 제공합니다. 제네릭 컬렉션(들)에는 다음과 같은 것들이 있습니다:

  • TList<T>, 기본 제네릭 리스트로 정렬과 열거(enumeration) 지원합니다.
  • TThreadList<T>, 쓰래드에 안전한 리스트로서 잠금(locking)을 지원합니다.
  • TQueue<T>, TStack<T>
  • TDictionary<TKey,TValue>, 상당히 막강한 딕셔너리이며, 키(key)와 값(value)의 타입을 필요에 맞게 지정할 수 있습니다.
  • TObjectList<T: class> 객체 타입을 담을 수 있으며 소유권을 지원합니다.(아래의 컨테이너들도 동일)
  • TObjectQueue<T: class>, TObjectStack<T: class>
  • TObjectDictionary<TKey,TValue>
  • TThreadedQueue<T>

제네릭 컬렉션의 장점

제네릭스 컬렉션(들)을 사용하면 여러분이 사용하고자 하는 데이터 타입을 담을 특정 컨테이너(들)을 정의할 수 있습니다. 그러면 해당 데이터 타입에 부합하는 지를 컴파일러가 확인하므로 실행 중에 데이터 타입을 확인하지 않아도 됩니다. 그 결과, 코드가 더 깔끔하고 읽기도 더 쉽습니다. 애플리케이션은 더 견고해지고, 실행 시점에 확인할 필요가 줄어들기 때문에 실행 속도도 빨라집니다:

myList: TList <TMyObject>;
myList.Get(3); // TMyObject 반환

델파이에서 새로 추가되는 라이브러리와 서브시스템들은 모두 제네릭 컬렉션(들)을 사용합니다. 예를 들어 파이어몽키는 전통적인 코딩 스타일이 아니라 제네릭 컬렉션(들)을 주로 활용합니다.

 

제네릭 컬렉션을 사용하면 안될 이유는 어떤것이 있나요?

제네릭 컬렉션(들)을 사용하면 안되는 경우는 기본적으로 다음 두 가지가 있습니다.

첫째, 작동하고 있는 기존 코드가 있다면 여러분은 굳이 변경하고 싶지 않을 것입니다. 특히 VCL과 같은 라이브러리에 들어있는 기존 코드를 변경하면, 해당 라이브러리를 사용하는 코드(들)에서 타입 불일치 문제가 발생될 수 있습니다.

둘째, 델파이에 있는 제네릭(들)은 상당한 코드 비대화(Code bloat)을 유발합니다. 컬렉션에서 사용되는 데이터 타입이 거의 같더라도 다양한 데이터 타입을 위한 메소드들이 매번 복제되기 때문입니다. 이점은 굉장히 규모가 큰 애플리케이션에서라면 컴파일 시간과 링크 시간 그리고 실행 파일 크기 측면에서 부정적인 영향을 끼칩니다.

 

 

또 다른 제네릭 컬렉션

마지막으로, 전하고 싶은 점이 있습니다. 만약 여러분이 제네릭 컬렉션(들)을 상당히 많이 사용한다면 스프링4D (Spring4D) 라이브러리에 있는 것들을 고려하시기 바랍니다. 이 라이브러리는 RTL에 있는 것들을 확장한 것입니다. 관련 도움말은 https://bitbucket.org/sglienke/spring4d/wiki/Collections 에 있습니다.

 

다시 말씀드리지만 이 글은 짧은 요약입니다. 훨씬 더 광범위하고 세밀하게 설명할 수도 있겠으나 델파이의 제네릭 컬렉션(들)을 충분히 알지 못해서 예전 방식만 사용하고 있는 개발자들이 있다면 이 요약 만으로도 도움이 되기를 바랍니다.

 

 

참고자료


번호 제목 글쓴이 날짜 조회 수
공지 [DelphiCon 요약] 코드사이트 로깅 실전 활용 기법 (Real-world CodeSite Logging Techniques) 관리자 2021.01.19 15402
공지 [UX Summit 요약] 오른쪽 클릭은 옳다 (Right Click is Right) 관리자 2020.11.16 13957
공지 [10.4 시드니] What's NEW! 신기능 자세히 보기 관리자 2020.05.27 16493
공지 RAD스튜디오(델파이,C++빌더) - 고객 사례 목록 관리자 2018.10.23 22043
공지 [데브기어 컨설팅] 모바일 앱 & 업그레이드 마이그레이션 [1] 관리자 2017.02.06 23266
공지 [전체 목록] 이 달의 기술자료 & 기술레터 관리자 2017.02.06 18920
공지 RAD스튜디오(델파이, C++빌더) - 시작하기 [1] 관리자 2015.06.30 39241
공지 RAD스튜디오(델파이,C++빌더) - 모바일 앱 개발 사례 (2020년 11월 업데이트 됨) 험프리 2014.01.16 174690
50 델파이 코드 주석 추가 및 문서화 방안 험프리 2019.05.30 864
49 1PASSWORD: 델파이로 개발된 BEST 패스워드 관리 프로그램 관리자 2020.12.07 852
48 델파이에서 아이콘 폰트 사용하기 험프리 2019.12.12 830
47 [추가된 문법 정리] - 클래스 필드(Class Field):델파이 2007 추가 관리자 2016.06.03 828
46 [무료 툴] 델파이 JSON 데이터 자동 연동 프로그램 file 관리자 2020.07.20 807
45 [고객사례-게임, 델파이] 오목게임 관리자 2018.10.23 799
44 [고객사례-게임, 델파이] Rise of Legions 관리자 2019.11.08 794
43 [고객 사례- 의료, 델파이] COVID-19 - 검사 결과 실시간 확인 앱 관리자 2020.03.25 788
» 델파이 RTL: 새로운 제네릭 컬렉션 vs 기존 클래식 컬렉션 험프리 2020.01.06 776
41 파이어닥(FireDAC)으로 IBLite 연결 시 "unavaliable database." 오류 발생에 대한 대응 file Humphery 2015.05.15 768
40 [DelphiCon 요약] High DPI 고해상도를 VCL에서 활용하기 (Leveraging High DPI in VCL Applications) 관리자 2021.01.13 767
39 1차 공개 중고생 강의용 앱 소스 및 메뉴얼입니다. file 쭈니아빠 2016.07.16 762
38 델파이 코드 정적 분석기 V2.4 출시 및 무료 다운로드 관리자 2021.05.25 733
37 델파이로 3D 크레딧 스크롤 구현하기(소스제공) file 험프리 2018.05.09 731
36 [UX Summit 요약] 윈도우10에 멋진 플루언트UI 룩앤필을 델파이로 구현하기 #2 (Giving your Apps the Fluent UI Look and Feel with Delphi #2) 관리자 2021.03.02 726
35 리팩토링 3-메소드 추출 file 김원경 2017.02.24 722
34 [DelphiCon 요약] 델파이로 함수형 프로그래밍하기 (Functional Programming With Delphi) 관리자 2020.12.29 710
33 [고객사례-유틸리티, 델파이] 녹음기 앱 - Voice Recorder 관리자 2019.12.10 685
32 [10.4 시드니 신기능] 언어 서버 프로토콜 (LSP, Language Server Protocol) 관리자 2020.06.04 675
31 [델파이 샘플 코드] 안드로이드, iOS, OSX, 윈도우, 리눅스, HTML5 관리자 2019.11.13 673