본문 바로가기
독서에서 한걸음

Clean Code .Part10

by oncerun 2022. 7. 30.
반응형

 

깨끗한 클래스

 

코드의 표현력과 코드 블록을 깨끗하게 했다고 해도 더 높은 단계까지 신경 쓰지 않는 다면 클린 코드에 다가가기 힘들다. 

 

객체지향 프로그래밍에서 클래스가 작성되는 시점을 중심으로 생각해보면 프로그램의 목적이 정해지고 목적을 달성하기 위한 책임을 분배할 때 생성된다. 

 

 즉 이 말은 클래스에는 책임을 가시적으로 보여주는 네이밍을 부여하고 그 내부에는 그 책임을 이행하기 위한 내용물들이 존재함을 뜻한다. 

그리고 그 크기는 대개 작아야 한다고 한다. 객체지향 프로그래밍 및 설계의 원칙 중 SRP에 따르면 클래스나 모듈을 변경되어야 하는 이유는 단 하나뿐이어야 한다는 원칙이 있다. 이는 변경될 이유 즉 책임이 하나 여야만 한다는 의미를 가지고 있다. 

 

하지만 클래스 설계자는 SRP를 가장 무시한 규칙 중 하나이다. 수많은 책임을 가진 클래스는 꾸준히 접한다. 그 이유는 우리는 돌아가는 소프트웨어를 자신도 모르게 원한다. 깨끗한 소프트웨어보다 말이다.

 

그리고 자잘한 단일 책임 클래스가 많아지면 전체적인 시스템을 이해하기 어렵다고 말한다. 규모가 어느 정도 큰 수준의 시스템은 논리가 상당히 많고 복잡하다는 것을 우리는 안다. 

여기서 저자는 질의한다. 복잡하고 거대한 논리를 체계적으로 정리할 것인가? 아님 큰 뭉텅이 여러 개로 구성할 것인가?

 

복잡성을 다루기 위해선 정리가 필수다. 그래야 개발자가 무엇이 어디에 있는지 쉽게 찾는다. 

 

현실 보다 이상을 이루기 위해 고생하자. 큰 클래스 몇 개가 아니라 작은 클래스 여럿으로 이뤄진 시스템이 바람직하다.

 

여기까지 클래스의 크기에 대하여 이야기했다. 그럼 내부는 어떻게 정리해야 할까?

 

클래스는 인스턴스 변수 수가 작아야 한다. 또한 각 클래스 메서드는 클래스 인스턴스 변수를 하나 이상 사용해야 한다.  이를 쉽게 응집도가 높다고 한다.

결국 응집도가 높다는 것은 클래스에 속한 메서드와 변수가 서로 의존하며 논리적인 단위로 묶인다는 의미이기 때문이다.

 

응집도에 집중하다보면 자연스레 클래스를 여러 개로 분할할 수 있다. 몇몇 메서드만이 사용하는 인스턴스 변수가 많아진다면. 이는 클래스로 쪼개 한다는 신호이기 때문이다.

 

즉 응집도를 유지하면 작은 클래스 여럿이 나온다.

 

큰 함수를 작은 함수 여럿으로 나누기만 해도 클래스가 많아진다고 한다. 그 이유를 설명하기 전 예시를 하나 들어준다. 

 

변수가 아주 많은 큰 함수 하나가 있다. 큰 함수 일부를 작은 함수 하나로 빼내고 싶은데, 빼내려는 코드가 큰 함수에 정의된 변수 넷을 사용한다. 그렇다면 변수 네 개를 새 함수에 인수로 넘겨야 옳을까?

 

그렇지 않은데, 이 경우 네 변수를 클래스 인스턴스 변수로 승격한다면 새 함수는 인수가 필요없다. 그만큼 함수를 쪼개기 쉬워진다.

 

대신 클래스가 응집력을 잃는다. 왜 응집력을 잃는 것인가? 앞에서 살펴보면 이는 특정 함수만 사용하는 인스턴스 변수가 증가하기 때문이다. 그렇다면 우리는 특정 함수들이 특정 변수만 사용한다는 것을 알기에 이들을 특정 클래스로 분리할 수 있기 때문이다. 따라서 큰 함수를 쪼개기만 해도 작은 클래스를 만들 수 있는 기회가 생긴다.

 

저자가 예시로 빽빽한 코드를 클래스로 풀어가는 방법을 설명할 때 어떻게 리팩터링을 수행했는지 방법도 알려주는데 매우 유용하다. 

 

그는 가장 먼저 원래 프로그램의 정확한 동작을 검증하는 테스트 코드를 먼저 작성했다.  이후 한 번에 하나씩 수 차례에 걸쳐 조금씩 코드를 변경했다. 그는 변경할 때마다 테스트를 수행해 원래의 프로그램과 동일하게 동작하는지 확인했다고 한다. 나에게 큰 도움을 준 것 같아 매우 흡족하다.

 

지금까지 클래스를 리팩터링하거나 설계할 때 응집력을 높이는 방식으로 개선하거나 생성하라고 권고한다. 

다만 클래스가 현재 혹은 미래의 변경 가능성에 생각해볼 필요가 있다. 

대다수 프로그램은 변한다. 그리고 테스트 코드가 촘촘하지 않는다면 변경 이후 의도대로 동작하지 않을 위험이 따른다. 

 

클린 한 시스템은 클래스를 체계적으로 정리해 변경에 수반하는 위험을 낮춘다. 미완성 클래스, 추후 지원 예정인 클래스를 생성할 때 어떻게 해야 하는가?  

이상적인 시스템은 새 기능을  추가할 때 확장할 뿐 기존 코드를 건드리지 않거나 최소인 구조가 바람직하다고 한다. 

쉽게 우리는 DIP와 SRP를 생각하며 구조를 맞춰가면 된다. 그럼 OCP는 자연스레 따라올 수 있다.

 

이 장의 마무리는 객체지향의 설계 원칙을 강조한다. 아마 객체지향의 설계 원칙에 따르기만 해도 자연스레 클린한 코드를 얻을 수 있다는 말을 하고 싶은 것 같다.

 

 

 

 

 

반응형

'독서에서 한걸음' 카테고리의 다른 글

Clean Code .Part12  (1) 2022.08.04
Clean Code .Part11  (0) 2022.08.02
Clean Code .Part9  (0) 2022.07.30
Clean Code .Part7  (0) 2022.04.21
Clean Code .Part6  (0) 2022.04.11

댓글