본문 바로가기

기타/객체지향의 탄생(2013)

객체지향의 탄생-Strategy Pattern

 

  1. 패턴

디자인 패턴은 '객체와 객체간의 관계에서 반복적으로 발견되는 좋은 원칙을 이끌어 내어 패턴으로 만들어낸 ' 이라고 정의했다.

 

객체지향의 기법이 가장 고도화 되고 추상화 되고 패턴화 결과물이 디자인 패턴이다. 디자인 패턴은 객체지향의 최고 고수, 저명한 학자들이 발견하고 패턴화 했다. 우리가 디자인 패턴을 안다는 것은 객체지향 최고의 추상화되고 패턴화된 지혜를 쉽게 아는 것과 같다.

 

디자인패턴은 '특정한 객체지향 개발 영역에서 자주 발생되는 설계 및 구현 문제에 대하여, 유연하고 확장성 높은 객체지향적 설계 패턴으로 해결하는 방법들의 모음' 이다.

 

디자인패턴 정의에 모음이란 단어를 포함했듯이 디자인패턴 안에 많은 패턴들이 존재한다. 많은 종류의 디자인패턴은 종류별로 비슷한 특성을 보이기도 한다. 디자인패턴의 비슷한 특성끼리 모아 별도의 범주로 구성하기도 한다. 디자인패턴 카탈로그에 따라 이 책도 행동, 구조, 생성의 범주로 디자인 패턴을 나누었다.

 

행동 관련 패턴은 클래스와 객체들이 서로 효과적으로 상호작용하는 방법 및 역할을 분담하는 방법과 관련된 패턴이다. 구조 관련 패턴은 클래스 또는 객체들의 효과적인 구성을 통해서 객체지향 효과를 극대화하는 패턴이다. 생성 관련 패턴은 객체 생성과 관련된 패턴이다.

 

  1. 행동 관련 패턴(Behavioral Patterns)
    1. 스트라테지 패턴(Strategy)

1. 모든 기술에는 기술의 뿌리가 되고 기본이 되는 기술이 있다. 기마자세와 정권치기는 무술의 기본이 되는 기술이다. 크롤킥은 수영의 기본이 되는 기술이다. 달리기는 모든 운동의 기본이 되는 기술이다. 일기쓰기는 모든 글쓰기의 기본이 되는 기술이다. 푸시업은 모든 근력운동의 기본이 되는 기술이다. 돈과 외모는 모든 연애생활의 기본이 되는 능력이다. 등의 뿌리가 되고 기본이 되는 기술이 존재한다.

 

스트라테지 패턴은 바람직한 객체지향 개발을 위한 객체지향 설계자의 힘겨운 노력의 출발이자 디자인패턴의 출발이 되는 패턴이다.

 

책의 처음에 객체지향과 그 요소들을 숲과 나무에 비유 했다. 객체는 나무이고 애플리케이션은 숲이다. 속성은 줄기와 같고, 메소드는 잎이나 꽃과 같다. 상속과 폴리모피즘이 태양처럼 숲과 나무의 성장에 필요한 가장 근본적이고 자연스러운 에너지라면, 상속과 구성은 인간의 인위적인 노력과 같다. 숲과 나무는 알아서 성장하지만, 무서운 자연재해 앞에 그 성장이 더디기도 하다. 상속과 구성은 이런 자연재해로부터 숲과 나무를 보호하는 인간의 인위적인 노력과 같다. 라고 설명했다.

 

나무와 숲은 보통 자연의 위대한 힘에 의해 저절로 성장하지만, 때로는 산불의 위험과 가뭄의 위험과 해충의 위험(=잘못된 코딩)에 대비하여 사람의 '지속적인 보살핌'이 요구된다.

 

'지속적인 보살핌'의 출발점이 바로 전형적인 '상속과 폴리모피즘' 구조를 '위임, 구성, 집합'의 구조로 개선하는 노력이다. 관리자가 생각을 깊게하여 인위적으로 변경하는 주도적인 노력이다. '위임, 구성, 집합'으로의 구조 변경 노력은 주로 관리자의 사려깊음과 보살핌의 정도에 따라 결정된다.

 

'위임, 구성, 집합'은 사람의 인위적인 보살핌의 출발과 기본이 되는 기술로서 중요하다. 좀더 나아가면 복잡다단하게 발생하는 다양한 상황과 위험에 대비한 높은 수준의 객체지향 기법을, 객체지향 선각자들이 나무와 숲을 위해 개발해왔다.

 

디자인패턴과 리팩토링이 숲과 나무를 울창하게 뽐내게 도와주는 고수준의 기술이자 핵심기술이며, 그 출발에는 '위임, 구성, 집합'등의 기본적인 기술이 자리잡고 있다. 이와 비슷한 디자인패턴의 출발이 바로 스트라테지 패턴이다.

 

2. 10년 전, 레이져 광선검 같은 태양빛이 내무실을 관통한다. 나는 땀을 뻘뻘 흘리며 칙칙하게 삭은 군장에 짐을 싸고 있었다. 오늘은 훈련중에서도 제일 힘들다는 23 완전군장 산악행군을 하는 날이다. 그동안 온갖 훈련을 고통 속에 잘견뎌 왔지만 오늘도 두렵다. 나는 마칠 것이다. 사실은 긍정의 자기 암시까지도 무력했다.

 

모두가 똑같은 철모를 쓰고, 똑같이 칙칙하게 삭은 군장을 등에 매고, 똑같이 두터운 군복을 입었는데 더구나 풀독 오를까봐 소매는 반팔로 접지 못하고 길게 폈다. 똑같이 딱딱한 군화를 신고 행군을 시작한다.

 

절벽같은 산길을 몇시간째 오르는 이곳은 지옥이다. 태양에 달궈지는 철모에 갇힌 내 머리가 삶은 계란이 되어 폭발하기 직전이다. 아무리 꽉매어도 헐렁하게 밀착된 군장덕분에 어깨는 빠지기 직전이다. 군복은 두꺼운데다 땀도 흡수하지 못해서 군복에 갇힌 내 몸으로 땀이 줄줄 밑으로 흐르니 찐득거려서 불쾌감의 극치에 욕이 저절로 나온다. 군화에 비누칠도 하고 별짓다해봤지만 뒤꿈치가 시리고 발가락이 따끔 다끔 거리니 그 고통과 불쾌함에 땀과 눈물이 섞인 것 같다.

 

3.10년 후 어느날, 도봉산에 갔다. 최근에 구입한 배낭은 3개의 멜빵끈이 배낭과 몸을 단단히 묶어 주며 인체공학적인 설계로 등과 허리에 감기게 만들어져 있다. 모자는 일반 모자와 챙이 둥그런 햇모자가 있었는데 오늘은 햇볕이 쨍쨍하다고 하니 햇빛을 가려주는 햇모자를 쓰기로 했다. 등산복은 땀을 배출해주는 소재의 옷을 입기로 했다. 등산화는 발을 착착 감기게 움직이게 해주면서 고어텍스 기능까지 있는 신발을 신기로 했다. 또한 알파인 스틱은 산을 오를때의 충격을 분산시켜 무릎을 보호해줄 것이다.

 

산을 탈때는 언제나 사서 고생이다. 산을 올라갈때 언제나 나는 헉헉~거리면서 심폐의 고통을 감수하고, 허벅지와 무릎과 종아리에 전해지는 복잡미묘한 신경의 자극을 견디며, 땀은 내몸 구석구석에서 진득거리며 불쾌감 담은 열기를 전한다.

 

그래도 가벼운 햇모자는 햇빛으로부터 몸을 보호하며 이마의 땀도 흡수한다. 등산복은 땀같은 습기를 최대한 밖으로 배출한다. 배낭은 맨듯 안맨듯 몸에 달라붙어 자신의 존재를 최대한 숨긴다. 무엇보다 등산화는 가볍고 발에 달라붙은 편안함과 무쇠같은 튼튼함으로 발을 지켜준다. 그래서 견딜만하게 산을 타고 정상에 올라가서 시원한 물을 마시며 시원한 바람을 맞고 시원하게 펼쳐지는 광경을 지켜보며 기쁨을 마음껏 즐긴다.

 

4. 10년전 산악행군 하던 나는 산악 장비가 정해져 있다. 머리를 삶은계란으로 만들어버리는 철모, 두터운 군복, 무겁고 삭은냄새 나는 군장, 말이 필요없는 군화 이런 것들만 선택할 있다는 것은 마치 짜여지지 않은 객체 프로그램 같다.

 

[군산악장비 클래스 하나]

 

등산하려는 사람 클라이언트는 군산악장비라는 클래스에 의존되어 있다. 군산악장비에서 리턴해주는 기능들만 사용하게 되어 있다. 만약 개발자가 좀더 머리를 써서 다음과 같이 구현했다고 치자.

 

 

설계는 그래도 낫다. 산악장비 인터페이스와 군산악장비 구현 클래스가 분리되어 있어 만약 일반산악장비 클래스가 추가되었다면 사람 클라이언트는 일반, 산악장비중에 취사 선택을 있다.

 

그러나 설계는 실제 세상의 설계를 담지는 못했다. 사람 클라이언트가 모자면 모자, 등산복은 등산복, 등산화는 등산화, 배낭은 배낭 이렇게 새부적인 취사선택을 하지 못하기 때문이다.

 

실제 세상과 비슷한 설계인 도봉산 험한 길을 안전하고 편하게 오르는데 도움을 주었던 장비를 취사선택하는 설계는 다음과 비슷할 것이다.

 

 

산악장비 클래스는 생성할때, 등산모, 등산복 상의, 하의, 배낭, 스틱, 등산화 등의 인터페이스로부터 실제 구현 클래스를 취사 선택할 있다.

 

5. 군산악장비 클래스 하나에서 산악장비 인터페이스의 분리 그리고 스트라테지 패턴으로 진화하기까지 명의의 처방처럼 여러가지 디자인 원칙등이 처방되었다.

 

군산악장비 클래스 하나에서 산악장비 인터페이스가 분리되는 과정에서는 '구현이 아닌 인터페이스에 맞춰서 프로그래밍한다.' 라는 디자인원칙이 처방되었다. 디자인 원칙의 전형적인 사용방법은 위에서 설명했지만 다음과 같다.

 

public class People {

 

    Cap cap = null;

 

    public People(Cap cap) {

        this.cap = cap;

    }

 

    public int coolingStat() {

        return cap.getCoolingEffect();

    }

}

[클라이언트(사람 클래스), Cap 모자 클래스를 인자로 받는다. Cap 모자와 같은 인터페이스를 가진 여러 상속 클래스가 존재한다.]

 

public interface Cap {

 

    public int getCoolingEffect();

}

[모자 인터페이스]

 

public class ChengCap implements Cap {

    @Override

    public int getCoolingEffect() {

        // TODO Auto-generated method stub

        return 50;

    }

}

[ 모자 클래스]

 

public class HatCap implements Cap {

    @Override

    public int getCoolingEffect() {

        // TODO Auto-generated method stub

        return 100;

    }

}

[ 모자 클래스]

 

public class MainLauncher {

 

    public static void main(String[] args) {

        People people = new People(new ChengCap());

        int peopleCoolStat = people.coolingStat();

        System.out.println("peopleCoolStat ["+peopleCoolStat+"]");

    }

 

}

[실행 클래스, 챙모자 클래스를 인자로 넘겼기 때문에 50 쿨링~ 효과를 본다.]

 

클라이언트 객체는 산악장비 인터페이스 객체에만 의존되어 있는 상태이다. '런쳐'클래스가 클라이언트 객체를 선언할때 인자로 산악장비 인터페이스 객체를 구현한 클래스를 넘긴다. 이렇게 하면 클라이언트 객체는 산악장비 인터페이스만 의존해도 여러 산악장비 구현 클래스를 활용하기 때문에 확장성이 높고, 하나의 인터페이스/클래스에만 의존했기 때문에 결합도가 낮아진다. 만약 구현 클래스를 직접 의존했으면 클라이언트 객체는 컴파일될때 의존한 구현 클래스만 사용할수 밖에 없다. 하지만 인터페이스에 의존하고 구현클래스를 인자로 받으면 실행시에 얼마든지 다양한 구현 클래스를 활용하게 된다. 이것은 전형적인 상속과 폴리모피즘 효과이다.

 

산악장비 인터페이스가 분리되는 과정은 사람 클라이언트가 모자면 모자, 등산복은 등산복, 등산화는 등산화, 배낭은 배낭 이렇게 새부적인 취사선택을 하지 못하는 문제가 있다. 이때는 '애플리케이션의 달라지는 부분을 찾아내고, 달라내지 않은 부분으로부터 분리시킨다.' 디자인 원칙이 처방되었다. '바뀌는 부분은 따로 뽑아서 캡슐화시킨다.' 같은 뜻이다.

 

그렇게 하면 나중에 바뀌지 않은 부분은 간섭하지 않으면서 캡슐화한 부분만 고치거나 확장할수 있다. 여기서 쓰인 캡슐화의 개념은 속성의 은닉의 개념이 아니고, 객체에 주어진 기능중에 일부를 나머지 부분으로 분리하여 다른 객체 패밀리안으로 감싸는 의미의 캡슐화란 뜻이 사용 되었다.

 

런쳐코드에서 먼저 산악장비 인터페이스를 구현한 클래스를 선택하여 생성한다. 이때 등산모, 등산화, 등산복 상의. 등의 구성으로 연결된 클래스도 선택하여 생성한다. 산악장비 클래스를 클라이언트 객체에 넘겨준다. 이렇게 하면 좀더 유연하고 확장하기 쉬우며 실세계와 비슷한 어플리케이션을 구현할 있다.

 

변하는 모든 것을 캡슐화하여 변하는 것을 자유롭게 교환하여 사용할 있는 디자인을 위해. 상속과 폴리모피즘의 경직성의 문제를, '구성'구조로 개선하여 경직성을 풀어주는 디자인패턴 아이디어의 출발이자 전형적인 구성 구조을 갖는다.

 

 

[스트라테지 패턴 원본]

 

덧 ) 이 객체지향의 탄생 원고는 제가 책으로 내려다가 일단 잘 안되었는데요. 이유는 비문이 많다. 단락내 주제가 중복된다. 어떤 상황 설명을 과장한다.등 입니다. 그래도 원고를 일단 블로그에 몽땅 풀어보고 언젠가 제대로 교정해서 다시 도전할 생각입니다. 이점을 감안해서 읽고 객체지향을 이해하는데 도움이 되셨으면 좋겠습니다. 의견도 주셨으면 좋겠습니다. 원고 조금만 교정하면 괜찮을것 같은 출판사 관계자분의 피드백도 환영합니다. 특별한 일 없으면 매주 월수 발행 예정입니다.