diff --git "a/\354\261\225\355\204\260_9/\353\205\270\354\230\210\354\260\254.md" "b/\354\261\225\355\204\260_9/\353\205\270\354\230\210\354\260\254.md" new file mode 100644 index 0000000..cf876e1 --- /dev/null +++ "b/\354\261\225\355\204\260_9/\353\205\270\354\230\210\354\260\254.md" @@ -0,0 +1,73 @@ +9장에서는 8장에 이어서 계층형 설계에 대한 설명을 하고 있다. +앞 장에서 계층형 설계의 전반적인 내용을 살펴보았다. 계층형 설계를 해나가기 위한 4가지 패턴이 있는데, 그 중 첫번째 패턴을 8장에서 살펴보았고, 9장에서는 나머지 3개의 패턴을 살펴보고 있다. + +## 패턴2. 추상화 벽 + +> 추상화 벽은 세부 구현을 감춘 함수로 이루어진 계층입니다. p204 + +추상화 벽은 특정 '계층'에 대해서 이름을 붙인 것이다. 이 이름이 의미하는 바는 이 계층의 벽 너머로는 무엇이 있는지 알 필요가 없다는 것을 뜻하는 것이다. 벽 앞에 존재하는 것들은 그저 벽만 바라보면 된다. 벽 너머는 신경쓸 일이 아니다. + +이렇게 하는 것이 무엇에 도움이 되는 것일까? + +- 해결해야 할 문제가 명확해진다. + - 이렇게 벽만 바라보면, 해결해야 할 문제가 명확해진다. 구체적인 수준에서 문제를 해결하려하지 않아도 된다. 어떤 데이터 구조를 사용할지, 데이터 구조를 활용해서 어떤 연산을 적용할 지를 고민하기 위해서 사용하는 언어레벨에서의 코드는 생각하지 않아도 된다. 추상화 벽에 구현되어 있는 좋은 함수들을 이용하여, 요구사항을 구현해나간다. +- 코드의 변경 사항이 감추어진다. + - 추상화 벽 너머에서 구현을 변경하려고 한다. 하지만, 추상화 벽을 의존하고 있는 쪽에서는 오로지 인터페이스만 바라보고 있다. 때문에 구현이 변경 되었는지 안되었는지는 신경 쓸 일이 아니다. 추상화적이 잘 세워져있다면, 앞쪽에서는 벽만 잘 쳐다보면 된다. +- 선언적인 코드를 사용할 수 있게 된다. + - 추상화 벽에 있는 함수들을 활용하여, 상위 계층에서 코드를 작성하게 되면, 더욱 선언적인 코드를 사용할 수 있다. 복잡해질 수 있는 코드를 더욱 명확하게 바꾸게 된 것이다. + +이런 추상화 벽은 언제 사용하는 것이 좋을까? + +- 구현을 쉽게 바꾸기 위해 + - 변경이 예상되는 지점이 있으면, 그곳에 인터페이스로 코드 변경사항 전파에 대한 방어벽을 만들어둔다. 이 방어벽을 의존하여 코드를 작성하면, 코드의 변경사항이 어떻게 변경되던지 간에 신경쓰지 않을 수 있으며, 구현을 더욱 쉽게 바꾸어나갈 수 있다. 만약 방어벽이 없다면, 코드의 변경사항은 여기저기 퍼져나가서 개발자들을 괴롭히게 될 것이다. +- 코드를 읽고 쓰기 쉽게 하기 위해 + - 세부적인 내용은 신경쓰지 않고, 추상적인 레벨의 함수만 사용하면 된다. 선언적인 코드. +- 조율할 것을 줄이기 위해 + - 인터페이스로만 소통하면 된다. +- 주어진 문제에 집중하기 위해 + - 문제의 구체적인 부분은 무시할 수 있다. + +이 추상화 벽을 읽다보니 유사한 개념으로 의존성 역전 원칙이 떠올랐다. 의존성 역전 원칙의 정의는 다음과 같다. + +> 의존성 역전 원칙은 구체적인 구현보다, 안정적이고 추상적인 인터페이스에 의존하도록 강제하는 원칙이다. + +의존성 역전 원칙은 oop에서 설계를 유연하게 만들기 위하여, 가장 핵심이 되는 개념이라고 할 수 있다. 구체적인 구현사항에 의존하지 않고 추상적인 인터페이스에 의존하도록 만듦으로써 언제든지 쉽게 구현 사항을 변경시킬 수 있다. +이런 개념은 추상화벽과 유사한 개념을 가진다고 느껴졌다. + +또 다른 예시로는 디자인 시스템이 생각났다. 프론트 개발자들로 하여금 구체적인 컴포넌트의 구현에 대해서 신경쓰기 보다는, 조금 더 비지니스 로직에 해당하는 부분에 집중할 수 있도록 다양한 컴포넌트들을 제공해준다. 컴포넌트가 구현되는 내용은 바뀔 수 있지만, 인터페이스가 변경되지 않는다면 디자인 시스템 컴포넌트에 변경사항이 발생해도, 사용하는 쪽에서는 어떤 코드의 변경도 일어나지 않게 될 것이다. + +## 패턴3. 작은 인터페이스 + +> 작은 인터페이스 패턴은 새로운 코드를 추가할 위치에 관한 것입니다. p.213 + +여기서 말하는 인터페이스란 하나의 계층에 존재하는 함수들을 가리킨다. 책에서는 주로 추상화 벽이라는 계층에 대해서 이야기하고 있다. 새로운 기능이 추가되어야 한다. 근데 이 구현을 추상화벽에 놓을 것인가? 아니면, 그 위에 있는 계층에 놓을것인가를 고민해야한다. 이때 가능하면 추상화벽에 놓는 것보다는 더 상위계층에 구현을 놓는 의사결정을 하는 것을 작은 인터페이스라고 한다. + +이렇게 인터페이스의 갯수를 줄여야하는 이유는 다음과 같다. + +- 인터페이스가 많아질 수록 팀 간 조율해야 할 것도 많아진다. +- 인터페이스가 많아질 수록 알아야 할 것이 많아 사용하는 것이 어려워진다. + +## 패턴4. 편리한 계층 + +이 편리한 계층 이라는 패턴은 '설계라는 작업을 언제 그만둘 것인가?' 에 대한 기준을 마련해준다. + +> 스스로 물어봅시다. 지금 편리한가요? 만약 작업하는 코드가 편리하다고 느낀다면 설계는 조금 멈춰도 됩니다. --- 하지만 구체적인 것을 너무 많이 알아야 하거나, 코드가 지저분하다고 느껴진다면 다시 패턴을 적용하세요. p.220 + +--- + +- 호출 그래프를 활용하면 비기능적 요구사항이 잘 이루어지고 있는지 파악할 수 있다. + + - 유지보수성 + - 테스트성 + - 재사용성 + +- 호출 그래프상에서 위쪽에 있는 함수 : + - 코드를 고치는 것이 쉽다. + - 왜냐하면 의존하고 있는 코드가 별로 없기 때문이다. +- 호출 그래프상에서 아래쪽에 있는 함수 + - 코드를 고치는 것이 어렵다. + - 왜냐하면 의존하고 있는 코드가 많기 때문이다. + - 그렇기 때문에 테스트를 잘 작성해야한다. + - 하지만, 코드가 변경될 이유가 별로 없기 때문에 테스트의 생명 주기가 길다. + - 또한 작고 명확한 문제를 해결하고 있기 때문에 테스트를 작성하기가 쉽다. + - 재사용성이 높다.