ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 실용주의 프로그래머 정리5
    Study/실용주의 프로그래머 2021. 12. 6. 21:47

    구부러지거나 부러지거나

    코드는 항상 빠르게 변화한다. 빠른 변화 속도를 대처하기 위해 느슨하고 유연한 코드를 작성해야 한다. 이번 장에서는 변화하는 세상속에서 코드의 유연성과 적응성을 잃지 않는 법을 소개한다.

    우선 결합도를 낮추는 법을 알아보고, 메타 프로그래밍을 이용해서 적은 양의 코드를 작성해서 유연함을 유지할 수 있는 방법을 소개한다. 그리고 시간 측면에서 결합도를 알아보고 뷰와 모델을 분리하는 법을 소개한다. 마지막으로 모듈들이 데이터를 교환할 수 있는 만남의 장소를 마련해서 결합도를 획기적으로 줄이는 방법을 알아본다.

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

    결합도를 줄이면 코드가 유연해지고 변경을 잘 적응할 수 있다. 결합도를 낮게 유지하는 방법 중 하나는 디미터 법칙을 지키는 것이다.

    디미터 법칙은 내가 소유한 객체 또는 매개변수로 받은 객체 이외의 메소드는 호출하지 않는 것이다. 예를들어, 메소드 체이닝이 있다. bank.getAccount().getMoney() 이 코드는 디미터 법칙을 어긴 코드다. account는 현재 소유한 객체가 아니기 때문에 알아서는 안되고 메소드 체이닝으로 호출하게 되면 결합도가 높아진다. 따라서 account의 수정에 영향을 받을수 있다.

    성능이 중요한 상황에서는 디미터 법칙을 어길 수 있다. 하지만 끔찍한 미래를 가져올 수 있기 때문에 가능하면 그러지 않는 것이 좋다.

    27. 메타 프로그래밍

    세부 사항은 코드를 지저분하게 만들고 관리하기 힘들게 한다. 추상화 된 코드는 유연성 있고 변경에 강하다. 따라서 코드는 추상화해서 유지할 수 있도록 하고 세부 사항은 메타데이터로 표현하면 유연한 코드를 작성할 수 있을 것이다.

    설정 정보 등의 세부 사항을 코드로 작성하지말고 메타 데이터로 표현하자. 이런 정보들은 언제든지 바뀔 수 있고 바뀔때 마다 다시 컴파일하고 싶지 않을 것이다. 여기에 더해 자주 변화하는 비즈니스 로직도 메타 데이터로 표현할 수 있다. 매우 유연하게 프로그램을 변경할 수 있다.

    보통 프로그램을 재시작할 때 변경된 메타데이터를 읽어서 실행할텐데 이는 유연성이 떨어진다. 실행 중에도 메타 데이터를 변경할 수 있도록 만들자. 더 복잡해지겠지만 매우 강력한 프로그램을 만들 수 있다.

    28. 시간적 결합

    시간적 결합을 고려해서 설계하자. 시간적 결합이란 작업의 순서에 의존성이 있는 것이다. 예를들어, A 작업 이후에 B 작업을 하면 B 작업은 A 작업에 대한 시간적 결합이 있는 것이다.

    시간적 결합이 없는 작업들은 동시에 처리될 수 있다. 이는 시간적 결합을 끊은 동시성에 대한 고민으로 이어지고 다양한 설계에 대한 측면을 바라볼 수 있게 된다. 직선적으로 처리할 때는 문제가 없던 것도 동시성을 고려하면 문제가 많아진다. 가장 대표적인 예가 전역 변수다. 동시성을 고려하게 되면 확장 가능성과 성능에 대한 요구사항을 더 쉽게 대비할 수 있다. 또한 자연스럽게 설계가 깔끔해진다.

    29. 단지 뷰일 뿐이야

    데이터와 뷰는 따로 관리되는 것이 좋다. 데이터가 뷰를 의존하거나, 뷰가 데이터 구조에 의존하기 시작하면 시간이 지나면 관리하기 힘든 코드가 된다. 또한 한 데이터에 대한 여러가지 뷰의 형태를 보고 싶을때 데이터의 중복이 생기기도 한다.

    따라서 원본 데이터를 따로 관리하고 뷰를 위한 데이터 구조로 바꿔주는 컨트롤러를 두면 유연한 코드 작성이 가능해진다. 새로운 형태의 뷰를 제공하고 싶으면 원본 데이터를 바꿀 필요없이 컨트롤러와 뷰를 추가하면 된다.

    뷰와 데이터를 분리하는 방법에는 여러가지가 있다. 그 중 pub/sub 패턴과 MVC 패턴이 유명하다. pub/sub 패턴은 이벤트의 형태로 뷰와 데이터를 분리한다. 데이터가 변경되면 등록된 뷰에게 이벤트를 통지한다. 만약 관심있는 데이터가 아니라면 구독하지 않으면 된다. MVC 패턴은 아주 익숙한 패턴으로 컨트롤러가 뷰와 데이터 모델을 연결해주는 역할을 한다. 위에서 설명한 것 처럼 컨트롤러가 데이터 모델을 뷰에 맞는 형태로 변환해서 전달한다.

    대부분 좋은 아키텍쳐는 책임을 잘 분리하고 모듈간의 결합도를 떨어뜨리기 위해 나오는 것 같다. 이런 점을 이해하고 있으면 다른 좋은 아키텍쳐를 이해하기 쉬울 것이라고 생각한다. 각 아키텍쳐가 어떤 문제를 해결하기 위해 어떻게 책임을 분리하고 결합을 분리하는지 이해하도록 하자.

    30. 칠판

    칠판은 분산된 작업 흐름이 바라보는 데이터 공간에 대한 비유적인 표현이다. 여러 사람이 서로 만나지 않고 칠판에 작업한 데이터를 공유하고 다시 공유된 데이터를 읽고 작업을 진행하는 과정을 생각하면 된다.

    칠판 시스템은 문제의 규모가 크고 복잡한 인공지능 애플리케이션에서 사용할 목적으로 발명됐다. 예를들어 JavaSpaces라는 분산 시스템이있는데 키/값 튜플 공간을 활용한다. 자바 객체를 키값으로 저장하거나 키값으로 가져올 수 있다. Redis와도 유사하다고 생각하면 될 것 같다.

    댓글

Designed by Tistory.