본문 바로가기
Book/실용주의 프로그래머

5장 : 구부러지거나 부러지거나

by dug_developer 2022. 4. 1.
반응형

삶은 멈추지 않는다.

우리가 작성하는 코드도 마찬가지이다.

현대의 미친 듯이 빠른 변화 속도에 맞추기 위해서는 가능한 느슨하고 유연한 코드를 작성하기 위해 노력해야 한다. 그렇지 않으면 코드는 금세 낡고 수정하기 어려워져 기억 저편으로 사라져 버릴 것이다.

이 챕터에서는 되돌릴 수 있는 의사 결정을 내릴 수 있는 구체적인 방법에 대해 설명한다.

이를 잘 활용하면 여러분이 작성하는 코드가 불확실한 세상에 닥쳐도 유연성과 적응성을 잃지 않게 될 것이다.

📔결합도 줄이기와 디미터 법칙

좋은 울타리는 좋은 이웃을 만든다.

 

부끄럼 타는 코드를 작성하는 것이 이롭다고 말했었다.

이때 부끄럼 타는 이란 자신을 남에게 들어내지 말고 너무 많은 사람과 상호작용하지 말라는 2가지 의미를 갖는다.

코드를 모듈로 구성하고 이들 간의 상호작용을 제한하라.

 

결합도 줄이기

불필요한 의존이 많은 시스템은 유지 보수하기 어렵고 이로 인해 비용이 많이 들며 시스템 자체가 불안정한 경향이 있다.

우리는 의존도를 최소화하기 위해 디미터 법칙을 사용하여 메서드, 함수를 설계해야 한다.

 

디미터 함수 법칙

이 법칙은 한 객체가 제공하는 메서드에 접근하기 위해 또 다른 객체들을 통하는 것을 허용하지 않는다.

모듈 간의 결합도를 최소화하라.

 

함수를 호출하는 클래스의 응답집합 크기를 줄일 수 있기 때문에 좀 더 적은 에러를 가진 클래스를 만들 수 있다.

디미터 법칙은 코드를 더 적응성 있게 강하게 만들어 주지만 '주계약자'로서의 대가를 치러야 한다.

주계약자는 모든 하부 계약자를 직접 관리하고 이들에게 일을 위임해줘야 한다.

실제로 이는 위임자에게 단순히 요청을 전달하는 역할만을 하는 간단한 위임 메서드를 상당수 만들어야 함을 의미한다.

이러한 위임 메서드는 성능 저하와 메모리 과부하 같은 문제를 일으킬 수 있다.

하지만 트레이드오프로 디미터 법칙을 포기하고 여러 모듈의 결합도를 높임으로써 중요항 성능 향상을 꾀할 수 도있다. 작성한 개발자가 코드의 결합도를 다 이해하고 받아들일 수 있다면 괜찮은 설계이지만 이런 경우가 아니라면 유연하지 않은 미래를 향해 가고 있는 것이다.

 

📔메타 프로그래밍

아무리 뛰어난 천재라도 세부사항에 집착하면 그 재능이 발휘되지 않는 법이다. -레비의 8번째 법칙-

 

세부사항은 깔끔한 코드를 어질러 놓는다.

특히 변화가 잦을 때는 더욱 그러하다

비즈니스 로직, 법률, 경영자의 취향 등을 수용하느라 코드를 변경할 때마다 우리는 새로운 버그가 시스템을 깨뜨릴 수 있는 위험을 낳게 된다.

그러므로 우리는 "세부사항에서 벗어나라"라고 말한다!

이렇게 함으로써 우리의 코드는 매우 설정 가능하게 되고 소프트 해진다.

즉, 변화에 쉽게 적응할 수 있게 되는 것이다.

 

동적 설정

우선 시스템을 되도록 설정 가능하게 만들어라.

통합하지 말고 설정하라.

 

메타 데이터를 이용하여 반환 매개변수, 사용자 선호 사항, 설치 디렉터리와 같은 애플리케이션 설정 옵션을 기술하라.

메타 데이터란?
엄밀히 말해서 데이터에 관한 데이터.
애플리케이션을 기술하는 모든 데이터다
어떻게 실행되어야 하는가, 어떤 자원을 사용해야 하는가 등등

 

목표는 동적이고 적응 가능한 프로그램을 만드는 것이다. 이를 위해서 다음의 규칙을 따른다.

일반적 경우에 대해서 프로그램을 만들고 특별한 것들은 컴파일된 코드 밖 어딘가에 내놓는다.

 

코드에는 추상화를, 메타데이터에는 세부 내용을.

  • 설계의 결합도를 줄여 좀 더 유연하고 적응성 있는 프로그램을 만들 수 있다.
  • 세부사항을 코드 밖으로 몰아냄으로써 보다 강하고 추상적인 디자인을 만들 수 있다.
  • 애플리케이션을 커스터마이징 하기 위해 다시 컴파일할 필요가 없다. 이런 방식의 커스터마이징을 통해 실제 제작 공정 시스템에서 일어날 수 있는 치명적인 버그에서 벗어나는 우회로를 쉽게 만들 수 있다.
  • 메타데이터는 범용 프로그래밍 언어보다 문제 도메인에 가까운 방식으로 표현될 수 있다.
  • 동일한 애플리케이션 엔진과 상이한 메타데이터를 이용해 여러 다른 프로젝트를 진행할 수 있게 된다.

가능한 마지막 순간까지 세부 정의를 피하고 세부사항을 소프트하게 변화하기 쉽게 남겨 두라.

빠르게 변화할 수 있는 해결안을 강구함으로써 많은 프로젝트에 범란 하는 방향 전환이란 홍수에 보다 유연하게 대처할 수 있게 될 것이다.

비니니스 정책이나 룰은 프로젝트의 다른 어떤 부분보다 변화하기 쉽기 때문에 이를 유연한 포맷으로 통해 유지 보수하는 것이 좋다.

예를 들어 기간에 대한 정책이 있다면 기간을 수시로 바뀔 수 있으니 
기간은 설정가능하게 만드는 식으로 만드는 것이다.

 

협동적 설정

애플리케이션을 동적으로 설정하는 사용자와 개발자에 대해서 얘기를 했다.

그러나 애플리케이션들이 서로를 설정하게 만든다면, 소프트웨어가 스스로 환경에 적응하도록 만들면 어떻까? 미리 계획되지 않고 그때그때 맞게 설정되는 시스템이 있다면 매우 강력할 것이다.

ex) 운영체제의 다크 모드에 따라서 웹 환경에서도 다크 모드로 적용되는 것

 

📔시간적 결합

소프트웨어의 설계 요소 자체로서의 시간의 역할에 대해서!

시간적 결합 끊기!

동시성 : 같은 시각에 일어나는 일들

우리는 동시성을 허용할 필요가 있고 시간이나 순서에 따른 의존성의 결합을 끊는 방법을 생각할 필요가 있다.

유연성도 얻을 수 있고 작업 흐름 분석, 아키텍처, 설계, 배치 같은 개발의 여러 측면에서 시간과 관련된 모든 의존성을 줄일 수 있다.

작업흐름 분석을 통해 동시성을 개선하라.

순서대로 해야 되는 것처럼 보이지만 자세히 보면 병행해서 실행할 수 있는 부분들이 많기 때문에 개선해라!

 

서비스를 사용해서 설계하라.

우리는 컴포넌트 대신 서비스를, 즉 잘 정의되고 일관성 있는 인터페이스 뒤에서 일하는 독립적이고 동시적인 객체를 만든 것이다.

 

동시성을 고려한 설계

여러 일이 동시에 일어날 수 있기 때문에 전에 못 보던 시간에 관련된 의존성이 보이기 시작한다.

모든 전역 변수나 정적 변수들을 동시 접근으로부터 보호해야 한다.

애초에 왜 전역 변수가 필요했는지 스스로에게 물을 수 있는 좋은 기회이다.

 

언제나 동시성을 고려해 설계하라.

동시성을 허용하도록 설계한다면, 확장 가능성이나 성능에 대한 요구사항이 들어올 때 더 쉽게 그것에 맞춰 줄 수 있으며, 그런 일이 들어오지 않더라도 여전히 깔끔한 설계의 이점을 누리게 된다.

 

📔단지 뷰일 뿐이야

우리는 전부터 프로그램을 커다란 덩어리 하나로 짜지 말고, '나눠서 정복하기'방법을 써서 여러 모듈로 나눠 짜야한다고 배웠다.

모듈마다 자기만의 책임이 있다.

잘 정의된 단 하나의 책임만 가지는 것이야 말로 모듈에 대한 좋은 정의가 된다.

 

이벤트

이벤트를 이용하면 객체들 사이의 결합을 최소화할 수 있다.

이벤트의 전송자는 수신자에 대해 아무런 지식을 가질 필요가 없다.

객체가 자기가 필요한 이벤트들만 구독해서 받아보고 필요하지 않은 이벤트들은 받아오지 않도록 해야 한다.

전송자는 이벤트 수신자에 대한 목록을 유지하고 수신자들에게 이벤트가 일어났다고 알려주는 방식이다.

 

모델에서 뷰를 분리하라.

모델을 표시하는 뷰, 뷰를 관리하는 컨트롤러에서 모델을 분리해 내는 것이 바로 MVC의 핵심 개념이다.

이렇게 하면 동일한 데이터 모델에 여러 뷰를 둘 수도 있고 여러 다른 데이터 모델을 보는 공통된 뷰를 만들 수 도 있고 여러 다른 데이터 모델을 보는 공통된 뷰를 만들 수도 있다,

심지어 일반적이지 않은 입력 메커니즘을 지원하는 컨트롤러를 여럿 둘 수도 있다.

모델과 뷰/컨트롤러를 분리하면, 적은 비용으로 큰 유연성을 얻게 된다.

 

MVC는 주로 GUI 개발이라는 맥락에서 가르치지만 꼭 그런 것은 아니고 일반적으로도 쓸 수 있는 프로그래밍 기법이다.

모델 : 대상 객체를 나타내는 추상 데이터 모델.

모델은 어떤 뷰나 컨트롤러에 대해서도 직접적인 지식을 지니지 않는다.

 : 모델을 해석하는 방법

뷰는 모델의 변화 그리고 컨트롤러가 보내는 논리적 사건을 구독한다.

컨트롤러 : 뷰를 제어하고 새로운 데이터를 제공하는 방법

모델과 뷰 둘 모두에 이벤트를 보낸다.

 

📔칠판

형사가 살인사건에서 범인을 추측할 때 칠판을 어떻게 활용하는지에 대하여

  1. 어떤 형사도 다른 형사들의 존재를 알 필요가 없다.
  2. 형사들은 칠판을 보며 새로운 정보를 얻으며 자기가 발견한 것을 추가로 쓴다.
  3. 형사들은 저마다 다른 종류의 훈련을 받았거나 다른 수준의 교육과 경험을 지녔을 수도 있으며 사건을 해결하고 싶은 마음은 모두 있지만 공통점은 그 점뿐이다.
  4. 수사 과정에서 여러 형사들이 들어오거나 나갈 수 있고, 임무 교대 시간도 제각기 다를 수 있다.
  5. 무엇을 칠판에 올려도 되는지에 대한 제한이 없다. 사진, 증언, 물리적 증거 등등 어떤 것이라도 상관없다.

칠판 시스템을 이용하면 자식의 소비자와 생산자들이 익명으로 그리고 비동기적으로 데이터를 주고받을 공간이 생긴다.

그 덕분에 객체들 사이의 결합을 완전히 끊을 수 있다.

작성해야 할 코드의 양도 줄어든다.

 

칠판을 사용해 작업흐름을 조율하라

참여하는 요소들의 독립성과 심지어 고립성을 유지하는 동시에 이질적인 사실과 행위자들을 잘 조정하는 데 칠판을 사용할 수 있다.

반응형

'Book > 실용주의 프로그래머' 카테고리의 다른 글

7장 : 프로젝트 전에  (0) 2022.04.01
6장 : 코딩하는 동안 해야 할 일들  (0) 2022.04.01
4장 : 실용주의 편집증  (0) 2022.04.01
3장 : 기본적인 도구  (0) 2022.04.01
2장 : 실용주의 접근법  (0) 2022.04.01