객체지향 이야기 – 2.상속설계(2)

대한민국 개발자와 객체지향 이야기 – 2.상속설계(2)

복잡성이 소프트웨어 개발의 가장 기술적인 주제라면, 확장성은 소프트웨어 생명에 있어 심장과도 같다. 상속 설계를 살펴보며, 두 가지 주제에 대해 차례대로 알아보고, 평가해 보자.

정명수 ㅣmsguns.jung@samsung.com ㅣ 삼성전자 메모리사업부 플래시 소프트웨어 개발 관련 연구원

설계의 핵심은 무엇인가

어떤 소프트웨어 설계자라도 프로젝트 시작을 요구사항 문서부터 합리적이고 오류를 제거해 가는 방법으로 제작해내기란 그리 녹녹치 않다. David parnas와 paul clements에 의하면 이러한 방법으로 개발 된 시스템은 전혀 없었고, 앞으로도 그럴거라고 말한다. 심지어 책이나 논문에 나오는 소규모 프로그램도 전무하다고 단언한다. 원래 설계는 엉성한 프로세스이다. 설계과정에서 몰랐던 부분을 구현하며 깨닫기도 하지만 요구사항과는 달리 잘못된 길로 빠져 들기도 한다. 정성들여 만든 UML 모델을 코드로 구현하는 과정에서 발견하는 구조적인 결함은 어찌 보면 보편적이다. 일부 개발자는 기발한 언어적 기교를 사용해 설계결함을 감추기도 한다. 우리가 생각하는 설계는 언어적 기교를 피하고, 가급적 알기보기 쉽게 작성하는 게 목적이다. 언어적 기교를 개발자의 기본 소양으로 생각하는 경향도 있다. 기교를 써서 설계결함을 감추기 보다는 잘 정의된 설계를 바탕으로 이해하기 쉬운 심플한 코드를 작성하는 게 개발자의 미덕이자 기본 소양이다.

과연 결함을 가지는 설계는 잘못 된 것인가? 설계에 있어 핵심은 무엇 인가? 누구나 설계과정에서 실수를 범할 수 있다. Parnas와 Clements가 주장하는 대로 모든 요구사항을 이해하고 깨끗한 설계를 제시 할 수는 없다. 오히려 실제 설계과정이나 구현 단계에서 설계결함을 발견하는 게 시스템에 있어 올바른 방향이며 설계의 핵심이라고 할 수 있다. 기교에 의해 시스템을 구현한 후, 되돌릴 수 없는 버그를 발견하는 것 보다는 설계과정에서 오류를 발견하고 변경하는 게 개발자의 삶의 질을 높여준다. 코드는 시간에 따라 얼어버리는 냉장고 속 얼음과 같아서 문제점을 설계과정에서 발견하고 수정하는 게 시스템이 개발에 착수 된 다음에 문제점을 발견하고 수정하는데 비해 비용 측면에서 훨씬 이익이다. 시스템에서 실수나 결함을 찾고 조기에 제거하는 게 소프트웨어 설계의 핵심이다.

설계의 정석

훌륭한 해결책을 가진 설계와 그렇지 못한 설계의 차이는 아주 미묘하다. 그래서 특정설계에 대해 엉성하다고 단언하기 힘들다. 브룩스는 설계에 있어 본질적인 어려움과 비본질적인 어려움. 이 두 가지 이질적인 문제로 인해 소프트웨어가 복잡하게 만들어 진다고 주장한다. 본질적인 어려움이란 한마디로 말해 소프트웨어가 하는 일을 정의 할 수 있는 실제 속성을 뜻한다. 비본질적인 어려움은 프로그램이 하는 일 이외에 지켜져야 하는 요구사항 및 언어적인 제약사항을 말한다. 브룩스는 비본질적인 문제가 3세대 언어를 거치면서 해결 됐다고 정의하고 있다.

하지만 브룩스의 정의와는 달리 비본질적 문제가 단지 언어적인 제약사항에서만 오는 게 아니다. 필자는 본질적인 문제를 해결하기 위해 모든 제약사항은 비본질적인 문제에 귀결 될 수 있다고 생각한다. 소프트웨어 개발에 있어서 특별하면서도 도저히 빠져 나갈 수 없는 제약사항을 갖는 문제는 예나 지금이나 디바이스이다. 디바이스의 속도가 빨라지고 지능적인 디바이스가 증가하고 있지만 성능이 향상된 만큼 제약사항의 종류가 더 다양해지고 복잡해 졌다. 또한 소프트웨어가 휴대성과 결합하면서 디바이스와 소프트웨어가 하나의 패키지로 보급되는 빈도가 높아졌다. 이처럼 디바이스를 제어하는 미들웨어나 소프트웨어의 비중이 높아졌기 때문에 디바이스에 대한 제약사항이나 자원의 제약사항 같은 비본질적인 문제가 설계에 영향을 미칠 수밖에 없다. 독자들은 WDM에서 제공하는 리스트와 DMA 조작을 위한 MDL(Memory descriptor list)등이 잘못된 설계의 부산물이라고 생각 하는가?

제약사항을 가진 설계는 이상적인 세계에서 제작된 설계와는 분명 다르다. 좀 더 비약하자면 동일한 상황에 대해 약자에게 일을 맡겨 특정 문제를 해결하는 것과 같다. 이러한 소프트웨어는 비본질적인 문제가 소프트웨어 설계에 상당한 영향력을 갖기 때문에 풍부한 자원과 제약사항이 적은 곳에서 만들어진 소프트웨어 설계에 비해 빈약하고 기형적인 요소를 갖게 된다. 만약 특정한 설계가 이상적인 설계에 비해 복잡도 관리에서 실패하고 확장성을 갖지 못하는 설계로 제작됐더라도 설계를 비웃거나 무시 할 수 없다.

설계의 정석이란 충분히 잘 정의된 디자인을 만드는 것이다. 하지만 충분히 잘 정의된 설계라는 요구사항에서 알 수 있듯이 이 문장의 한정사인 ‘충분히’와 ‘잘 정의된’이라는 단어는 정말 애매모호하다. 하나의 솔루션에 대해 몇 가지 설계를 생각할 수 있을까? 또 촉각을 다투는 프로젝트 현장에서 얼마나 형식적이고 시간 소모적인 설계 표기법을 사용 할 것인가? 명확한 정의가 없는 ‘설계’라는 주제에 대해 충분히 잘 설계한다는 표현이 비현실적으로 느껴진다.

설계와 구현의 반복적인 작업을 통해 충분히 잘 정의된 설계를 하는 것은 스티븐 맥코넬의 말처럼 “더 이상 시간이 없을 때까지” 반복돼야 한다. 여기서는 몇 개의 클래스 계층도 후보들을 작성하고 이를 평가해 제작하는 방법을 이용한다. 지난 호에서 간단히 하나의 추상적인 시스템에 대해 필요한 클래스와 서비스를 클러스터링하고 세 가지 벤 다이어그램을 생성했다. 각 벤 다이어그램을 평가하기 전에 각 벤 다이어그램의 섬네일과 명칭을 정해 평가에 활용하도록 하자(<마소 8월호> 참조).

상속의 자연스러움에 대한 평가

생성된 세 가지 다이어그램은 IS-A관계에 있어서 문맥적으로 어색하지 않다. 특별한 부연 설명 없이도 상속 트리 구조가 간단하기 때문에 쉽게 평가할 수 있다. 자신이 추상화한 시스템의 설계가 IS-A나 HAS-A의 관계에 있어서 모두 동일한 점수를 획득해 좀 더 구체적인 평가가 필요하다면 LSP(Liskov Substitution Principle)에 대한 원칙을 적용해 볼 수 있다. LSP는 OOP의 Seminal paper 주장 중 하나로 오랫동안 상속을 구현하는 개발자들에게 등대가 되었다. Liskov는 논문에서 파생클래스가 특수화 과정을 위해 기본 클래스로부터 상속받지 않는다면 상속을 피해야 한다고 주장했다. LSP는 2000년에 들어서 Andy Hunt와 Dave Thomas에 의해 다시 다음과 같은 내용으로 재해석 됐다.

“사용자는 서브클래스를 사용함에 있어서 기본 클래스의 인터페이스를 통해 둘의 차이점을 인지하지 않고도 사용 할 수 있어야 한다”

필자가 다시 정리하면, 한 트리 내에 클래스 계층도를 형성하는 클래스의 메소드는 모두 동일한 의미의 일관성을 가져야 한다. 만약 상속을 사용해 작성된 프로그램이 굳이 중복성을 고려하지 않았더라도 LSP에 의해 상속 설계가 투명하게 제작됐다면 개발자들이 메소드에 대한 세부 사항들에 대해 걱정하지 않고 객체 자체의 일반적인 특성을 구현하는 데 중점을 둬서 상속의 복잡성이 어느 정도 제거 됐다고 볼 수 있다.

혼합식 벤 다이어그램을 통해 LSP의 예를 간단하게 살펴보자. 혼합식 벤 다이어그램으로부터 파생되는 클래스다이어그램을 참조하면(<그림 3> 참조), 개발자와 관리자의 클래스를 Employee라는 중간의 기본 클래스로부터 상속받아 구현하고 있다. 여기에는 GetPay라는 것이 가상함수로 선언되어 있다. 현재 인스턴스가 자신의 월급을 얼마나 되는지에 대한 값을 return 한다고 가정해보자. 월급을 리턴하는 Employee의 클래스를 상속받은 개발자와 관리자는 가상함수에 대해 오버로딩시켜 구현 할 수 있지만, 관리자는 개발자와 달리 그 쓰임새가 달라서 월급을 리턴하는 게 아니라 연봉을 리턴한다고 생각해보자. 이러한 경우 Employee를 통해 상속을 받아 구현 했음에도 불구하고 메소드의 의미 자체가 달라져서 LSP를 위반하게 된다.

이렇게 Employee의 상속을 받은 개발자와 기획자 클래스의 GetPay 루틴은 동일한 의미를 갖지 못하므로 Employee로 부터 상속을 꾀하지 말라는 의미이다. 꼭 상속을 사용하고 싶다면 완전히 다른 이름을 갖는 메소드를 오버라이드시켜 구현하는 게 좀 더 바람직하다. 즉 GetPay를 통한 값 취득보다는 연봉에 대한 다른 루틴, GetAnnualPay() { return GetPay() * MONTH_ PER_YEAR; };과 같은 구현을 통해 사용하는 것이다.

눈치 빠른 독자는 이미 생각했겠지만, 설계평가에 있어서 LSP의 원칙은 순수 상속 설계보다는 구현에 더 가깝다. 단지 이름을 가진 클래스의 추상화 수준에서 IS-A 관계를 파악하고, 다이어그램 간 상속성의 자연스러움에 대한 가중치를 주기위한 수단으로 LSP와 같은 원칙을 적용하면 된다.

중복성에 대한 평가

클래스 계층도에서 중복성 평가를 확인하는 이유는 코드의 효율성과 유지보수의 용이성을 고려한 것이다. 중복성을 가진 클래스 계층도를 통해 제작된 시스템은 동일한 코드가 여러 곳에 산재한다. 유지보수 기간 동안 중복성을 띄는 기능을 변경하려면 코드가 중복된 만큼 여러 곳에 걸쳐 수정해야 한다. 중복성을 완전히 제거하는 게 개발자의 희망이겠지만 코드가 중복되지 않는 이상적인 시스템은 절대로 존재할 수 없다고 스티븐 맥코넬 같은 대가를 통해 기정사실화 돼버렸다. 중복된 코드가 없는 시스템을 작성할 수 없더라도 시스템의 개발자는 상속 트리를 잘 설계해 동일한 코드가 산재하지 않게 해야 한다. 코드 중복 여부를 판단하는 가장 손쉬운 방법은 동일한 속성(Attribute, 데이터 멤버)이 시스템의 여러 클래스에 존재 하는지를 확인하면 된다.

평가를 위해 우선 나열식 벤 다이어그램을 클래스 다이어그램으로 도식화 시켜보자. 나열 수준의 벤 다이어그램에 대해 많은 사람이 저 수준의 설계라고 알고 있지만 현실에선 나열 수준의 디자인을 자의든 타의든 실제 프로젝트에서 사용하고 있다. 프로젝트에 매진하다 보면 간혹 요구사항에 없는 모듈을 구현해 기존 시스템에 넣거나 기능과는 완전히 동떨어진 부분을 구현하기도 한다. 이때 대부분의 개발자에게는 시간적 여유가 없다. 형상화 도구의 사용은 물론, 머릿속 디자인을 떠올릴 시간조차 없이 편집기에 바로 코딩하는 경우가 다반사이다. 이런 와중에 나열식 설계를 사용한적이 한 번도 없다고 주장할 수 있는 개발자는 극소수이다. 무조건 나열식 설계가 나쁘지만은 않다.

클래스 다이어그램의 가장 큰 문제는 중복되는 속성이 많이 존재 한다는 사실이다. 클래스 다이어그램에서 알 수 있듯이 고객(Client) 클래스와 후원자(Supporter) 클래스에서는 등급(m_nClass)과 자본금(m_nMoney)이 중복되고 개발자와 관리자, 기획자의 클래스에서도 부서(m_nDepartment), 급여(m_nPays), 등급(m_ nClass), 경력(m_nCarrier)의 속성이 중복되며, Managed Object 아래에 추가 되는 모든 클래스는 성(m_bSex)에 대한 속성이 매번 겹친다.

속성과 같은 데이터 멤버가 중복 된다는 것은 속성에 대한 행위, 즉 연산이 중복되고 속성을 이용하는 알고리즘이 같은 방식으로 구현돼서 결국, 클래스에 대한 코드가 중복성을 갖게 될 가능성이 높다. 이런 나열식 클래스 다이어그램은 코드 반복성에서 분명히 좋지 못한 점수를 받을 수밖에 없다. 앞서 제시한 기계식 클래스 계층도는 이러한 측면에서 가장 효율적인 계층도가 되며 나열식 클래스 계층도의 경우 가장 비효율적인 클래스 계층도가 된다. 물론 효율적인 측면에서 평가가 좋다고 클래스 계층도가 뛰어나다고 할 수는 없다. 즉 중복성 이외에도 상속 간 관계의 자연스러움, 확장성을 모두 고려해 후보 다이어그램 중에서 가장 적절한 계층도를 선택해야 한다.

확장성에 대한 평가

언제나 그렇듯이 요구사항은 프로젝트가 진행되는 동안 점차로 늘어나는 경향이 있다. 나선형 개발 프로세스를 가진 객체지향 프로세스에서는 좀 더 일반적인 현상으로 받아들여진다. 객체지향 프로세스를 써서 개발하려면, 우선 전체 시스템에서 일부 기능을 담당하는 클래스를 제작해 시스템을 구성한 후, 미처 생각하지 못하거나 구현하지 못한 모든 기능을 추가시켜 전체 시스템을 구성하는 경향이 강하다. 때문에 확장성에 대한 평가는 설계 초기부터 매우 중요한 역할을 담당한다.

 

 

 

<그림1>나열식 구조의 클래스 다이어그램

클래스 확장이란 개념은 약간 모호함이 존재한다. 일반적으로 두 가지로 해석이 가능하다. 첫째는 기존 클래스 자체에 대한 확장을 요구하는 경우이다. 이러한 경우 기존 클래스에 기능이 확장됨으로써 시스템이 변경돼야 하는 경우가 될 수 있다. 둘째는 시스템 요구사항을 만족하기 위해 새로운 클래스가 제작되거나 새로운 컴포넌트로 인해 확장하는 경우이다. 전자의 경우에 예를 들면 고객, 후원자, 기획자, 개발자, 관리자 등에 대한 각각의 클래스에 해고를 위한 Entire()라는 메소드가 추가되는 경우를 생각할 수 있다. 이런 경우 ManagedObject에 삽입하면 모든 클래스에서 Entire 메소드를 받아 사용할 수 있으므로 적절히 대응할 수 있지만 몇 개의 특징으로 구분되는 그룹 단위로 각기 다른 메소드가 삽입되면 일괄적으로 ManagedObject에 삽입해 시스템을 유지보수 할 수는 없다. 즉 관리자, 기획자, 개발자의 클래스에 새로운 프로젝트를 설정하는 NewProject()라는 메소드를 삽입하면 연관성이 없는 고객과 후원자 같은 클래스를 모두 아우르는 ManagedObject에 NewProject라는 메소드를 삽입할 수 없다. 확정성은 클래스 계층도의 유연함보다 코드 중복과 더 밀접한 관련이 있다. 결국 메소드도 특정 속성을 갖는 데이터 멤버에 따라 결정되기 때문이다. 앞서 코드 중복성에 대한 적절성을 따져 봤지만 전자의 의미를 통해 확장성을 평가하려는 것은 아니다.

후자의 경우 차후에 새로운 클래스가 추가될 여지가 있는가에 대한 평가가 우리가 원했던 확장성 평가에 가깝다. 지난 호에서 작성한 보안견(Dog)에 관련된 클래스를 떠올려 보자. 유지보수 기간에 회사내부 자산인 보안견 클래스에 대한 요구사항이 변경되면 클래스를 어디에 배치해 시스템을 구성할 것인지 난해해 진다. 보안견 클래스는 기본적인 나이, 성별, 개인 관리 아이디를 갖고 있고 보안견을 판매했던 상점들에 대한 속성도 함께 관리해야 한다.

나열식 클래스 계층도의 가장 상위에 존재하는 기반 클래스인 ManagedObject로 부터 보안견 클래스는 파생될 수 있다. IS_A 관계를 바탕으로 평가해 볼 때 상속에 대한 자연스러움을 만족하며 다른 클래스에 영향을 주지 않고 시스템의 한 부분을 새롭게 차지한다. 물론 ManagedObject가 너무나 평범한 기반 클래스이다 보니 보안견 클래스에 보안견에 대한 특성이 좀 더 많이 반영되게 수정이 필요하지만, 효율성 면에서 아주 높은 평가를 받았던 기계식 클래스 계층도에 비해 훨씬 유연한 상속 확장성을 제공한다. 이제 효율성 측면에서 좀 더 높은 평가를 받았던 기계식 클래스 계층도의 문제를 살펴보자.

 

 

 

<그림2>기계식 구조에 새로운 요구사항이 추가 되는 경우

새로운 클래스가 변경된 요구사항에 의해 계층도에 삽입될 때, 이상적으로 설계된 계층도라면 어느 클래스의 자식 클래스로 배치 될 것인지를 판단하기 쉬워야 한다. 기계식 클래스 계층도에서는 보안견 클래스의 기반 클래스가 될 만한 클래스를 찾기 힘들다. 정확히 말하면 기계식 계층도에 의해 만들어진 시스템에 보안견이라는 클래스는 어디서도 상속 받을 수 없다. 시스템 입장에서 보면 고객이나 임직원처럼 관리 대상임이 틀림없기 때문에 현재 클래스가 구현된 계층도 어디엔가 배치돼야 기존 시스템과 어울릴 수 있다. 기계식 계층도는 보안견의 상속을 위한 설계가 없으므로 상속을 금지해야 하는 대상이다.

마지막으로 혼합식 계층도를 평가해보자. 우리가 언급하고 있는 기계식, 나열식, 혼합식 계층도는 모두 어느 정도 자연스러운 상속관계를 유지하고 있다고 볼 수 있다.

 

 

 

<그림3>혼합식 구조의 클래스 다이어그램

<그림 3>과 같은 혼합식 계층도는 기계식 계층도의 사람 클래스 위에 추상 기초 클래스로 인터페이스가 되는 ManagedObject의 인터페이스를 하나 더 얹은 것에 불과하다. 스콧 메이어에 의해 언급된 적이 있지만 이와 같이 상속에 단말 노드로 있지 않는 클래스는 추상 클래스로 만드는 게 설계상에 많은 이점을 준다(이는 다음 호에서 좀 더 상세하게 알아본다). 물론 필요에 따라 구현 시 고객과 임직원의 경우도 추상 클래스로 제작이 가능하다. 혼합식 계층도의 경우 시스템이 관리하는 다른 개체. 즉 보안견과 같은 클래스는 ManagedObject아래에 다른 분류로써 배치가 가능하며, 만약 외주 개발자와 같이 임직원과 고객 사이에 애매하게 존재하는 클래스도 사람이라는 클래스를 통해 새로운 분류로의 상속이 가능하도록 여운을 남겨둔다. 추가가 용이하면서 코드 중복성을 최대한 줄이는 식으로 계층도가 형성되는 게 가장 이상적이다.

혼합식 계층도가 다소 복잡해 보일 수도 있지만, 일반적으로 사용되는 API, 데이터, 메소드(또는 behavior)는 가능한 가장 높은 곳으로 이동시키는 게 좋다. 높은 곳으로 이동할수록 파생 클래스가 이들을 쉽게 사용할 수 있고 이로 인해 여러 개의 단말 노드에서의 코드 중복성을 피하게 된다. 물론 무한정 높이는 것은 깊은 상속 트리를 만들게 된다. 객체지향 프로그래밍은 복잡성을 관리하기 위해 수많은 기법들을 제공하지만, 깊은 상속으로 상속의 기법이 전환되면 복잡성을 줄이기보다 증가시키게 된다. Basili, Brand, Melo에 의해 깊은 상속 트리는 오류율 증가와 상당한 연관성을 갖는 게 입증된 바 있다. 그럼 어느 수준까지 올리는 게 좋을까? 해당 객체의 추상화 수준을 깨트리는 위치까지만 배치하는 게 좋다. 예를 들어 혼합식 계층도에서 임직원(Employee)의 속성인 GetPay()가 사람의 클래스까지 올라가면 그것은 추상화 수준을 깨버리는 게 되므로 임직원 클래스 상에서 배치가 마감돼야 한다.

종합평가

이제 상위 세 가지 평가항목에 대해(하나는 지난 호에서 제시되었다) <표 1>과 같은 상속 설계의 후보를 평가 할 수 있다.

평가 결과를 바탕으로 종합적으로 계층도를 판단해 볼 때 상속 설계에 있어 혼합식 계층도가 가장 유용하게 쓰일 수 있다. 예로 든 한 IT업체의 시스템은 상속 설계에 있어 평가돼야 할 항목을 살피고 각 항목의 장단점을 고찰하는 데 목적이 두기 때문에 아주 간단한 예제이다. 실제 시스템을 구현할 경우 요구사항의 분석이 어렵고 쉽게 평가하기가 힘들다. 특히 특정 프레임워크나 솔루션을 제공하는 경우가 아니면 더욱 그렇다. 실체를 알 수 없는 다수의 개발자를 고객으로 하는 라이브러리, 코어, 엔진 등을 제작할 경우에 상속 설계에 대한 평가는 난해한 면이 있다. 이러한 분야는 많은 시행착오를 겪으며 만들어질 가능성이 높다. 상속 설계가 조금은 난해하고, 개발 프로세스에 있어서 가시적이지 못하지만, 실제 어떤 상속 계층도를 설계하고 평가해 선택하는가에 따라 전체 시스템의 작업 난이도는 물론 유지보수에 대한 비용이 결정된다는 점에 있어서 상속 설계는 단순한 코딩 작업 이상으로 중요하다.

HAS-A 관계

상속 설계에 있어 public으로 표현된 모든 상속은 IS-A 관계로 보고 계층도를 형성했다. 만약 클래스가 원시적인 데이터나 객체를 포함한다면 HAS-A 관계로 구현돼야 한다. 지난 호에 이어 상속 설계에 있어서 IS-A 관계에 대해 많이 살펴본 이유는 IS-A 관계가 HAS-A 관계보다 뛰어나서가 아니다. 상속 관계(IS-A)는 포함 관계보다 오류가 많고, 시스템을 해칠 가능성이 더 크고 까다롭기 때문이다. 반면 HAS-A 관계는 문제가 적기 때문에 편하게 사용 할 수 있다. 다만 HAS-A 관계에서 주의할 점은 private를 상속을 거쳐 포함관계를 구현하는 경우다. Meyers나 Sutter에 의해 제시된 private 상속을 통한 포함관계가 사용되는 이유는 포함되는 클래스의 protected 멤버에 접근 할 수 있기 때문이다. 이러한 접근 방법은 부모 클래스에 지나치게 밀접한 관계를 만들고 객체지향 언어에서 정보 은닉의 주제를 위반하는 결과를 초래한다. 물론 대가들이 제시한 방법들이 큰 도움이 되지만 필자라면 가급적 private를 통한 HAS-A 관계는 포함에 있어서 마지노선에 남겨 둘 것을 권한다.

<표1>종합 평가 테이블

기타 주제

설계를 함에 있어서 간혹 많은 양의 데이터 멤버, 즉 속성을 포함하는 클래스를 설계하기도 한다. 포함, 상속 등의 레벨에 있어서 김태균 교수는 가급적 7이라는 숫자를 넘기지 말라고 권유한다. 이는 실제로 1995년 밀러(Miller)에 의해서도 똑같이 강조됐던 부분이다. 밀러는 개인이 여러 작업을 수행 하면서도 기억 할 수 있는 개별적인 항목의 수가 ‘7+-2’라고 언급했다. 뿐만 아니라 Arthur Riel도 Object-Oriented Design Heuristic이라는 저서에서 7이라는 숫자를 넘기지 않도록 권유하고 있다. 다양한 코딩 보조 애플리케이션(Visual assist와 같은)이 보편화 되어있는 시점에서 숫자에 기인해 클래스를 분리 한다는 게 다소 어색할 수 있으나 멤버와 메소드가 한눈에 들어오지 않는다면 클래스 분리를 적극 고려해야 한다.

제공 : DB포탈사이트 DBguide.net
출처 : 마이크로소프트웨어 2007년 9월

답글 남기기