클래스 체계
표준 자바 관례에 따름 첫째로 변수목록, 정적 공개 상수가 있다면 맨 위층에 나온다, 다음에 정적 비공개 변수 이어서 비공개 인스턴스 변수가 나온다. 비공개 함수는 자신을 호출하는 공개 함수 직후에 넣는다. 즉 추상화 단계가 순차적으로 내려간다.
캡슐화는 변수와 유틸리티 함수는 공개하지 않는 편이 낫지만 반드시 숨겨야한다는 법칙도 없다.
클래스는 작아야 한다!
클래스를 만들 때 첫 번째 규칙은 크기다. 두번째 규칙도 크기다, 더 작아야 한다. 그렇다면 얼마나 작아야 하는가 함수는 물리적인 행 수로 크기를 측정했다. 하지만 클래스는 다른 척도를 사용한다. 클래스가 맡은 책임을 센다. 클래스 이름은 해당 클래스 책임을 기술해야 한다. 간결한 이름이 떠오르지 않는다면 필경 클래스 크기가 너무 커서 그렇다. Processor, Manager, Super등과 같이 모호한 단어가 있다면 클래스에다 여러 책임을 떠안겼다는 증거다. 클래스 설명은 if,and,or,but을 사용하지 않고서 25단어 내외로 가능해야 한다.
단일 책임 원칙은 클래스나 모듈을 변경할 이유가 하나, 단 하나뿐이어야 한다는 원칙이다. 책임, 즉 변경할 이유를 파악하려 애쓰다 보면 코드를 추상화하기도 쉬워진다. 더 좋은 추상화가 더 쉽게 떠오른다.
SuperDashboard Class 책임
- 소프트웨어 버전 정보 추적
- 스윙 컴포넌트 관리
단일 책임 규칙에 위배!
Version Class으로 버전정보 추적의 관심을 분리한다
단일 책임 클래스가 많아지면 큰 그림을 이해하기 어려워진다고 우려한다, 큰 그림을 이해하려면 이 클래스 저 클래스를 수없이 넘나들어야 한다고 걱정하지만 명확한 컴포넌트로 나눠담아 관리하고 싶지 않은가?
일반적으로 메서드가 변수를 많이 사용할수록 응집도가 높다. 모든 인스턴스 변수를 메서드마다 사용하는 클래스는 으집도가 가장 높다. 바람직하지 않다. 응집도를 유지하면 작은 클래스가 여럿이 나온다. 큰 함수를 작은 함수 여럿으로 나누기만 해도 클래스 수가 많아진다. 클래스가 응집력을 잃는다면 쪼개라!
변경하기 쉬운 클래스
깨끗한 시스템은 클래스를 체계적으로 정리해 변경에 수반하는 위험을 낮춘다. 어떤 변경이든 클래스에 손대면 다른 코드를 망가뜨릴 잠정적인 위험이 존재한다.
클래스 일부에서만 사용되는 함수나 책임을 각 클래스별로 나누라, 코드는 순시간에 이해되고 망가질 위험도 사라진다.
요구사항은 변하기 마련이다. 인터페이스와 추상 클래스를 사용해 구현에 미치는 영향을 격리한다. 상세한 구현에 의존하는 코드는 테스트가 어렵다.
아래 예시는 Porfolio클래스가 상시로 변하는 TokyoStockExchange API를 사용해 포트폴리오 값을 계산할때 결합도를 내리는 예시다.
public interface StockExchange {
Money currentPrice(String symbol);
}
다음으로 StockExchange 인터페이스를 구현하는 TokyoStockExchange 클래스를 구현한다.
이후 Portfolio 생성자를 수정해 StockExchange 참조라를 인수로 받는다.
이렇게 구현하면 클래스는 주가로 언제나 100불을 반환하는 인터페이스를 구현한것이다.
위와 같이 테스트가 가능할 정도로 시스템의 결합도를 낮추면 유연성과 재사용성도 더욱 높아진다. 자연스럽게 DIP를 따르는 클래스가 나온다.
다음장으로 11장