Post

Clean Code 10장. 클래스

TIL(Today I Learn)

2024.07.08


오늘 읽은 범위

10장. 클래스


책에서 기억하고 싶은 내용을 써보세요.

  1. 클래스 체계
    클래스는 아래 순서로 멤버를 포함한다.
    정적(static) 공개(public) 상수가 제일 먼저 등장한다.
    정적(static) 비공개(private) 변수가 그 다음 등장한다.
    비공개(private) 변수가 그 다음 등장한다.
    변수 목록 다음에는 공개 함수가 제일 먼저 등장한다.
    비공개 함수는 자신을 호출하는 공개 함수 직후에 넣는다.
    위 순서에 따르면 추상화 단계가 순차적으로 내려가며, 클래스는 신문 기사처럼 읽힌다.

  2. 캡슐화
    변수나 유틸리티 함수는 공개하지 않는 편이 낫지만 반드시 감춰야 하는 것은 아니다.
    가끔은 테스트 코드에서 사용하기 위해 변수나 유틸리티 함수를 protected로 선언한다.
    하지만 비공개를 유지할 수 있는 모든 방법을 고민하고 최후의 결정을 내려야 한다.

  3. 클래스는 작아야 한다!
    클래스는 최대한 작게 만들어야 한다.
    클래스가 작다는 것은 무슨 의미인가? 클래스가 맡은 책임이 많지 않다는 뜻이다.
    클래스 이름은 클래스의 책임을 표현해야 한다. 작명이 클래스 크기를 줄이는 첫걸음이다.
    클래스 이름이 모호하다면 클래스 책임이 너무 많아서 그럴 수도 있다.
    Processor, Manager, Super 등과 같은 모호한 단어가 있으면 안된다.

  4. 단일 책임 원칙1
    단일 책임 원칙(SRP)은 클래스나 모듈을 변경할 이유가 하나뿐이어야 한다는 원칙이다.
    SRP는 ‘책임’이라는 개념을 정의하며, 적절한 클래스의 크기를 제시하고 있다.
    즉, 클래스를 변경할 이유가 하나여야 한다는 뜻이다.

  5. 단일 책임 원칙2
    SRP는 개발자가 이해하기 쉬운 원칙이지만, 반대로 개발자가 가장 무시하는 규칙 중 하나다.
    개발자는 ‘깨끗하고 체계적인 소프트웨어’보다 ‘돌아가는 소프트웨어’에 초점을 맞춘다.
    규모가 큰 시스템은 논리가 복잡하다. 복잡성을 다루기 위해서는 체계적 정리가 필요하다.
    큰 클래스 몇 개가 아니라 작은 클래스 여럿으로 이루어진 시스템이 더 바람직하다.
    작은 클래스는 단일 책임을 가지므로, 변경할 이유도 하나이다.
    또한, 다른 작은 클래스와 협력하여 시스템에 필요한 동작을 수행한다.

  6. 응집도
    클래스는 인스턴스 변수가 적어야 하며, 메서드는 인스턴스 변수를 하나 이상 사용한다.
    응집도가 높은 것은 메서드와 변수가 서로 의존하며 논리적인 단위로 묶이는 것이다.
    ‘함수를 작게, 매개변수 수를 작게’에 따르면 특정 메서드만 사용하는 인스턴스 변수가 많아진다.
    이것은 새로운 클래스로 쪼개야 한다는 신호이며, 응집도가 높아지도록 클래스를 분리한다.

  7. 응집도를 유지하면 작은 클래스 여럿이 나온다
    사이즈가 큰 메서드를 사이즈가 작은 메서드 여러 개로 분리하려고 한다.
    빼내려는 코드가 큰 메서드의 변수를 여러 개 사용하는 문제가 발생했다.
    해당 변수를 클래스 인스턴스 변수로 승격시키면 새 함수는 인수가 필요 없다.
    문제는 인스턴스 변수가 불필요하게 많아지면서 클래스의 응집도가 낮아진다는 것이다.
    몇몇 함수가 몇몇 변수만 사용한다면 독자적인 클래스로 분리해야 마땅하다.
    즉, 큰 함수를 작은 함수 여럿으로 쪼개다보면 자연스럽게 작은 클래스로 분리된다.
    결과적으로 프로그램에 체계가 잡히며, 구조가 투명해진다.

  8. 변경하기 쉬운 클래스
    깨끗한 시스템은 클래스를 체계적으로 정리하여 변경에 수반되는 위험을 낮춘다.
    OCP란 클래스는 확장에 개방적이고 수정에 폐쇄적이어야 한다는 원칙이다.
    기능을 수정하거나 기존 기능을 변경할 때 건드릴 코드가 최소인 시스템이 바람직하다.
    이상적인 시스템은 기능을 추가할 때 시스템을 확장할 뿐 기존 코드 변경하지 않는다.

  9. 변경으로부터 격리
    구체적인 클래스는 상세한 구현(코드)를 포함하며, 추상 클래스는 개념을 포함한다.
    상세한 구현에 의존하는 클라이언트 코드는 상세 구현이 변경되면 문제가 발생한다.
    따라서 인터페이스와 추상 클래스를 사용하여 구현에 미치는 영향을 최소화해야 한다.

  10. 변경으로부터 격리(테스트)
    상세한 구현에 의존하는 코드는 테스트가 어렵다.
    테스트가 가능할 정도로 시스템의 결합도를 낮추면 유연성과 재사용성도 높아진다.
    결합도를 최소로 줄이면 또 다른 클래스 설계 원칙인 DIP를 따를 수 있다.
    본직적으로 DIP는 클래스가 상세한 구현이 아닌 추상화에 의존해야 한다는 원칙이다.


오늘 읽은 소감은? 떠오르는 생각을 가볍게 적어보세요.

  • 클래스는 SRP 원칙을 기반으로 단 하나의 책임만 가지는 것이 중요하다는 것을 배웠다.
    클래스 이름을 짓는게 쉽지 않았는데, 너무 많은 책임을 가진 클래스를 설계해서 그럴 수도 있겠다.

  • 응집도가 높은 것은 메서드와 변수가 서로 의존하며 논리적인 단위로 묶이는 것이라는 것을 배웠다.
    그동안 메서드를 작성할 때 인스턴스 변수와의 관계에 대해서는 크게 고민하지 않았던 것 같다.

  • 클래스 내 인스턴스 변수, 메서드 등의 순서도 중요하다는 것을 배웠다.
    그동안 중요하지 않다고 생각했던 부분들을 개선하면 가독성이 좋은 클래스를 만들 수 있을 것이다.


궁금한 내용이 있거나, 잘 이해되지 않는 내용이 있다면 적어보세요.


This post is licensed under CC BY 4.0 by the author.