객체 지향 설계 5원칙

흔히 SOLID라고 부르는 객체 지향 설계 5원칙는 아래 5가지 원칙의 앞 글자를 따서 만들어진 것이다.

  • SRP(Single Responsibility Principle) : 단일 책임 원칙
  • OCP(Open Closed Principle) : 개방 폐쇄 원칙
  • LSP(Liskov Substitution Principle) : 리스코프 치환 원칙
  • ISP(Interface Segeregation Principle) : 인터페이스 분리 원칙
  • DIP(Dependency Inversion Principle) : 의존 역전 원칙

이 SOLID라고 불리는 설계 원칙은 프로그래머가 시간이 지나도 유지 보수와 확장이 쉬운 시스템을 만들고자 할 때 적용할 수 있다.

SRP - 한 클래스는 하나의 책임만 가진다.

책임

  • 책임 != 메서드

    하는 일이 너무 많다고 해서 여러 개의 책임이 있는 것은 아니다. 예를 들면 DAO에 findById가 추가되었다고 해서 또 다른 책임이 주어지는 것이 아니다.

  • 책임은 사용자에 관한 것

    현재 클래스를 사용하고 있는 외부 클래스에 따라 책임을 분리할 수 있다. Employee라는 클래스의 develope() ,codeReview()메서드는 CoWorker클래스에 의해 사용되므로 하나의 책임으로 묶고, date()라는 메서드는 GirlFriend라는 클래스에 의해 요구되니 또 다른 책임이 생기는 것이다.

책임이 많으면 일어나는 상황들

  • Collision

    책임이 많아진다는 것은 각각의 사용자들의 요구를 반영해야 한다는 뜻이다. 개발자A가 어떤 요구에 의해서 Employee의 codeReview() 로직을 변경했고, 개발자B가 어떤 요구에 의해서 date() 로직을 변경했을 때 이 둘의 소스코드는 충돌이 나게 된다.

  • Fan Out

    여러 군데에서 사용하는 만큼 변경이 좀 더 많고, 이 클래스가 변경될 때 이에 의존하고 있던 여러 클래스들 또한 민감해진다. GirlFriend 클래스의 변경된 요구로 인해서 이와 관련없는 많은 클래스들이 영향을 받는다.

고로 클래스는 반드시 하나의 변경 사유를 가져야 한다.

  • Extract Class 책임의 개수당 클래스를 생성하여 분리한다. 예를들면 Employee는 Worker 클래스와 BoyFriend 클래스로 나누고 각각에 하나의 책임만 가지도록 만든다.

    • 사용자 클래스와 구현 클래스 강하게 coupled
  • Inverted Dependencies(의존성 역전)

    인터페이스와 구현 클래스로 분리시킴으로써 결합도를 낮춘다. Employee라는 인터페이스를 만들고, CoWorker와 GirlFriend는 인터페이스를 사용하고, 각각의 클래스의 요구에 맞는 Employee 구현체를 만드는 것이다.

    • 사용자 클래스와 구현 클래스를 Decouple 시킴
    • 사용자 클래스가 인터페이스 coupled됨
    • 하나의 클래스에 구현되어 각각의 구현도 coupled
  • Interface Segregation

    Extract Class의 경우 하나의 책임당 하나의 클래스를 생성했다면, Interface Segregation은 책임당 하나의 인터페이스를 지니는 경우이다.

    • 사용자 클래스와 구현 클래스를 Decouple
    • 사용자 클래스의 입장에서 해당 인터페이스의 구현이 어디에 되어있는지 찾기 어렵다.
    • 하나의 클래스에 구현되어 각각의 구현은 coupled