클린 아키텍처는 밥 아저씨의 클린 시리즈에서 가장 최신작인 것 같다.
이 책은 이전에 읽었던 [클린코드]와는 달리 아주 멀리서 소프트웨어산업을 바라보고 자신의 생각을 담아내고 있다.
내용
초반에는 자신이 생각하는 소프트웨어에 대해 설명하며 무엇이 소프트웨어를 더욱
소프트하게 만드는지 알려준다.
소프트함이라는 것은 변하기 쉬워야 한다는 것이다. 변하기 어렵게 만들거였으면, 하드웨어로 만들었을 것이라는 것이 그의 주장이다.
극단적인 예로, 변하기 쉽지만 요구사항에 맞지 않는 프로그램과 요구사항에는 맞지만 변하기 어려운 프로그램을 주어지면 그는 주저없이 첫번째를 선택하겠다고 말한다.
변하기 쉬운 것은 요구사항에 맞출 수 있지만, 후자는 비즈니스 로직이 변하거나, 버그를 발견했을 때, 바꾸기 어려우므로 안된다는 것이다.
물론 전대 변할 수 없는 프로그램은 없다. 하지만 프로그램을 변화시켜서 기대되는 비용과 개발을 하는 비용의 수지타산이 맞지 않을 때, 변할 수 없는 프로그램이라 부를 수 있다면 그런 프로그램은 존재할 것이다.
중반부터는 어떻게 하면 안전한 코드를 만드는지 설명한다. 하지만 코딩자체를 말하지는 않는다. 오히려 컴포넌트나 서비스같은 단위로 설명한다. 하지만 이 모든 내용은 작게는 코드에 대한 내용과 별 다를 것이 없어보인다.
그는 객체지향에 대해 설명을 하지만, 객체지향에 어떤 것도 이전에 C로 코딩을 하던 개발자들을 더 나은 개발자로 만들지는 못했다는 것을 설명한다. 왜냐하면 당시 개발자들 모두 그렇게 개발을 했었기 때문이다.
상속, 캡슐화, 다형성 모두 C언어로 가능한 구현들이었다. 대부분 문법적으로 간단하게 해준 것이며, 그 마저도 어떤 것은 오히려 구현이 불안정하게 만들었다. 저자가 객체지향으로 넘어가면서 얻은 장점은
다형성이라고 주장한다.
그리고는 지속적으로 그래프를 보여주면서 컴포넌트의 의존성의 방향이 얼마나 중요한지 설명한다. 나는 처음 이런 것을 보면서, 저자의 깊이를 더 알게 되었고, 정말 나중에 한 번 더 읽어야 겠다는 생각을 했다.
더해서 DI라는 것이 어떻게 아키텍처에서 쓰이는지 알게 되었다. 아무때나 DI를 다 붙잉는 것이 아니라. 이 방향을 바꾸기 위해서 하는 것이라는 것을 알게 되었다.
더해서 컴포넌트를 분리할 때도 DI를 사용해서 A,B컴포넌트에 서로 로직들이 잘 분리되도록 하는 것이다.
확실히 저자는 다형성에 큰 의의를 두고 있었다.
또 기억나는 것은 바로
구현에 대한 결정은 나중으로 미루라이라는 것이다. 그는 지속적으로 플러그인 패턴을 강조했다. 예를들어, 출력되는 곳이 콘솔일지, 프린터일지, HTML일지 이런것은 나중에 결정하라는 것이다.
환경은 또 어떨까? 웹으로 할 것인지 아닌지도 나중에 결정할 수 있도록 해야한다. 영속성은? DB로 할지도 나중에 결정해야 한다. 단순히 오라클/MySQL/... 중에 뭘 고를지 정하는 것이 아니다.
처음에는 map자료구조에 메모리로 저장하여 개발함으로써 영속성의 결정을 미룬다. 그리고 파일로 저장해서 또 미룬다. 미루고 미룬 후에 결정하는 것이다. 저자는 때때로 DB를 사용하지 않고 파일로 저장하고 가져와서 로딩하는 방식을 사용했다.
왜냐하면 DB가 필요 없었기 때문이다. 파일로도 충분했다.
이 구현을 미루는 것은 아키텍처에게 유현함(soft)함을 가져오게 해주고, 이런 외부 사항들로과 비즈니스로직을 자연적으로 분리시켜주게 된다. 그는 software가 firmware가 되는 것을 싫어했다. 펌웨어는 한 하드웨어에 종속되어 움직이는 경우가 대부분인데
그의 관점에서는 특정 DB에 종속된 것, 아니면 DB에 종속된 것을 펌웨어라 간주한다. 왜냐하면 세상은 많이 복잡해졌고, 그 정도의 종속도 펌웨어라는 것이다.
HTTP에 종속된 것도 펌웨어이다. 그는 코어 로직이 어딘가에 종속되지 않기를 바란다.
예를 들어보면 아래와 같다.
Core <- DB-AccessObject -> DB
<- Network-Object
여기서 화살표 방향은 해당 객체가 무엇을 사용하는지 알려준다. 왼쪽에 있는 Core컴포넌트는 아무것도 사용하지 않아야 한다. 그래야 플랫폼이 바뀌어도 사용할 수 있다. DB를 사용하기로 결정했어도 Core는 변경되지 않는다.
그런데 말이 되지 않는다. 만약 Network에서 요청이 오고 DB-AccessObject를 실행해야 하는데 어떻게 Core에서는 사용하지도 않는데 실행을 한다는 거지? 그 답은 아래 DI에 있다(!!)
아래처럼 화살표가 되어 있다고 해보자.
Core -> DB-AccessObject -> DB
<- Network-Object
이렇게 구현하는 것이 자연스러울 것이다. 여기서 DI를 적용하면?!
Core -> I-Persistent(in Core Component) <- DB-AccessObject -> DB
<- Network-Object
이렇게 I-Persistent를 이용하여 저장하고 조회하는 것이다. I-Persistent는 코어 컴포넌트 안에 있고, 영속성관리를 무엇으로 해도 상관이 없게 되었다.
이것이 DI의 힘이다. 나는 지금까지 재사용을 쓰기 위해서다. 구현이 바껴도 사용할 수 있어서 DI를 쓴다고 알고 있었다. 물론 맞는 말이긴 해도, 이정도의 깊이가 있는 사람이 동일한 말을 하는 사람과는 전혀 달랐다.
나는 이정도의 넓은 숲을 보면서 말하지는 않았다. 왜냐하면 이런 세상을 전혀 몰랐으니까...
방향을 바꿔서 컴포넌트의 분리를 꾀하고, 종단에는 코어를 (유연하게 하는 것)지키는 것.
일류 아키텍처의 속마음을 잠깐 들여다 볼 수 있는 순간이었다.
마지막으로 가면 갈수록 그는 이 DI를 더 강조하는 것처럼 보인다. 그리고 실제적인 예시들을 보여주면서 어떻게 해야 하는지 알려 준다. 사실 다 읽었지만, 완벽하게 이해했다고 생각되지는 않는다.
나에게 또한 많은 생각을 하게 한 내용은 바로 프레임워크다.
그는 프레임워크에 종속되면 안된다고 말한다. 물론 프레임워크 개발자는 당신이 종속되도록 요청한다. 아예 하나의 언어처럼 붙어살길 원한다. 하지만 당신은 그렇게 하면 안된다는 것이다.
당신은 프레임워크를 툴로 써야 하며, 언제든지 바꿀 준비가 되어있어야 한다. 도구로써 써야 한다. 마법과 같은 일을 할 수 있다고 계약하지 말라.
당신에게 분명 되돌아 온다. 프레임워크에 종속되어 펌웨어가 되지 말라고 한다.
예를들어 자바의 스프링프레임워크를 예를 들면, Autowired를 하지말라고 한다. 차라리 Main에 다가 종속성을 다 쓰라고 말한다. 당신이 사용하는 모든 클래스에 spring이 import되어 있다면
종속되어 있는 것이다. 어쩌면 플러그인 패턴을 사용하여 DI로 프레임워크를 분리해서 사용하는 것이 해답이 될 수도 있을 것 같다.
끝없이 소프트하게 하라, 그것이 소프트웨어 개발자가 해야 할 일인 것이다.
이 책은 분명 다시 읽어야겠다. 누군가가 개발자가 되었다면, 그리고 소프트웨어개발자라면, 언젠가는 읽어야 할 책이라고 소개하고 싶다.