본문으로 바로가기

1. 클래스 체계

클래스를 정의하는 표준 자바 관례에 따르면,

가장 먼저 변수 목록이 나오고 변수 목록 다음에는 공개 함수가 나온다.

  • 변수: 정적 공개 상수 -> 정적 비공개 변수 -> 비공개 인스턴스 변수 -> 공개 변수
  • 비공개 함수는 자신을 호출하는 공개 함수 직후에 넣는다.

즉, 추상화 단계가 순차적으로 내려간다.

 

1) 캡슐화

변수와 유틸리티 함수는 가능한 공개하지 않는 편이 낫지만 반드시 숨겨야 한다는 법칙도 없다.

때로는 protected로 선언해 테스트 코드에 접근을 허용하기도 한다.

그러나 그전에 비공개 상태를 유지할 온갖 방법을 강구하고 캡슐화를 푸는 결정은 최후의 수단이다.

 

2. 클래스는 작아야 한다!

함수와 마찬가지로 클래스 설계의 기본은 '작게'이다.

큰 클래스 몇 개가 아니라 작은 클래스 여럿으로 이뤄진 시스템이 더 바람직하다.

 

그렇다면 얼마나 작아야 하는가?

함수는 물리적인 행 수로 크기를 측정했다.

클래스는 맡은 책임을 센다.

 

클래스 이름은 해당 클래스 책임을 기술하는데 실제로 작명은 클래스 크기를 줄이는 첫 번째 관문이다.

  • 간결한 이름이 떠오르지 않는다면 클래스 크기가 너무 커서 그렇다.
  • 클래스 이름이 모호하다면 클래스 책임이 너무 많아서이다.

 

1) SRP : 단일 책임 원칙(Single Responsibility Principle)

단일 책임 원칙은 클래스나 모듈을 변경할 이유가 하나, 단 하나뿐이어야 한다는 원칙이다.

변경할 이유를 파악하려 애쓰다 보면 코드를 추상화하기도 쉬워진다.

 

2) 응집도

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

일반적으로 메서드가 변수를 더 많이 사용할수록 메서드와 클래스는 응집도가 더 높고

모든 인스턴스 변수를 메서드마다 사용하는 클래스는 응집도가 가장 높다.

 

일반적으로 이처럼 응집도가 가장 높은 클래스는 가능하지도 바람직하지도 않다.

그렇지만 우리는 응집도가 높은 클래스를 선호한다.

 

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

때때로 몇몇 메서드만이 사용하는 인스턴스 변수가 생기는데, 이는 새로운 클래스로 쪼개야 한다는 신호이다.

 

3. 변경하기 쉬운 클래스

대다수 시스템은 지속적인 변경이 가해진다.

그리고 뭔가 변경할 때마다 시스템이 의도대로 동작하지 않을 위험이 따른다.

깨끗한 시스템은 클래스를 체계적으로 정리해 변경에 수반하는 위험을 낮춘다.

 

새 기능을 수정하거나 기존 기능을 변경할 때 건드릴 코드가 최소인 시스템 구조가 바람직하다.

이상적인 시스템이라면 새 기능을 추가할 때 시스템을 확장할 뿐 기존 코드를 변경하지 않는다.

 

1) 변경으로부터 격리

객체지향 프로그래밍엔 구체적인 클래스와 추상 클래스가 있다.

구체적인 클래스는 상세한 구현(코드)을 포함하여 추상 클래스는 개념만 포함한다.

 

상세한 구현에 의존하는 클라이언트 클래스는 구현이 바뀌면 위험에 빠진다.

그래서 우리는 인터페이스와 추상 클래스를 사용해 구현이 미치는 영향을 격리한다.

 

SRP 이외에 필요한 SOLID 원칙을 아래와 같이 정리 하였습니다.

 

- SRP (단일 책임 원칙) :

   '한 클래스는 하나의 책임만 가져야 한다.' 중요한 기준은 변경이며, 파급 효과가 적으면 단일 책임 원칙을 잘 따른것


OCP (개방 폐쇄 원칙) : 

  소프트웨어 요소(클래스, 함수, 컴포넌트 등)는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다.

  이를 해결하기 위해 다형성을 활용해야 합니다.
  (예를 들어 자동차 모델들이 여러개 있어도 변경이 된다한들 운전자는 아무 영향이 없다.)


LSP (리스코프 치환 원칙) : 

   프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야한다. 
  (자동차 엑셀 기능 예시 :

   자동차 인터페이스의 엑셀은 앞으로 가라는 기능, 뒤로 가게 구현하면 LSP 위반, 느리더라도 앞으로 가야함)


ISP (인터페이스 분리 원칙) 특정 클라이언트를 위한 여러 개가 범용 인터페이스 하나보다 낫다
  (자동차 인터페이스 예시 : 운전 인터페이스, 정비 인터페이스로 분리) 


DIP (의존관계 역전 원칙) : 구현 클래스에 의존하지 말고, 인터페이스에 의존하라는 뜻
   (예를들어 운전자가 자동차 역할만 알면되고, 차에 대한 디테일 기능을 알필요가 없다)

 

참조 : 김영한의 스프링 강좌