일단 객체의 세계 내에서는 상태가 필요 없다는 점을 이야기 했다. 하지만 어떤 이유로든 상태가 생기고 조건문이 생기게 된다고 생각하는 사람들이 있을 것이다. 일단 이 문제를 해결하기 위해 상태가 발생하는 원인을 살펴보자.


1. 객체의 세계 외부와의 소통

2. null을 리턴하는 메소드

3. 상태 확인 메소드

4. 상태 매개 변수

5. 하위 캐스팅

6. enum


객체의 세계 외부와의 소통

객체지향 언어로 만들어진 시스템의 외부에서 내부로 흘러 들어오는 데이터는 모두 객체가 아니다. 이 데이터 중에는 분명 상태의 역할을 할 것들이 존재한다. 사용자가 라디오 버튼 중 어떤 것을 눌렀는가, 어떤 체크 박스를 체크했는가 하는 정보를 속성으로 변환 시키는 순간, 그것은 상태가 되고 조건문을 만들어 내기 시작한다. 또 외부 시스템은 자기가 동작하는 상태를 데이터화 해서 객체의 세계로 보낸다. 그것은 말 그대로 상태 정보다. 데이터베이스에서 튀어 나오는 값들 역시 모두 데이터이고, 이들 중에 어떤 것은 상태 정보일 것이다. 기본적으로 객체지향 내부와 외부의 소통에서는 상태가 무조건 만들어 질 수 밖에 없다. 이 부분을 어떻게 다루느냐가 무상태 프로그래밍의 핵심이다.


null을 리턴하는 메소드

Map에서 key를 찾을 때 key가 저장되어 있지 않는 경우 null을 리턴한다. 라이브러리를 디자인 하는 경우라면 이것은 용인될 수 있다. 하지만 자신이 만드는 메소드라면 null을 리턴하는 것은 좋지 않다. null을 리턴하는 순간 메소드 외부에서는 null인지 아닌지를 체크해야 한다. 이것은 조건문을 만들어 낸다. null 값은 리턴되는 순간 상태 역할을 하게 된다.


상태 확인 메소드

boolean isSomething()과 같은 메소드가 대표적이다. 이것은 보통 if문과 함께 쓰이면서 조건문을 만들어 낸다. 일을 위임할 객체의 상태를 확인할 것이 아니라 그냥 일을 시켜야 한다. 상태에 따른 동작은 위임 객체에서 알아서 할 일이다.


상태 매개 변수

상태를 다른 메소드에 집어 넣는 행위이다. 종종 객체가 다른 객체에게 상태 변수를 집어 넣기도 한다. 이것은 상태에 따른 동작, 즉 조건문을 다른 메소드나 다른 객체에게 전파하는 행위다. 이것은 상태를 객체 세계에 전파한다. 그리고 조건문을 만들고 코드의 가독성을 떨어 뜨린다.


하위 캐스팅

객체지향에서는 하위 타입 은닉을 중요시한다. 하위 타입을 확인하는 순간, 하위 타입을 위한 전용 코드가 된다. 하위 타입은 보통 여러개 존재하므로 비슷한 코드가 늘어나는 문제가 생긴다. 특히 하위 타입 확인은 그 자체가 조건문이다.


IFactory factory = new XpFactory();

if(factory instanceof XpFactory){

      ……

} 



enum 타입

enum은 열거형 타입을 말한다. 열거형은 상태를 가독성 있게 표시하는 대표적인 방식이다. 따라서 상태의 대표격이라고 말할 수 있다. 이것이 상태의 대표가 된데는 C언어의 영향이 크다. 사실 Java에서는 enum도 객체화 되었고, enum을 사용해도 조건문을 사용하지 않을 수 있는 방법들이 많이 있다. 하지만 C언어에서 enum은 int 타입이다. 즉 변수와 다름 없이 쓰이고 가독성도 높아서 거리낌 없이 switch - case 문과 함께 사용된다. enum은 번식력도 높아서 한번 switch - case문과 함께 사용되면 계속해서 사용된다.


여기서 하나 짚고 넘어가고 싶은 것이 있다. 상태라는 것이 꼭 속성으로 선언된 것은 아니라는 점이다.


잘 생각해 보면 조건문이 체크하는 모든 것은 상태다. 상태의 모습을 코드로 확인해 보면 다음과 같다.


상태의 여러가지 모습

boolean flag;

int state;

public boolean isSometing();

if(factory instanceof XpFactory){} 


enum Enum{

    A,

    B,

    C;

}

Enum type;

switch(type){

    case A :

        break;

    case B :

        break;

    case C :

        break;

}


flag는 대표적인 상태 변수다. flag와 if문은 너무나도 잘 어울리는 조합이다.

state는 상태를 나타내는 대표적인 변수명이다. 마치 트레이드 마크 같은 것이다. 이것은 switch - case 문과 매우 잘 어울린다.

boolean 타입을 리턴하는 메소드도 상태의 다른 모습이다. 이 역시 if문과 매우 잘 어울린다.

하위 타입 확인은 if 문과 쓰이는 것이 너무나도 전형적인 형식이다.

enum과 switch - case는 떼어놓기 힘든 커플이다.


이런 모습의 코드는 너무나도 자주 접하고 만드는 것들이라서 과연 저것들을 모두 없애고 "무상태 프로그래밍" 이라는 것을 할 수 있을까? 하는 의문이 생길 것이다.


나는 가능하다고 믿고 있다. 그리고 그것이 코드의 가독성을 높이고 객체지향의 세계를 온전하게 이해하는데 도움을 줄 것이라 생각하고 있다. 다음에 작성될 글들은 실제 상태 기반 프로그래밍 방식을 어떻게 무상태 프로그래밍 방식으로 바꾸는지를 보여줄 것이다.

Posted by 이세영2
,