Rapid developement와 Management를 생각한다면 자바가 뜰 수 밖에 없죠..에 이은 글입니다. (이하 반말.)
——————–
자바가 대세라고 이야기 될 수 없는 점에대해서는 앞서 글에서도 이야기했지만, 자바가 (언어적 특성을 제외한 프레임워크/플랫폼 측면) 표준이 매우 중요한언어이다보니 아직 갖추어지지 않은 ‘관리를 위한 특징’의 표준부재가 큰 문제가 된다는 것이다. 관리에 능한 언어라면 얼핏 생각하기에 동적 클래스로딩정도가 될텐데, 그렇다고 현재 MS 플랫폼의 솔루션들이 뭔가 새로이 할때마다 서버를 완전히 셧다운 했다가 새로 올려야하는 상황도 아닌 것으로 안다. 따라서 동적 클래스로딩의 특징은 별다른 장점이 될리 없다고 생각하고, 표준 관리 API가 부재중인데 관리가 뛰어날리가 없다고 생각한다.
두번째로 객체지향의 언어의 측면에서 자바는 분명히 훌륭한 한 획을 그었지만 (그렇지 않다면 이렇게 모든 사람을 괴롭히는 언어가 됐을리 없으니까), 자바는 객체지향 언어가 갖고있는 태생적 한계를 완전히 해결하지는 못했다. 자바가 C++을 단순화한 객체지향적 언어라는 점에서도 훌륭하지만, 그 외에도 언어에 쓰레드에 대한 특징을 포함시킨 언어라는 점에서 역시 칭찬받는다. 하지만, 자바가 가진 쓰레드의 특징의 발전은 무척 많이 지체되어있고, 심지어는 concurrent pascal이상을 넘지 못한다. 프로그래밍언어론 서적에서 concurrent pascal의 소스코드를 보다보면 놀랄정도이다. 자바는 그 환경의 약간 세련화정도이다.
하지만 C#은 언어적으로는 자바와 대동소이하다. 심지어는 약 2일이면 문법을 끝낼 수 있다. 자바도 C++을 알고 있다면 마찬가지다. 하지만 그 프레임워크가 갖고있는 특징을 이해하는게 문제일 것이다. C#이 갖고 있는 다양한 쓰레드 클래스 라이브러리를 보다보면, 왜 이런것이 자바에 없는지 한스럽다. 쓰레드풀과 같은 기본적 개발 라이브러리를 비롯해서 이벤트(아마 taming java thread에서 set이라던가 하는 이름으로 구현한 클래스에 해당)를 위한 클래스들역시 골고루 구비되어있다.
거기에 한술 더 떠서 닷넷 환경에서 논의되는 Polyphonic C#라는 것이 있다. (이 괴상한 이름이 생각 안나서 구글을 찾아헤멨다.) 다 보자면 복잡하고 아직 당장 갖다가 써야하는 것도 아니니 링크를 열면 나오는 첫번째 화면의 설명만 갖고 이야기하자.
다음코드가 buffer의 구현이다.
public class Buffer { public String get() & public async put(String s) { return s; } }
이런 식의 쓰레드 동기화 문제를 예전에 상상이나 해볼 수 있었을까?
내가 말하고자하는 ‘문제의 단순화를 통한 빠른 개발’이란 이런 식의 패러다임 이동을 뜻한다. (그리고 이것이 나를 자바에 능숙한 개발자이면서 C#에 열광하게 만든다. 만약 이글을 읽는 누군가가 RTFM이란 말을 사랑하는 오픈소스 only 개발자라면 MS의 이런 측면들을 보라. 당신도 곧 광분하게 될 것이다. 이런 세상을 몰랐다고 말이다.) 오래전에 시작되어 지금은 정제단계에 이르른 객체지향을 가지고 그것이 최고라고 말하면 나는 사실 재미가 없다. 아무런 자극이 없다. 그런 것들은 누군가가 다 연구한 것이고, 내가 말하는 지식이란 것도 남들이 다 밝혀놓고 정리한 것을 체계화하고 내것으로 습득한뒤 나의 언어로 말하는 것일 뿐이지 학문적 자극은 없지 않은가 하는 의미이다.
쓰레드란 굉장히 특징적인 이슈를 가지고 왜 이렇게 쓸데없이 자바라는 언어나 객체지향적 환경을 논의할지 궁금할 것이다. 그 이유는 우리가 사용하는 컴퓨터가 폰노이만형 컴퓨터라는데 있다. 알다시피 폰노이만형 컴퓨터는 데이터와 명령이 하나의 메모리에 들어있고 그것을 연산기 등으로 처리하여 다시 메모리로 돌려보내는 구조이다. 이것은 상당히 매력적인 구조이고, 현대에서는 상식적 컴퓨터의 기본 모델이다. 하지만 문제는 이러한 컴퓨터의 구조에 의해 우리가 사용하는 언어가 imperative language일색이 되었단 것이다. fetch->decode->execute의 순서를 반복하는 이 모델은 루프문과 변수할당 분기와 같은 기본적인 struct의 실행을 빠르게 해주었으나, 반면 고수준 언어에서 할당과 반복, 분기가 전부인 것처럼 보이게 만들었다. 이것이 모든 컴퓨터 언어서적에서 모두가 똑같이 분기문, 변수형과 같은 이야기를 늘어놓는 이유이다.
그리고 imperative langauge 군에 속하는 객체지향역이 이 환경을 벗어날 수 없다. 따라서 객체지향적 언어 역시 내부적으로 구조적 패러다임, 그리고 그 내부에는 절차적 패러다임을 포함하며 결과적으로 “문제를 풀기 위해 해야하는 일은 같다.”
따라서 문제를 어떤식으로 추상화했던지간에 해야하는 일은 같다. 물론 객체지향적 패러다임에 입각하여 공통분모를 뽑아내고 더욱 추상화시킨다는 것은 반복개발을 줄여준다. 하지만 “하는 일은 똑같다.”
그리고 그 일이란 측면을 자세히 들여다보면 결국 폰노이만 구조의 한계에서 나오는 분기, 할당, 제어문이다. 이것 뿐만이라면 별 문제가 없겠지만, 어떤 문제를 동시적으로 처리해야하는 상황에 도달하면 복잡하고 난해한 쓰레드의 세계에 도착한다. 이 세계에서의 에러는 재생불가능(irreproducible)하며, 심지어는 예측불가능하다. C#이 뛰어난 점은 이런 문제들을 풀어내려 하고 있단 점이며 자바가 내가 보기에 그냥 그런 이유는 이런 문제들을 언어차원에서 풀어내는데 굉장히 원시적인 construct만 제공한다는데 있다. (물론 다 상대적으로 이렇게 된 것이지만.)
언어간의 비교가 아닌, 패러다임 측면에서 보자면 “객체지향 언어가 대세이다”라고 말하는 것만큼 “우리의 종착역은 functional language 이다”라고 말하는 것도 상식으로 통한다. 함수형 언어가 가진 장점은 모듈화에 대한 강력한 권고에 있다. 하지만 보다 중요한 점은 함수형 언어는 모든 일을 함수에 대한 입력과 결과로보며, 따라서 우리를 메모리에 대한 값의 할당에서 해방시킨다. 또한, 함수에 대한 동시적 처리를 언어와 플랫폼에서 알아서 해결하게 만듦으로써 우리를 동시성 제어의 문제와 효율성 극대화를 위한 쓰레드풀과 같은 것들로 부터 해방시킨다.
물론 함수형 언어는 재귀적 특성으로 인한 한계가 있고, 심지어 여러가지 처방을 써도 그 성능이 나아지지 않고 있다. 하지만, 여전히 그래도 갈길은 함수형언어라고 생각한다. 객체지향적 언어는 인간이 사고하는 방식을 그다지 닮지 않았으며, 객체지향이 모델링한다는 그 실세계는 대부분의 경우 온데간데 없고 단지 숙련된 개발자의 능숙한 감각에 의해 인터페이스와 추상클래스 등이 찾아질 뿐이다.
또한 객체지향의 패배는 동시성제어나 변수, 그리고 인간과 다른 사고방식으로 문제를 풀어야하는데만 있지는 않다. 객체지향의 정말 문제는 그것이 상속을 지원하기 시작했다는데 있다. 최근에는 그나마 나아졌으나, 여전히 많은 사람들이 상속을 어려운 것으로 생각하고 있으며, 단지 몇단계의 의미없는 상속을 하거나 아니면 하지 않는다. 무엇이 문제인가? 이해하기 어려운 이 객체지향적 언어의 “장점”이 진정한 “장점”이라고 말할 수 있을까?
더욱 아이러니한 점은 GOF의 디자인 패턴에서도 드러나듯이, 상속은 서서히 사라지고 aggregation이나 delegation으로 문제를 풀어가고 있다는 점이다. chain of responsibility, strategy와 같은 패턴들. 이것들은 모두 “상속을 하지말고 내부 변수에 할당해서 써라”는 메시지에 다름아니다. 물론 완전히 활용도를 부정하지는 않는다. 다형성은 상당한 가치가 있고, 다형성은 상속없이는 불가능하니. 다만 상속은 여러모로 기대에는 미치지 않았다.
요즘은 상속보다는 컴포넌트나 서비스 기반 아키텍처(이하 SOA)를 생각해봐야한다.
컴포넌트와 SOA에서 대체 객체는 어디에 갔는가? 사실 컴포넌트나 서비스라는 말이 성립하려면 그것이 어떤 언어이든지 어떤 패러다임이던지 상관할 필요가 없다. 단지 인터페이스만을 사용해 통신할 뿐이며 내부의 구조에는 무관심하겠다는 것이다. 만들어진 빌딩블록은 바이너리 수준에서 호환가능하고 이것들을 갖다다가 그냥 붙여서 바로 쓰겠단 것이다.
그런데 정말 대세가 “객체지향”일까. 대세가 객체지향인 시점은 지나갔다. 평범한 개발자나 코더로 남겠다면 객체지향은 아직도 대세이다. 하지만, 대세를 컴퓨터 과학도가 논한다면 적어도 이런 측면에서 바라봐야한다고 생각한다. 또한 기계에게 알맞는 코딩방식에서 벗어나 정말 인간의 측면에서 문제를 해결하고 문제의 복잡도를 낮추는 functional language와 logic programming에 기대를 걸게되는 것은 피할 수 없으며, 그것들이 내게는 매력있는 대세이며, 언젠가는 빠른 개발이나 패러다임 쉬프트나 대세라는 말에 걸맞는 현실적인 환경이 될 것이다.
그땐 정말 지금보다는 언어가지고는 덜 투덜거리겠다.
p.s. 이 글은 단지 현재에 존재하는 패러다임이나 객체지향 언어에대해서만 바라본 것이다. 실제 소프트웨어의 본질은 인간에 있다고 생각한다. 그리고 그 ‘인간의 본질’을 다루는 측면에서는 이전글에 복연군이 코멘트한 내용이 좋아서 다시 인용한다.
[quote]
너의 글을 보면 왠지 만능인 무언가가 나오지 않으면 ‘그것만으론 모든 문제를 해결할 수 없다’고 주장할 것만 같아. 객체 지향이건 표준적인 프로파일링이건, 동적 관리 기법이건 보다 효율적인 개발을 위한 하나의 수단들에 지나지 않아. 프로젝트 특성과 조직 특성 등에 맞게 여러 요소들을 적절히 조합하고 상황에 맞게 지속적으로 관리해 줘야 좋은 결과가 나오는 거야.
개발 방법론, 언어, 플랫폼? 그 어떤 것들도 모든 소프트웨어 개발에 최적인 것은 없어. 오히려 한 가지만 고집스럽게 주장하면 실패할 확률이 훨씬 높지.
[/quote]