실용주의 프로그래머 5. 구부러지거나 부러지거나

jiffydev·2021년 8월 3일
0

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

모듈이 서로 결합되고 의존하게 되면 어떤 일이 일어날까?
시스템의 무관한 변화가 코드에 영향을 미치게 되고, 간단한 수정으로도 시스템 전체에 해를 끼칠 수 있다.
이러한 위험을 덜어내기 위해 결합도를 줄이고자 노력하게 된다.

결합도를 줄이기 위한 방법으로 디미터 함수 법칙을 적용할 수 있다.
디미터 법칙은 객체의 모든 메서드가 호출할 수 있는 메소드를
자기자신, 메서드로 넘어온 인자, 자신이 생성한 객체, 직접 포함하고 있는 객체로 한정하는 것이다.
다만 주계약자가 되는 클래스는 모든 하부 계약자를 관리할 책임이 있기 때문에, 위임하는 메서드를 많이 만들어야 하고 이는 성능 저하로 이어질 때가 있다.

데이터베이스 스키마 설계시 반정규화를 통해 성능을 개선하는 것처럼, 결합도를 높여 성능을 올릴 수도 있을 것이다. 따라서 무작정 디미터 법칙을 적용하는 것이 아니라 만들려는 애플리케이션의 특성을 고려한 후에 적용해야 한다.

2. 메타프로그래밍

세부사항이 좋은 코드를 망칠 수 있다.
세부사항을 코드에서 몰아내면 코드는 유연해질 수 있다.

시스템도 가능한 한 통합하지 않고 설정가능하도록 만드는 것이 좋다.
메타데이터를 이용해 애플리케이션에 관련된 모든 데이터를 기술할 수 있도록 해야 한다.
메타데이터가 주도하는 애플리케이션을 작성하게 되면 결합도가 줄어 유연해지고, 세부사항은 코드 밖으로 몰아냄으로써 코드는 강한 추상화를 적용할 수 있다.

나아가 비즈니스 로직도 메타데이터를 통해 유연한 포맷으로 만들 수 있다.

3. 시간적 결합

보통 프로그래밍을 하면 직선적으로 사고하게 된다.
A 메소드를 실행한 다음에 B 메소드를 실행하는 식이다.
이것이 시간 측면에서의 결합이고, 우리는 이런 시간적 결합을 어떻게 끊을 수 있을까 고민해야 한다.

요구사항을 분석하면서 작업 흐름 속에서 동시에 일어나도 되는 것과 엄격하게 순서에 따라 일어나야 하는 것을 나눌 수 있다.
UML 호라동 다이어그램같은 표기법을 사용하면 작업 흐름을 쉽게 파악할 수 있고, 어떤 것을 병렬적으로 수행할 수 있을지도 찾아낼 수 있다.

멀티스레딩이 가능한 언어가 등장하면서 기존의 (시간적으로 결합된) 직선형 코드와는 다른 방식으로 코드를 작성해야 하게 되었다.
여러 일이 동시에 일어날 수 있기 때문에 시간과 관련된 의존성을 더 유심히 살펴봐야 한다.
예를 들어 전역변수와 정적변수를 동시 접근으로부터 보호하고 있는지, 객체가 호출될 때 언제나 유효한 상태인지 등을 항상 확인해야 한다.

4. 단지 뷰일 뿐

프로그램을 여러 모듈로 나누어서 짜게 되면 객체간의 의사소통이나 의존성, 객체의 상태 변화가 새로운 문제로 부상한다.
모듈은 서로에 대해 몰라야 하는데, 이 때 사용할 수 있는 것이 이벤트이다.
이벤트를 통해 객체의 상태 변화에 대해 관심을 가질 객체에게만 알릴 수 있고, 이로 인해 객체간의 결합도는 낮아지게 된다.

이벤트를 사용할 때 중요한 것은 객체가 자신이 필요한 이벤트만 받도록 해야 한다는 점이다.
이를 위해 출판/구독 프로토콜을 사용할 수 있는데, 출판자는 이벤트를 보내고 이에 관심이 있는 구독자는 출판자를 등록하여 이벤트가 발생했을 때 호출을 받는다.
출판자는 구독자들의 목록을 유지한다.
아래에서 설명할 MVC 패턴에서도 출판/구독 매커니즘을 사용할 수 있다.

데이터와 데이터를 조작하는 연산들인 모델과 데이터를 보여주는 뷰, 뷰를 관리하는 컨트롤러, 이 셋을 분리함으로써 적은 비용으로 애플리케이션의 유연성을 얻을 수 있다.
이것이 MVC 패턴인데, 여기서 뷰는 반드시 그래픽이어야 한다거나 컨트롤러를 입력장치와 항상 결부시킬 필요는 없다.

뷰는 모델을 해석하는 방법이라 할 수 있고, 컨트롤러는 뷰를 제어하고 모델에 새로운 데이터를 제공하는 방법이라고 인식하는 것이 낫다.
이를 통해 GUI를 넘어 뷰가 객체의 모델이 되고, 그 객체도 다른 뷰의 모델이 되는 식의 네트워크 형태도 만들 수 있다.

5. 칠판

수사 관련 매체를 보면 형사들이 단서들을 한데 모아 정리해 놓은 칠판이 나오는 것을 볼 수 있다.
프로그램의 객체들도 이런 칠판에 모아 놓는 방식을 사용할 수 있는데, 이를 통해 객체간에 익명, 비동기적으로 데이터를 주고받을 수 있게 되어 객체 사이의 결합을 끊을 수 있다.

이처럼 객체 자체를 저장하면 객체의 흐름에 기반한 알고리즘을 설계하는 데 칠판을 사용할 수도 있고, 일관성 있는 칠판 인터페이스를 통해 내부의 상호작용을 위한 인터페이스를 많이 만들 필요가 없어짐으로써 시스템도 일관성 있도록 만들 수 있다.

profile
잘 & 열심히 살고싶은 개발자

0개의 댓글