# 애자일(Agile)한 설계?
앞선 게시글에서 애자일과 애자일방법론중 하나인 XP에 대해서 살펴 봤다. 애자일 방법을 사용한다면 변경에 유연하고 빠르게 개발 하며 릴리즈할 수 있었다. 그렇다면 이러한 애자일방법을 사용하기 위해서 어떻게 설계를 해야하는 것일까? 즉, 변경에 유연하고 빠르게 개발하기 위해서는 우리는 어떤 걸 해야할까?
애자일 설계의 핵심은 결과가 아닌 과정이라는 것이다. 뒤에서 배우겠지만 SOLID원칙을 준수하면서 원칙,패턴을 적용하고 명료하고 표현적으로 소프트웨어를 유지하는 과정을 거친다면 자연스레 애자일한 결과가 나온다. 과정이 아닌 설계인 이유이다. 앞으로 다가올 변화에 대비하여 복잡한 코드를 짜지 않고, 현재 상황에서 짤 수 있는 최대한 간결한 코드를 짜야한다는 것을 명심하자.
# 소프트웨어는 왜 잘못 되는가?
우리가 개발해야할 소프트웨어에 대한 분명하고 완벽해보이는 설계도를 우리에게 건내줬다고 생각해보자. 그리고 그 완벽한 설계도에 만족하는 소프트웨어를 개발했다. 완벽한 설계덕에 빠르게 개발을 맞칠 수 있었다고 우리는 생각한다. 그러나 이건 정말 완벽했던 것 일까?
결국 무슨 소프트웨어건 업데이트(변경)이 일어날 것이다. 그러나 우리가 설계도를 기반으로 작성했던 이러한 코드들은 변경에 자유롭지 못한다. 결국 "부패"하게 된다. 결국 우린 재설계를 해야하겠다고 마음 먹지만, 이것은 성공하기 매우 어렵다. 소프트웨어는 계속 발전하고 변경되고 있을 것이기 때문이다. 우리가 만든 새로운 설계가 적용되기도 전에 다시 새로운 설계를 만들어야 할 것이다.
책에서는 이것을 "움직이는 목표를 쏘고 있다"라고 표현 했다.
# 부패한 소프트웨어
뭔가 잘못된 소프트웨어에서는 7가지 항목들을 찾아 볼 수 있다.
- 경직성(Rigidity)
- 취약성(Fragility)
- 부동성(Immobility)
- 점착성(Viscosity)
- 불필요한 복잡성(Needless complexity)
- 불필요한 반복(Needless Reptition)
- 불투명성(Opacity)
책을 읽으면서 7가지의 항목 중 경직성,취약성,부동성이 특히 중요하다는 생각이 들었다. 이 악취가 변경에서 자유롭게 하지 못하기 때문이다.
## 경직성(Rigidity)
경직성의 사전적 의미는 뻣뻣해지는 성질, 융통성이 없고 엄격한 성질이라는 의미를 가지고 있다. 소프트웨어에서는 이러한 경직성의 표현은 단순한 방법으로는 변경이 어려운 경향을 말한다. 융통성이 없다는 말과 일맥상통한다. 난 A라는 모듈에서의 한 기능을 변경하고 싶었지만, A<-B<-C 와 같이 모듈들이 의존하고 있어 B와 C들도 단계적으로 변경을 해야하는 경우이다. 뒤에 가서 배우겠지만 이 경직성은 OCP(개방폐쇄원칙)에 정확히 불합하는 성질이다.
## 취약성(Fragility)
말그대로 취약점이 있는 것이다. 난 A라는것을 변경했는데 C라는 곳에서 예기치 않은 문제가 발생했다. 변경한 영역과는 개념적으로 아무런 관계가 없는 곳인데 말이다. 이러한 취약성문제를 띄면 고칠 수록 어딘가가 계속계속 나빠지는 최악의 경우가 생길 수 있다.
## 부동성(Immobility)
부동성은 움직이지 않는다는 의미를 가진다. 소프트웨어에서 부동성은 내가 작성한 함수가 유용해서 다른 곳에서 쓰면 좋을것 같은데, 부동성때문에 다른 곳에서 쓸 수 없다는 의미를 가진다. 만약 이 코드를 분리하여 사용할 경우 어떤 문제가 발생하거나 큰 위험성을 지닐 것이다. 즉, 부동성의 성질은 분리할 수 없게 만든다.
## 점착성(Viscosity)
점착성은 끈끈하게 달라붙어있는 성질을 말한다. 소프트웨어의 점착성과 환경의 점착성 두가지로 나눌 수 있다. 끈끈하게 달라붙어있으면 떼어내기 어려울 것이다. 만일 소프트웨어에서 변경이 발생한다면 최고의 방법은 기존의 설계를 유지한체로 변경하는 것일거다. 그러나 점착성을 가진다면, 서로가 너무 끈끈히 붙어있어 설계를 변경하지 않고는 변경사항을 적용 할 수 없는 경우이다.
환경의 점착성은 개발환경이 느리고 비효율적일때 발생한다. 만일 컴파일 시간이 길다면, 개발자들은 컴파일 발생시키지 않는 방법으로 변경을 하려고 할 것이다. 이 변경이 기존의 설계를 깨버리는데도 말이다.
## 불필요한 복잡성(Needless complexity)
현재 시점에서 사용하지는 않지만, 미래의 생길 변경에 대비하기 위해서 코드를 작성하는 경우이다. 미래의 변경이 생기지 않을 수 있다. 이러한 코드는 괜한 복잡성을 띄게 한다. 앞으로 일어날지도 모르는 일에 대해서 생각하지 말자!
## 불필요한 반복성(Needless Reptition)
분리가능한 코드가 임에도 불구하고 copy&paste로 같은 코드를 반복하여 사용하는 경우이다. 이럴 경우 추상화된 개념을 잃어빌게 되고 결국 유지보수를 어렵게 만들 것이다.
## 불투명성(Opacity)
모듈(코드)를 이해하기 어려운 경우이다. 불투명성을 줄이기 위해서는 코드를 최대한 명료하고 간단하게 작성해야 한다. 특히 이러한 예는 우리가 흔히 저지르게 된다. 코드를 작성할때는 그 코드에 대해서 많은 고민과 시간을 들여서 작성할 것이다. 대게 우린 코드 몇줄을 작성하기 위해서 1시간을 씨름한적도 허다할 것이다. 그래서 코드를 쓰는 당시에는 이 코드가 매우 이해가 잘가고 명료해 보이지만, 몇달이 지난뒤 코드를 다시보면 이해가 가지 않는 경우가 허다하다. 그렇기 때문에 일관되고 간단하고 명료한 코드를 작성하여 불투명성을 줄여야 한다.
# 결국 문제는 변경이다
결국 이러한 7가지 부패한 요소들을 발견하게 되는 이유는 우리는, 소프트웨어를 유지보수하기 위해서 변경을 항상 마주치기 때문이다. 그렇기 때문에 변경은 항상 일어난다는 전제하에 간단 명료하게 코드를 작성할 수 있어야 한다. 그렇다고 미래의 있을지도 모르는 변경을 대비하는 코드를 작성하라는 것은 아니다. 이것은 불필요한 복잡성을 나타낼 것이다.
미래에 대비하지말라고 하면 어떻게 변경에 대해서 우리가 대비를 할 수 있을까? 책을 처음 읽었을때는 이것이 이해 되지 않았다. 그러나 글의 처음에서 말했듯이 이러한 변경에 유연한 설계를 하기 위해서는 원칙, 패턴, 가독성들이 잘 녹아들어가 연속적인 작용을 하는 상태를 만들어 간단하고 명료하게 소프트웨어를 만드는 것이다. 이러한 원칙을 지키면 자연스럽게 변경에 대비가 될 것이다.
# Copy 예제
책에서는 Copy예제를 담았다. 이 부분의 모든 서사와 코드를 담기에는 좋지 않을 것 같기에 간단하게 정리하도록 한다.
- 첫 Copy프로그램의 요구사항은 키보드의 입력을 받아 프린트로 출력하는 것이었다. 이 요구사항대로 개발을 끝냈다
- 이후 종이테이프의 입력을 받아 프린트로 출력가능하도록 소프트웨어를 수정하라고 했다. 어찌 저찌 수정했다.
- 이번엔 프린트 말고 천공기에 출력이 가능하도록 새로운 변경요구사항이 들어왔다. 또 수정을 했다.
그러나 애자일한 설계원칙을 지키지 않고 짠 이러한 코드들은 변경사항이 생길때마다 작성했던 코드들을 수정해야 했다. 그러면서 처음에 완벽해 보였던 설계는 경직성, 취약성, 부동성, 복잡성, 반복성, 불투명성을 띄게 됐다.
그러나 애자일한 설계를 적용했다면 이러한 변화에 유연하게 대처 했을 수 있다. Reader와 Printer라는 인터페이스를 만들고 각각의 종이테이브와 키보드 입력을 Reader로 상속받게 하여 구현했다면, 원래코드를 수정할 필요가 없다. 다형성의 엄청난 기능을 누리면서 새로운 기능이 추가 될때 새로운 Reader를 상속한 클래스를 만들기만 하면 됐다. 이렇게 작성함으로써 개방폐쇄원칙(OCP)원칙을 자연스럽게 지킬 수 있었다.
새로운 요구사항이 들어왔을때마다 어찌저찌 if-else와 같은 조건문을 남발하면서 땜질하는 코드가 아닌 변화에 유연한 애자일한 설계를 적용했다면 새로운 변경이 들어와도 겁먹지 않아도 됐다. 우린 모두가 사용중인 Client코드 Copy 클래스를 수정하지 않아도 될 것이다.
# 마치며
다음시간에는 이러한 애자일한 설계를 충족시키는, 즉 변경에 유연한 코드를 작성하기 위한 5가지 원칙을 알아본다. 너무나도 유명해 한번씩은 들어 봤을 SOLID이다. 단일책임원칙, 개방폐쇄원칙, 리스코프 치환원칙, 인터페이스 분리원칙, 의존성 역전법칙이 그에 해당한다.
'• 독서 > Design Pattern' 카테고리의 다른 글
[클린소프트웨어#5] SOLID-개방 폐쇄 원칙(Open Closed Principle) (0) | 2022.10.19 |
---|---|
[클린소프트웨어#4] SOLID-단일 책임 원칙(Single Responsibility Principle) (0) | 2022.10.19 |
[클린소프트웨어#2] 익스트림프로그래밍(XP)에 대해서 (0) | 2022.10.18 |
[클린소프트웨어#1] 애자일(Agile) 방법론과 4가지 가치와 12개의 원칙 (0) | 2022.10.18 |
[디자인패턴] 중재자 패턴(Mediator Pattern) (0) | 2022.10.11 |