프로그래밍 공부
작성일
2024. 1. 29. 17:13
작성자
WDmil
728x90

5.3 객체 세상에서 생각하기

프로그래머가 절차적인 패러다임에서 객체지향 패러다임으로 전환하면 프로퍼티와 행동을 조합하여 객체로 만드는 새로운 통찰력이 생기는 것을 경험할 떄가 많다. 어떤 프로그래머는 작업하던 프로그램의 디자인 단계를 다시 밟아 일부 코드를 객체로 재작성하고, 어떤 프로그래머는 모든 코드를 버리고 객체지향 방식으로 완전히 새로 시작하기도 한다.

 

객체를 이용해서 소프트웨어를 개발할 떄는 두 가지 접근 방법이 있다. 어떤 사람에게는 객체가 단순히 데이터와 함수를 묵어주는 좋은 툴로만 보인다. 이러한 프로그래머는 코드의 가속성과 유지보수 편의성을 높이는 목적으로 여기저기 객체를 심게 된다.

 

이러한 접근 방법을 사용하는 프로그래머는 마치 외과의사가 심장질환 환자에세 심박 조절기를 심듯이 독립된 코드를 분리해내어 객체로 만든다. 이러한 접근방법이 본질적으로 문제가 있는것은 아니다.

 

객체를 하나의 툴로 보는 접근 방법은 많은 상황에서 이득을 준다. 프로그램의 어떤 부분은 주식 시세처럼 객체로 보이는 듯한 감이 들 떄가 있다. 이러한 부분은 실세계의 용어로 기술하면 격리되어 독립화될 수 있는 부분이다.

 

반면, 다른 프로그래머는 객체지향 패러다임을 완전히 수용하여 모든 것을 객체화 한다. 오렌지나 주식 시세처럼 실 세계의 것과 연결되는 객체와 더불어서 추상적인 개념들, 예를 들면 정렬이나 Undo같은 것도 객체화 한다. 이상적인 접근 방법은 이 극단 사이에서 적절한 절충점을 찾는 것이다.

 

처음 작성하는 객체지향 프로그램은 전통적인 절차적 프로그램에 객체 몇몇을 양념으로 끼워넣은 수준일 수도 있다.

반면 객체지향에 너무 빠져들면 모든 것을 강박적으로 객체화한 나머지, int타입마저도 클래스로 만들지도 모른다.


5.3.1 과잉 객체

창의적이고 훌륭한 객체지향 시스템과 사소한 것 까지 객체화하여 모든 팀원을 불편하게 만드는 것은 분명 다르다. 어떤 때는 변수가 그저 변수일 뿐 객체화할 만큼 특별한 이유가 없을 때도 있다.

 

Tic-Tac-Toe 게임을 만든다고 생각해보자. 객체지향 방법론을 제대로 한 번 적용해보기로 마음먹고 클래스와 객체를 어떻게 만들지 곰곰이 생각한다. 이런 종류의 게임은 현재의 판세로부터 누가 이길지 미리 알 수 있다. 게임보드를 표현하기 위해 격자(Grid)객체를 이용하기로 하고 마킹되는 X, O값과 그 위치를 기록하게 한다. 사실 이때 각각의 격자 눈금은 X, O로 된 개별적인 말(Piece) 객체로도 표현할 수 있다.

 

여기서 잠깐! 겨우 X 또는 O표기를 객체로 표현한다고? 무언가 너무 앞서 나갔음이 틀림없다. 그냥 char타입 변수로 X와 O를 표기하면 안 될까? 그것도 좀 무겁다. 아예 Grid자체를 enum타입의 2차원 배열로 하면 어떨까? Piece객체는 따로 객체로 존재할 만큼 복잡한 코드인가?

 

Piece 객체를 정리한 아래 표를 보자.

클래스 연관 컴포넌트 프로퍼티 행동
Piecee 없음 X 또는 O 없음

 

위 표는 굉장히 허전하다. 이러한 허전함은 어엿한 객체로 포장하기 어렵다는 것을 암시한다.

물론 좀 더 앞선 생각을 하는 프로그래머라면 나중에 그래픽 유저 인터페이스에서 복잡한 형태의 X와 O를 그리는 기능을 가질 수 있으니, 객체화 해도 무리가 없다고 주장할 수 있다. 그리기 뿐만 아니라 최근에 마킹한 부분을 다른 색깔로 표현해주는 기능이 들어간다면 색상 항목이 프로퍼티로 추가될 수도 있다.

 

또 다른 접근 방법으로 각 격자 말이 아니라 상태로 취급할 수도 있다. 각 격자 상태는 공백이거나 X또는 O이다. 나중에 적용될지모를 그래픽 애플리케이션을 위해 State라는 상위 클래스를 두고 하위 구현 클래스로 StateEmpty와 StateX, StateO를 만들어 해당 격자를 그리게 할 수도 있다.

 

당연하지만 따로 정답이 있지는 않다. 중요한 점은 애플리케이션을 디자인할 떄 객체화와 관련해서 고민을 ㅁ낳이 해야 한다는 것이다. 이때 잊지 말아야 할 점은 객체는 프로그래머가 코드를 관리하기 쉽게 할 목적으로 있다는 것이다. 만약 다른 특별한 이유 없이 단지 객체지향을 위해 객체화 한다면 무언가 잘못된 것이다.

 

5.3.2 과도하게 일반적인 객체

객체화보다 더 성가신 것은 막연할 정도로 과도하게 일반적인 객체다. 객체지향 개념을 배울 떄는 '오렌지' 같이 누가 봐도 객체임이 자명한 예부터 시작한다. 하지만 실제로 코딩을 할 때는 객체가 상당히 추상적일 떄가 많다. 많은 객체지향 프로그램이 '애플리케이션 객체' 를 가지고 있는데, 비록 애플리케이션 자체는 물리적으로 표현할 길은 없지만 어떤 프로퍼티와 행동을 가지고 있어 객체화 하는것이 유용하기 때문이다.

 

너무 일반적인 객체는 어떤 특정한 것을 표현하지 않는다.

 

무언가 유연하고 재사용성 높은 것을 만들려는 의도에서 일반적인 객체를 만들 수는 있지만 혼란스럽기만 하다. 예를 들어 어떤 프로그램이 미디어 데이터를 정리해서 표시한다고 하자. 사진첩이 될 수도, 뮤직 앨범 모음이 될 수도, 보관 목록이 될 수도 있다. 과도하게 일반적인 접근을 한다면 모든 것을 '미디어' 객체로 보아서 모든 종류의 미디어 데이터 포멧을 담을 수 있는 하나의 상위 클래스를 정의할 수 있다. 미디어 클래스는

'데이터' 라는 프로퍼티를 가질 것이고 거기에 사진이나 음악의 로우 비트값을 담을 것이다. 그리고 어쩌면 '실행' 이라는 행동을 가져서 그림을 그리기도 하고, 음악을 플레이하기도 하며, 보관기록을 수정하기도 할 것 이다.

 

프로퍼티와 행동의 이름을 보면 그 클래스가 과도하게 일반적인지 아닌지 알 수 있다. '데이터' 라는 이름은 너무 일반적이다. 이 이름은 서로 성격이 다른 미디어 데이터 들을 한곳에 담으려다 보니 주어졌다. 마찬가지로 '실행' 이라는 행동도 너무 일반적이다. 이 행동도 서로 성격이 다른 행동들을 대표하려다 보니 너무 일반적이 되었다. 이 디자인에서 미디어 클래스 자체도 너무 일반적인 이름이다. '미디어' 클래스는 대응되는 구체적인 객체가 없기 떄문이다. 사용자 인터페이스에도 없고 실세계에도 없고 프로그래머의 머릿속에도 없다.

 

만약, 프로그래머의 아이디어가 한 개의 클래스로 모두 합쳐졌다면, 그 클래스는 과도하게 일반적일 가능성이 높다.

728x90