메뉴 닫기

SOLID 설계 원칙

SOLID 설계 원칙이란 다음을 뜻한다.

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

단일 책임 원칙

클래스는 단 한개의 책임만을 가져야 한다.

객체 지향은 책임을 객체에게 할당하는 것이다. 클래스가 여러 책임을 가지면 각 책임마다 변경되는 이유가 발생하기 때문에, 클래스가 한 개의 이유로만 변경되거나 교체되려면 클래스의 책임은 하나여만 한다.

예를 들어 한 클래스가 데이터를 읽어 처리하고 화면에 보여주는 두 가지 책임을 가진다면, 기능이 변화되었을 때 변경이 어렵게 된다. 또 어떠한 기능을 사용하고자 할 때 필요하지 않은 패키지까지 의존해야 하는 경우가 생갈 수도 있다. 이럴 땐 클래스를 분리하여 한 클래스가 한 책임만 지게 하는 것이 옳다.

예를 들어 List<Student>를 받아 각각 학생들의 이름을 출력하는 책임을 가진 객체가 있다고 한다면 List<Student>에서 이름만을 뽑아 List<String>으로 만들고, 이를 다른 객체가 받아 출력하는 식으로 개선이 가능할 것이다.

또한 여러 사용자 객체가 한 객체의 서로 다른 부분을 사용한다면 그 부분을 분리하는 것도 고려해 볼 수도 있다. 예를 들어 다음은 자바 체스 게임에서 방향을 담당하는 Direction enum이다.

이름에서 유추할 수 있는 본연의 업무인 시작위치와 도착위치를 받아서 이동할 방향을 얻어내는 책임 이외에, 방향이 대각선 방향에 속하는지, 2칸 이동인지, 폰에게 적합한 이동인지 판별하는 메소드들이 섞여 있다. 이들을 분리하여 별도의 클래스로 변경할 수 있을 것이다.

개방 폐쇄 원칙

확장에는 열려 있으면셔 변경에는 닫혀 있어야 한다.

기능을 변경하거나 확장할 수 있으면서 그 기능을 이미 사용하는 코드는 수정하지 않아도 잘 작동해야 한다.

이는 추상화(인터페이스)를 통해 만들 수 있다. 예를 들어 콘솔 체스 프로그램을 웹으로도 보이게 해야 한다면 뷰 로직을 인터페이스로 만들면 기존의 콘솔 프로그램을 그대로 두고도 웹 체스 프로그램을 작동시킬 수 있다.

다운캐스팅을 하거나, 비슷한 if-else 블록이 존재하거나 하는 것은 개방 폐쇄 원착이 깨졌다는 신호이다.

리스코프 치환 원칙

상위 타입의 객체를 하위 타입의 객체로 치환해도 상위 타입을 사용하는 프로그램은 정상적으로 동작해야 한다.

스 게임에서 기본적으로 모든 말들은 다른 말을 뛰어넘을 수 없지만 오직 나이트만이 다른 말을 뛰어넘을 수 있다. 체스 게임을 구현하기 위해 모든 타입의 말들이 Piece를 상속하여 구현되어 있다. 이 경우 나이트의 경우에만 뛰어넘기를 방지하는 로직을 끄기 위해 이런 코드를 짠다고 한다면 리스코프 원칙을 위반한 것이 된다.

리스코프 치환 원칙은 확장과도 연관이 있기에 리스코프 치환 원칙을 어기면 개방 폐쇄 원칙 역시 여길 가능성이 높아진다.

인터페이스 분리 원칙

인터페이스는 그 인터페이스를 사용하는 클라이언트를 기준으로 분리해야 한다.

다르게 말하면 자신이 사용하는 메서드에만 의존해야 한다는 뜻이다. C++에서는 이 원칙을 어김으로 인해서 소스 재컴파일 문제 등이 발생할 수 있지만, 자바에서는 이런 문제가 일어나지는 않는다. 다만 단일 책임 원칙과 연결되어 있으므로 이 원칙을 지키는 것이 좋다.

의존 역전 원칙

고수준 모듈은 저수준 모듈의 구현에 의존해서는 안 된다. 저수준 모듈이 고수준 모듈에서 정의한 추상 타입에 의존해야 한다.

저수준 모듈은 고수준 모듈의 세부 기능을 구현한 것이다. 즉 고수준 모듈이 저수준 모듈에 의존하지 않음으로써 저수준 모듈을 쉽게 교체할 수 있게 함이다.

Posted in Java, 개발, 우아한테크코스

댓글 남기기