스터디/Five Lines of Code

Five Lines of Code 11장. 코드 구조 따르기

마디니 2023. 11. 16. 20:53
반응형

소프트웨어는 현실 세계를 반영한 모델이다. 

현실세계가 성장하고 발전함에 따라 소프트웨어의 조정도 필수이다.

 

다양한 구조와 서로 다른 구조가 존재하는 이유

소프트웨어 개발에서는 여러 타입의 '구조'를 다룬다.

 

영향도(팀 내/팀 외)와 위치(코드 내/사람)에 따른 4가지 구조 형태

  팀 간 팀 내
코드에 있는 경우 외부 API 데이터와 함수, 대부분의 리팩터링
사람에 있는 경우 조직도, 프로세스 행위 및 도메인 전문가

 

매크로 아키텍처

- 팀 간 구조에 관한 것

- 제품이 무엇이며 다른 코드가 그것과 어떻게 상호작용 하는가

- 외부 API가 어떻게 보여야 하는지, 각팀이 어떤 데이터를 소유하는지 보여주며 소프트웨어 플랫폼을 정의한다.

 

마이크로아키텍처

- 팀 내 구조에 관한 것

- 팀이 가치를 제공하기 위해 무엇을 할 수 있는지 어떤 서비스를 사용하는지, 데이터를 어떻게 구성할지, 코드를 어떻게 작성할지 등

 

"콘웨이 법칙(Conway's law)"

외부 API의 모양은 조직 구조를 닮는 경향이 있다. 

비슷하게 도메인 전문가의 행위 패턴은 코드에 스며드는 경향이 있다.

 

사용자의 행위 또한 코드 구조에 영향을 미침

일부 코드 구조의 변경은 사용자 행위변경이 필요할 수도 있기 때문에 사용자는 코드의 또 다른 부분이다. 

 

행위를 코드화 하는 세 가지 방법

행위를 코드에 반영하는 세가지 방법은 다음과 같다.

- 제어흐름

- 데이터 구조

- 데이터 자체

 

제어흐름

- 제어 연산자, 메서드 호출, 단순히 열거된 코드의 줄을 통해 행위를 텍스트로 표현한다.

- 메서드 호출과 열거된 줄은 '비지역적 구조 표현'가능, 루프는 지역적으로만 동작 가능

- 제어 흐름 안에 행위를 기술하면 문장이동만으로 흐름이 변경 되기 때문에 리팩터링에 제어 흐름은 사용 하지 않는다.

- 메서드 추출, if문의 결합 패턴이 이에 해당된다.

 

데이터 구조에 행위 코드화하기

- 데이터 구조는 시간이 멈춘 알고리즘이다. 

- 이진검색 : 정렬된 목록에서 특정 요소를 찾는 알고리즘. 검색 공간을 반복적으로 절반으로 줄이면서 진행

- 이진검색트리(BTS): 여러 노드로 구성된 트리구조로 최대 2개의 자식 노드를 가질 수 있다. 오른 쪽 자식의 값은 항상 왼쪽 자식보다 크다.

- 기존의 변형이 발생하는 지점과 일치하지 않는 한 큰 변경을 수행하기가 어렵다. 대신 작은 변경은 더 쉽고 안전하다.

- 리팩토링 패턴중 클래스로 타입코드 대체, 전략 패턴의 도입이 이에 해당된다.

 

데이터에 행위 코드화 하기

- 컴파일러의 지원을 받지 못하는 영역이라 어렵고, 안전성 문제가 발생할 수 있다.

- 데이터 구조를 생성하는 도구(라이브러리)를 사용하는 것이 좋다.

- 너무 어렵기 때문에 될 수 있으면 위 다른 두가지 구조중 하나로 변환하는 것을 권장함

리팩터링이 도움이 되는 때와 그렇지 않은 때

- 코드가 변경될 필요가 없는 경우 리팩터링을 할 필요가 없다.

- 리팩터링은 현재 구조를 강화하고 유사한 변경 사항을 더 잘 수용할 수 있게 한다.

- 기본 구조에 대한 확신이 없다면 리팩터링 노력을 줄이고 먼저 정확성에 집중해야 한다.

- 새로운 기능이나 하위 시스템을 구현 할 때는 불확실 성이 있기 마련이다. 이런 상황에서는 빠르게 변경할 수 있도록 클래스보다는 열거형이나 루프를 사용하는 것이 좋다. 

- 이 후 코드가 성숙해지고 구조가 더 안정되면 코드도 리팩터링을 통해 구조에 맞게 안정되어야 한다.

 

예측 대신 관찰, 그리고 경험적 기술 사용

 

변경 범위를 예측하려는 시도는 코드베이스에 손상을 가져올 수 있다. 코드를 추측하지 말고 경험적인 기술을 사용해야 한다.

일반화 시킨 코드가 사용될지에 관한 확신이 없다면 복잡성만 가중시키는 셈이다.

 

- 변경되지 않으면 아무것도 하지 말자.

- 예측할 수 없이 변경되는 경우 취약성을 피하기 위해서만 리팩터링 해라

- 그렇지 않으면, 과거에 발생한 변경 유형을 적용해 리팩터링 해라.

 

"강력한 도구가 있어도 항상 사용할 필요는 없다"

 

코드를 이해하지 않고도 안전성을 확보하는 방안

테스트를 통한 안전성 확보

- 코드 테스트는 정확성을 확인하는 것 뿐만아니라 사용자 입장에서 공감할 수 있는 방법이다.

- 누군가의 세상을 더 좋게 만들기 위해 소프트웨어를 개발하는 것이고 따라서 그들의 세계를 이해해야 한다.

- 사람이 하는 것은 빠르게 관리하기 힘들고 엄청난 시간이 소요되며 오류가 발생하기 쉽다 => "자동화"를 통해 해결해라

- 실수가 일어나는 위치나 우리가 기대하는 것들이 100% 테스트 되지 않을 수 있다.

 

숙달을 통한 안전성 확보

- 리팩터링에 초첨을 맞추어 실수 가능성을 줄인다. 리팩터링을 작은 단계로 분할하여 일부 단계를 놓치지 않도록 한다.

- 안전한 환경에서 반복적인 리팩터링을 수행해서 기계처럼 할 수 있도록 숙달한다.

 

도구의 지원을 통한 안전성 확보

- 최대한 인적요소를 제거하고 IDE등 도구가 제공하는 리팩터링 기능을 사용한다. 

- 도구에 버그가 있을 수 있다는 점을 제외하면 안전하다. (널리 사용되는 도구는 패치도 빠르게 잘 된다.)

 

공식 인증을 통한 안전성 확보

- 비용이 많이 드는 소프트웨어와 같은 경우 증명보조기를 사용해 프로그램의 논리적인 명제가 올바른지 기계적으로 확인할 수 있다.

- 우리가 가진 잘못된 명제와 같은 오류가 증명보조기에 있으면 버그가 될 수 있다.

 

내결함성을 통한 안전성 확보

- 오류가 발생하더래도 자체 수정하도록 코드를 작성할 수 있다. 예)기능 on/off 토글

- 실패시 자동 롤백하도록 토글 기능을 추가 할 수 있다. 

- 전환 시스템이 올바른 응답과 오류를 구별하지 못하는 경우 실패할 수 있다.  

 

활용되지 않은 구조 이용

우리가 하는 모든 일에는 구조가 존재한다. (도메인, 의사소통 방식, 사고방식등) 

구조 대부분은 코드베이스에 스며든다.

리팩터링을 통해 이 구조를 활용해 안정적으로 코딩할 수 있다.

 

코드에서 활용가능한 구조를 찾는 방법

 

코드에서 활용가능한 구조를 찾는 방법

 

출 및 캡슐화에 공백 활용

- 복잡한 것을 구현할 때 그룹화 한후 작은 조각으로 잘라서 구현한다 > 이 때 조각 사이에 빈 줄과 주석을 추가하여 그룹이 추가됨을 알릴 수 있다.

- 공백이 들어가 그룹화된 문장들은 메소드로 추출 할 수 있는지 확인해봐야 한다.

- 공백 줄은 필드를 그룹화 하는데에도 사용된다. > 이 경우 데이터 캡슐화 리팩터링 패턴을 적용해 보는 것도 좋다.

 

통합에 중복 코드 활용

같은 클래스 내부나 서로 다른 클래스의 여러 메서드에 걸쳐 중복된 코드가 나오는 경우

- 메소드 추출 리팩터링 패턴으로 중복 내용을 추출한다.

- 추출된 메서드가 여러 클래스에 분산되어 있다면 데이터 캡슐화를 사용해 한 곳으로 모은다.

- 동일한 메소드 내용이라면 클래스도 동일하기 때문에 하나만 남기고 삭제가능

- 동일하지 않고 유사한 경우에는 유사 클래스 통합 리팩터링 패턴을 사용한다.

- 문장 자체가 다른 경우에는 전략 패턴을 사용해라. 

 

캡슐화로 공통 접사 활용

- 모큰 클래스에 공통 접사를 사용하지 않는다. -> 공통 접사를 사용한 곳은 구조화 대상이다!

- 공백이나 중복, 이름에 공통적인 명칭을 통해 그룹화 된 것들은 데이터 캡슐화를 통해 구조를 견고하게 바꿀 수 있다.

 

동적 실행으로 런타임 유형 활용

- typeof, instanceof 등 런타임시 하는 타입검사 > 인터페이스를 활용해 동적 실행하도록 한다.

- 인터페이스를 활용하여 다양한 타입의 클래스를 변수에 넣고, 변수에 대한 메서드를 호출 할 때 적절한 클래스의 메서드를 호출 한다.

반응형