내가 하는 일을 가치 있게 만드는 방법은 무엇일까?

정말 특별한 소수의 사람을 제외하고 삶이란 겉으로 보면 모두 다 똑같아 보인다. 누구나 다 반짝반짝 빛나는 삶을 꿈꾸지만 현실적으로 그런 사람은 드물고, 나는 남들보다 특별하게 살려고 노력하는 것 같은데 사실 겉에서 보면 다른 사람들과 똑같은 일을 하는 평범한 사람일 뿐이다.

이것은 어떤 관점에서는 너무나도 당연한 일이다. 내가 살고 있는 곳에서 조금씩 멀어져 보자. 조금씩 멀어지다 보면 점점 더 넓은 세상이 보인다. 더 넓은 세상을 바라보다 보면 사람들의 개성은 점점 희미해지고, 종교와 같이 사람들을 죽음의 갈등으로 몰아 넣는 것들도 시시해지고, 피부색은 보이지 않으며 이념은 자취를 감춘다. 지구에서 조금만 벗어나더라도 누군가가 거기에 무언가 있다고 말해주지 않는다면 찬란하게 빛나는 인류 문명조차 눈에 들어오지 않을 것이다.

그렇다면 내가 무슨 일을 하든 가치가 없다고 생각하고 사는 것이 바람직한 일일까? 내가 지금까지 겪어온 바를 바탕으로 생각해보면 모든 것을 의심해도 단 한가지 의심하지 말아야 할 것이 있다. 데카르트 같은 사람은 자기 존재에 대한 확신을 회의적인 철학적 사유로 풀어 냈지만, 내 경험상 자신의 존재를 의심하는 것은 사유적 금기이다. 그 이유는 그 의심이 어떠한 가치도 만들어 주지 못하기 때문이다. 그런 사유는 다른 사람들과 공유될 수도 없고, 이득이 될만한 무언가를 만들어 낼 수도 없다. 그리고 다른 사람에게 그것을 이야기 한들 들어줄 사람도 없다.

자기 존재에 대한 의심은 끊임 없는 자기 검증과도 같다. 어떤 기계가 자기가 해야 할 일은 하지 않고 계속 자기 자신이 정상인가를 확인한다고 하자. 그 기계는 과연 쓸모 있는 기계인가? 그리고 결국에는 자기가 정상이라는 것을 확인하고 다른 사람에게 그것을 알려준다고 해서 그 기계의 가치가 달라지는가? 기껏해야 그건 그냥 정상인 기계에 불과하다. 의심해야 할 것은 의심하되 의심하지 말하야 할 것은 관심도 두지 말아야 한다. 영국의 경험론은 "물의 깊이는 알 필요가 없다. 배를 띄울 수 있는지 없는지만 중요할 뿐이다"라는 생각에서 출발한다. 공자는 죽음 이후의 세계가 있는지를 묻는 제자에게 "사람이 사는 것에 대해서도 다 알지 못하는데 죽은 이후에 대해서 어찌 알겠는가"라고 말하면서 사후 세계에 대한 생각을 일축시켰다. 그래서 유교에는 사후 세계가 없다.

자, 다시 원래 질문으로 돌아가보자. 그럼 일단 내가 존재한다고 치고, 내가 하는 일을 가치 있게 만들어야 존재 가치도 있는게 아니겠는가? 그러면 내가 하는 일을 어떻게 가치 있게 만들 수 있는가? 아래 보기가 있다.


1. 열심히 한다.

2. 돈을 벌기 위해서 한다. 밥 벌어 먹기 위해서 한다.

3. 가족을 위해서 한다.

4. 회사를 위해서 한다.


눈치 챘겠지만 저 중에는 정답이 없다. 열심히 한다고 해서 가치 있어지는 일은 없다. 누가 부지런하고 성실한 사람이라고 자기를 소개한다면 충분히 의심해 볼만한 가치가 있다. 히틀러는 독실한 카톨릭 신자에 술과 담배를 하지 않았으며, 매우 성실한 사람이었다. 매우 성실하게 매일 같이 근력 운동을 하면 근육은 커지지 않는다. 마찬가지로 매일 같이 열심히 일을 하면 실력은 늘지 않는다. 근육은 쉴 때 커지고, 능력은 놀 때 자란다. 간단한 예로 내가 지금 이 시간에 회사에서 매일 같이 일을 하고 있다면 내가 쓴 블로그 글들은 한 개도 없을 것이며, 내가 블로그를 쓰면서 소프트웨어에 대한 개념들을 정리할 시간이 없었을 것이다. 수치로 계산해 볼 수는 없지만 내가 생각해낸 (내 생각에) 창의적인 발상이나 이해는 컴퓨터 앞에서 문제를 해결하기 위해서 열정을 불태우고 있을 때가 아니라 대부분 커피를 타러 갈 때와 화장실에 갔을 때, 자면서 꿈에 나타난 것들이다.

돈을 벌기 위해서 하는 것은 열심히 하는 것보다 낫다. 적어도 자기가 존재해야 가치가 있어지는 것이기 때문이다. 하지만 존재 하는 것만으로도 가치가 있는 것은 세상에 단 한가지도 없다.

가족을 위해서 일 하는 것. 일면 좋은 일일 수 있다. 분명한 목적이 있기 때문이다. 하지만 그 목적이 일을 가치 있게 만들어주지는 못한다. 내가 하는 일이 가치가 있으려면 실제로 가치를 만들어야 한다. 어느 누군가를 위해서 일하는 것은 숭고한 일일 수는 있어도 항상 가치 있는 일은 아니다. 일하는 스타일로 치면 겉은 번지르르 하지만 실속은 없는 일에 매달릴 수 있다. 일에 가치를 두지 않기 때문이다. 단지 일을 계속하거나 일에 대한 평판을 좋게 만드는데에만 신경을 쓸 수 있기 때문이다.

회사를 위해서 일하는 것. 말할 필요도 없이 가치 없는 짓이다.


사람들은 자기 일에 여러가지 방법으로 동기 부여를 한다. 자기 만족, 돈을 벌기 위해, 가족을 위해, 회사의 무궁한 발전을 위해 일한다고 생각할 수 있다. 실질적인 일의 내용이 바뀌지 않는데 그 일에 동기를 부여하는 것은 무가치에 가치를 부여하는 자기 기만이다. 즉, 속이는 것이다. 자기가 하는 일이 가치가 없어지는 때는 이 어설픈 속임수가 자기 스스로에게 들통났을 때이다. 열심히 일하고 있다고 자부하고 있다가 몸이 상해가는 것을 알게 된 순간 그 일은 가치가 없어진다. 스스로 속이는 일이 불가능해졌기 때문이다. 열심히 해서 가치가 있는 일로 만들어 보려 했지만 자기 스스로가 망가지는 것보다 가치 있지는 않다. 가족을 위해서 일하다 보니 회사와 동료들을 속여가면 자기가 하는 일을 포장하는 자기를 발견했을 때. 자기가 벌이던 사기 행각이 자기에게 발각되었을 때. 그 때처럼 자기가 하는 일이 가치 없음을 느끼게 되는 순간이 또 있을까?


자 그러면 어떻게 해야 내가 하는 일이 가치 있어 질까? 이것이 애초에 무가치에 가치를 부여하는 것, 즉 속임수라면 어설프게 속일 것이 아니라 제대로 속여야 한다. 한마디로 판을 키워야 하는 것이다. 그래야 자기 자신까지도 자기 일이 가치 있다고 믿을 수 있다. 자기 일을 가치 있게 만드는 방법은 자기가 자기 일을 바라보는 관점을 바꾸는 것 밖에 없다. 한마디로 영원히 자기를 속이는 것이다.

앞서서 시야를 넓혀 가면서 점점 내가 사는 곳과 멀어지는 것에 대한 이야기를 했었다. 이제 관점을 바꿔보자. 과거로 가보자. 까마득히 멀리 떠나서 약 7만년 전 쯤으로 가보자. 유발 하라리가 인지 혁명이 시작되었다고 하는 그 시점쯤 되겠다. 그 인지 혁명이 7만년전에 인류를 하나로 만들고 공통된 목적을 추구하며 보이지 않는 상상의 것들을 믿게 끔 만들었다고 해서 그들이 살던 삶이 그 순간 가치 있어진 것은 아니다. 그들은 여전히 원시인이었으며, 먹는 것, 자는 것, 생존 하는 것이 그들의 삶의 목표였다. 두뇌는 현대인들과 비슷했을지라도 그들의 삶은 매우 비 상식적이었을 것이다. 제레미 다이아몬드는 저서 "총, 균, 쇠"에서 지금도 파푸아 뉴기니의 서로 다른 부족 사람 둘이 만났을 때를 일어나는 일을 이야기 해주었다. 파푸아 뉴기니에서 다른 부족 사람들이 서로 만났을 경우 그들은 대부분 이웃 부족 사람들이다. 이웃 부족 사람들끼리는 서로 살인이 일어나기도 하고 혼인이 일어나기도 한다. 그리고 사냥을 나갔기 때문에 둘은 무기를 가지고 있다. 이들은 서로를 인지하면 조심스럽게 상대에게 다가간다. 그리고 위협이 없다고 생각하면 나무 아래에 나란히 앉는다. 그리고 서로 자기 가계도에 대해서 이야기 하기 시작한다. 둘이 서로 인척관계가 있는지, 서로 알고 친하게 지내는 사람들이 있는지를 확인하기 위해서다. 그리고 그 확인이 필요한 이유는 서로 죽이지 않아야 할 이유를 찾기 위해서다. 이러한 일이 7만년 전에는 없었을까? 지금의 우리가 낯선 이들에게 얼마나 호의적으로 대하는지를 생각해 본다면 답은 상당히 뻔할 것이다. 그리고 지금처럼 완성된 언어가 있고, 사회적으로 서로 잘 엮여 있어서 일말의 대화가 통하는 상대라면 모르겠지만 사냥을 위해 떠돌아 다니는 두 집단이 서로 같은 언어로 소통할 수 있을 것이라는 기대는 상당히 하기 어려운 일이다. 그리고 이들도 당연히 사냥을 나온 것이기 때문에 무장을 단단히 하고 있다. 이들이 서로 만났을 때 어떤 일이 벌어졌을지는 여러분들의 상상에 맡기도록 하겠다.

그럼 이제 현대로 돌아와 보자. 여러분이 방금 전까지 상상했던 일들과 현대 지금 시대를 살고 있는 우리들이 어떤 차이가 있을까? 두뇌가 7만년 사이에 개벽하듯 변화했을 것이라는 생각은 들지 않는다. 차이가 있다면 크게 말해서 문명 그 자체에 있다. 현재의 인류가 벌이는 행태에 분개하면서 문명을 저주하고 싶은 생각이 들 수도 있다. 그리고 최근까지 벌어졌던 수많은 전쟁과 인종학살, 혐오범죄, 차별들을 떠올리면서 인류는 7만년 전과 전혀 달라진게 없다고 믿고 싶을 수도 있다.

하지만 딱 한가지 사실만 이야기 해보겠다. 지금의 시대는 인류의 어느 시대에 비해서도 폭력이 가장 적은 시대이다. 인정하기 싫을지 모르지만 인류는 7만년 동안 서서히 나아지고 있었다. 그리고 이것이 추세라면 앞으로는 더 나아질 것이다. 물론 굴곡이 있고, 어느 순간 상상하지도 못할 엄청난 일이 발생해서 여태껏 쌓아 왔던 수많은 업적들이 대부분 사라져 버릴 수도 있다. 그러나 역사에는 언제나 전쟁과 살인이 있었듯이 항상 그 사이 사이에는 찬란한 문명들이 존재했다. 황금기의 로마, 페르시아의 다리우스 시대, 그리스의 황금기인 페리클래스 시대, 그리고 미처 열거하지는 못했지만 어느 왕조, 어느 나라, 어느 문명에서도 황금기가 있었다. 이것은 7만년전을 기준으로 보면 매우 기형적인 일이다. 과연 인류에게 평화를 사랑하는 마음이 있는가 싶은 시대에 살고 있으면서도 돌아보면 지금이 그래도 낫다는 아이러니 같은 존재가 인류이다.

현대의 인류가 가지고 있는 문제가 작은 것은 아니라는 점은 인정하겠다. 하지만 인류가 자기보다 높은 계급의 사람들에게 목숨을 내놓고 살아가는 것이 당연한 시대에서 자유와 평등의 사상을 기반으로 어느 누구에게도 충성을 맹세할 필요가 없는 (이론적으로는) 세상에 있는 것만으로도 인류의 지성은 크나큰 발전을 한 것이다. 적어도 이 자유와 평등의 사상 만큼은 인류 역사상 어느 시대에도 이렇게 보편적으로 적용된 경우가 없었다. 만약 7만년 전보다 지금이 어떤 면에서건 조금이라도 나아진 것이 있다고 믿는다면, 이제 자기를 속여 볼 시간이다.

스스로에게 이렇게 이야기 해보자. 내가 하는 일은 인류 전체에게 아무리 작으나마 기여를 하는 일이라고. 소프트웨어 개발자라면 (나도 실제로는 하고 있지 못하지만) 오픈 소스에 기웃 거려 보자. 오픈소스를 다운 받고, 분석해보고, 거기에 조금이라도 기능을 추가해본다면 이미 인류에 기여한 것이다. 나는 아직 그럴만한 능력이 안되서 시도를 못하고 있는 일이지만 지금은 블로그라도 써서 올리면서 지식을 공유해 보려고 노력하고 있다. 이미 발전을 해왔고, 앞으로도 발전할 가능성이 있는 인류에 기대하는 바가 있고, 그 인류가 하는 일에 내가 조금이라도 보탬이 되는것이 내가 나를 충분히 속일 수 있는 일이 아닐까? 내가 하는 일하고 오픈 소스에 기여하는 것은 다른가? 그러면 이렇게 생각해보자. 내가 하는 일로 실력이 늘고, 늘어난 실력이 오픈 소스에 기여하는데 도움이 된다면, 내가 하는 일이 인류에 기여하는 가치 있는 일이 되지 않는가?


자 이제 자신을 속이는 방법을 좀 더 단순한 단계로 정리해 보겠다.

1. 인류는 발전해 왔다.

2. 내가 (특정한 사람이 아닌) 보편적인 사람에게 작은 일이라도 기여하면 내 일은 가치 있는 일이다.

3. 그러면 인류는 더 발전할 것이다.


사실 내가 하는 일을 가치 있게 만드는 방법은 1번에서 시작한다. 역사를 이해하는 것이 시작이다. 단순히 믿는 것과 어떤 식으로든 확인해가면서 확신을 쌓아가면서 믿게 되는 것은 엄연히 다른 일이다. 따라서 끊임 없이 과거를 공부해야 한다. 과거 인류에게 있었던 어떤 일들이 지금 현대를 살아가는 우리들에게 어떤 영향을 미치고 있는지를 알게 되는 것. 그것이 인류가 발전해 왔다는 것을 믿게 하는 원동력이다. 그리고 이를 통해 나 스스로에게 인류라는 가치 있는 존재에게 기여하도록 하는 것이 스스로를 가치 있게 만드는 일이다. 

인정할 것은 인정하겠다. 이것은 믿음일 뿐이다. 믿음은 잘 알았을 때보다 잘 속았을 때 더 잘 생겨난다. 하지만 알고 있는지 모르겠다. "진리"라는 것은 "보편되게 믿어지는 사실"이라는 것을. 그 대단한 진리라는 것 조차 정의를 살펴보면 일개 믿음일 뿐이다. 그리고 어차피 믿음이 속는 것이라면 적어도 더 가치 있어 보이는 것에 속아 주어야 한다. 대충 "인류" 정도 되면 나 조차도 깜빡 속일 수 있지 않을까?

Posted by 이세영2
,

Mediator 패턴

5.디자인패턴 2016. 9. 18. 21:46

시스템을 설계하다 보면 이벤트가 발생하는 객체가 여러개(M)이고, 이들 이벤트를 받는 곳도 여러 곳(N)인 경우가 있다. 이런 경우에 모든 이벤트들을 주고 받기 위해서는 M : N의 관계가 생기게 된다. 이렇게 되면 전체 시스템이 복잡해지는 것은 당연하다. Mediator(중재자) 패턴은 이런 다 대 다 관계에 중간 객체를 도입하여 각각 일 대 다 관계를 만들어 주는 패턴이다.

우선 객체들 간의 관계가 아래와 같다고 하자.

각 이벤트 소스들은 모두 이벤트 수신자에게 이벤트를 보내 주어야 한다. 소스나 수신자의 개수가 1~2개 정도 일 경우에는 크게 문제가 없겠지만 그 개수가 늘어나게 되면 위와 같이 복잡한 관계가 만들어지게 된다. 이것은 모든 소스가 각각 모든 수신자들을 알고 있어야 하고, 자신이 알고 있는 모든 수신자에게 이벤트를 전달해 주기 때문이다. 이를 단순화 하기 위해서는 각 소스들은 각각 이벤트가 발생했다는 사실만 별도의 객체에 알려 주고, 이벤트 수신자에게 이벤트를 보내는 역할은 그 객체가 담당하도록 만들면 된다. 이것이 Mediator(중재자) 패턴이다.

위의 객체들 간의 관계를 중재자를 통해 단순화 하면 다음과 같다.

이처럼 소스와 수신자 간의 복잡한 관계를 단순화 시켜줄 수 있다.


Mediator 패턴 클래스 다이어그램


복잡한 관계를 단순화 하기 위해서는 소스와 수신자를 동일화 시킬 필요가 있다. 소스 측은 ISource 인터페이스를 통해서 구현하도록 만들고, 수신자 측은 IDestination 인터페이스를 구현하도록 한다. 그리고 소스 측 구체 클래스인 TcpComm과 SystemSignal을 만들어 주고, 수신자 측 구체 클래스는 Display와 Log를 각각 만들어 준다. 더 많은 소스와 수신자가 있을 때 Mediator가 더 유용해지지만, 복잡함을 피하기 위해서 각각 둘 씩 만 구현했다.

소스는 setMediator() 메소드를 통해서 외부로부터 Mediator 객체를 주입 받는다. 그리고 이벤트가 발생하면 Mediator 객체의 onEvent() 메소드를 호출하여 자신에게 발생한 이벤트를 전달해 주도록 한다. IDestination을 구현한 수신자 객체들은 생성된 후 Mediator 객체에 자신을 등록 시킨다. 이를 통해 Mediator 객체가 이벤트 발생 시 이벤트를 전달 받을 수신자들을 알 수 있게 된다.

아래는 Mediator 패턴의 구현이다.


Mediator 패턴의 구현

interface ISource{

    public void setMediator(Mediator mediator);

    public void eventOccured(String event);

}

class TcpComm implements ISource{

    Mediator mediator;

    public void setMediator(Mediator mediator){ // 중재자 설정

        this.mediator = mediator;

    }

   

    public void eventOccured(String event){ // 이벤트의 전달

        mediator.onEvent("TCP comm", event);

    }

}

class SystemSignal implements ISource{

    Mediator mediator;

    public void setMediator(Mediator mediator){ // 중재자 설정

        this.mediator = mediator;

    }

   

    public void eventOccured(String event){ // 이벤트의 전달

        mediator.onEvent("System", event);

    }

}

interface IDestination{

    public void receiveEvent(String from, String event);

}

class Display implements IDestination{

    public void receiveEvent(String from, String event){

        System.out.println("Display : from " + from + " event : " + event);

    }

}

class Log implements IDestination{

    public void receiveEvent(String from, String event){

        System.out.println("Log : from " + from + " event : " + event);

    }

}

class Mediator{

    List<IDestination> list = new ArrayList<IDestination>();

    public void addDestination(IDestination destination){ list.add(destination); }

   

    public void onEvent(String from, String event){

        for(IDestination each : list){ // 이벤트의 전송

            each.receiveEvent(from, event);

        }

    }

}


실행 방법

public static void main(String[] args) {

    Mediator mediator = new Mediator();

    ISource tcp = new TcpComm();

    tcp.setMediator(mediator);

    ISource system = new SystemSignal();

    system.setMediator(mediator);

    mediator.addDestination(new Display());

    mediator.addDestination(new Log());

    tcp.eventOccured("connected");

    tcp.eventOccured("disconnected");

    system.eventOccured("key input");

    system.eventOccured("mouse input");

} 

main() 메소드에서는 Mediator와 소스, 그리고 수신자를 생성하고, 각각의 관계를 설정해 준다. 이벤트는 소스에서 생성되어 중재자를 거쳐 수신자 쪽으로 흘러 가게 된다. 실행을 시켜 보면 어떤 소스로부터 이벤트가 발생하더라도 수신자들 모두에게 잘 전달됨을 알 수가 있다.

'5.디자인패턴' 카테고리의 다른 글

Actor Model 패턴의 구현(Java)  (0) 2016.09.30
Property List 패턴  (0) 2016.09.24
Facade 패턴  (0) 2016.09.18
Command 패턴  (0) 2016.09.18
Flyweight 패턴  (0) 2016.09.18
Posted by 이세영2
,

Facade 패턴

5.디자인패턴 2016. 9. 18. 15:12

Facade 패턴은 사용하기에 복잡한 라이브러리에 대한 간편한 인터페이스를 제공하거나 어떤 목적의 동작인지 이해하기 어려운 일련의 작업들에 대한 적절한 네이밍을 통해 사용자로 하여금 그 의미를 쉽게 이해 할 수 있는 인터페이스를 제공하기 위한 패턴이다.

Facade라는 단어의 의미는 잘 지어진 건축물의 정면을 의미한다. 건축물의 정면은 보통 건축물의 이미지와 건축 의도를 나타내기 때문에 오래 전부터 특별한 디자인을 적용하여 의미를 부여했다. 이와 마찬가지로 자칫 동작의 목적과 같은 중요한 사항을 놓치기 쉬운 경우, 이해하기 쉬운 인터페이스를 제공해주면 동작에 대한 이해도가 높아질 수 있다.


Facade 패턴의 클래스 다이어그램

Facade 패턴은 다른 패턴들처럼 일정한 구조를 가지고 있는 것이 아니다. 따라서 구현의 예는 매우 다양할 수 있는데 여기서는 자동차(Car)와 자동차에 대한 Facade(CarFacade)를 통해 Facade 패턴을 살펴 보기로 한다.


Facade 패턴의 구현

class CarFacade{

    Car car;

    public CarFacade(Car car){

        this.car = car;

    }

   

    public void drive(){

        car.enginStart();

        car.doorLock();

        car.wheelsRoll();

    }

   

    public void stop(){

        car.enginStop();

        car.doorUnlock();

        car.wheelsStop();

    }

      

    public void park(){

        car.enginStop();

        car.doorLock();

        car.wheelsStop();

    }

}

class Car{

    public void enginStop(){ System.out.println("engine stop"); }

    public void enginStart(){ System.out.println("engine start"); }

    public void doorLock(){ System.out.println("door locked"); }

    public void doorUnlock(){ System.out.println("door unlocked"); }

    public void wheelsRoll(){ System.out.println("wheels roll"); }

    public void wheelsStop(){ System.out.println("wheels stop"); }

}

Car의 경우 부품인 엔진, 문, 바퀴 등의 동작에 대해 구현되어 있다고 하자. 이들 기능은 자동차의 동작에 매우 중요한 부분이긴 하지만, 일반적인 운전자 또는 자동차의 상태를 쉽게 조작하고자 하는 사람들에게는 각 부품을 일일이 조작하기는 힘들다. 따라서 CarFacade 클래스를 통해서 사용자가 이해하기 쉽게 자동차의 상태를 변경할 수 있도록 한다. 예를 들어 일반적인 운전자는 자동차를 운전(drive) 정지(stop) 주차(park)와 같은 형태로 차의 상태를 조작하기를 윈한다. 따라서 CarFacade가 drive / stop / park와 같은 Facade 메소드를 제공하여 주면 자동차를 한결 쉽게 운전할 수 있게 될 것이다.


사용 방법

public static void main(String[] args) {

    CarFacade facade = new CarFacade(new Car());

    facade.drive();

    facade.stop();

    facade.park();

}


'5.디자인패턴' 카테고리의 다른 글

Property List 패턴  (0) 2016.09.24
Mediator 패턴  (0) 2016.09.18
Command 패턴  (0) 2016.09.18
Flyweight 패턴  (0) 2016.09.18
Chain Of Responsibility 패턴  (0) 2016.09.17
Posted by 이세영2
,