객체 지향 설계의 5원칙(SOLID)

개발자·2021년 4월 11일

📒 SOLID

  • SRP: 단일 책임 원칙(single responsibility principle)
  • OCP: 개방-폐쇄 원칙 (Open/closed principle)
  • LSP: 리스코프 치환 원칙 (Liskov substitution principle)
  • ISP: 인터페이스 분리 원칙 (Interface segregation principle)
  • DIP: 의존관계 역전 원칙 (Dependency inversion principle)

1. SRP (단일 책임 원칙)

  • 한 클래스는 하나의 책임만 가져야 한다.
  • 즉, 각 클래스는 하나의 기능만 가져야 한다. 한 클래스가 수행하는 기능이 여러가지라면 결합도가 높아져 변경이 생길 때 유지보수에 비효율적이다.
  • 변경이 있을 때 파급 효과가 적으면 단일 책임 원칙을 잘 따른 것이다.

2. OCP (개방-폐쇄 원칙)

  • 확장에는 열려 있고 변경에는 닫혀 있어야 한다.
  • 즉, 기존 코드를 수정하지 않고 기능을 추가할 수 있어야 한다.
  • 변경될 수 있는 부분과 변경되지 않는 부분을 구분해, 변경될 수 있는 부분을 추상화하여(주로 인터페이스를 통해 구현) 유연하게 작성해야 한다.
  • 추상화와 상속을 통해 OCP를 가능하게 할 수 있다. 추상화와 상속을 통해 기존 코드를 수정하지 않고 기능을 확장할 수 있도록 한다.

3. LSP (리스코프 치환 원칙)

  • 자식클래스는 부모클래스에서 가능한 행위를 수행할 수 있어야 한다
  • 즉, 부모클래스를 자식클래스로 치환해도 정상적으로 동작해야 한다.
  • 자식클래스가 부모클래스를 오버라이딩하거나 추가적인 기능을 통해 부모의 상태를 변경시키면 LSP원칙을 위반하는 것이다.

4. ISP (인터페이스 분리 원칙)

  • 인터페이스는 클라이언트를 기준으로 분리해야 한다.
  • 즉, 클라이언트가 사용하지 않는 인터페이스는 구현하지 말아야 한다. 자신이 사용하는 인터페이스만 구현해야 한다.
  • 하나의 큰 인터페이스를 상속 받기 보다는, 인터페이스를 구체적이고 작은 단위들로 분리시켜 꼭 필요한 인터페이스만 상속하는 것이 낫다.
  • 인터페이스가 명확해지고, 결합도가 낮아진다.
  • ISP와 SRP는 하나의 클래스가 커지는 것을 방지해주기 위한 것으로 동일한 문제에 대해 다른 해결책을 제시하는 것이다.

5. DIP (의존 역전 원칙)

  • 고수준 모듈은 저수준 모듈에 의존해서는 안된다.
  • 구체화에 의존하지 말고, 추상화에 의존해야 한다. 즉, 구현 클래스에 의존하지 말고, 인터페이스에 의존해야 한다.

정리

SRP 와 ISP 는 객체가 커지는 것을 막아준다. 객체가 단일 책임을 갖도록 하고 클라이언트마다 특화된 인터페이스를 구현하게 함으로써 한 기능의 변경이 다른 곳까지 미치는 영향을 최소화하고, 이는 기능 추가 및 변경에 용이하도록 만들어 준다.

LSP 와 DIP 는 OCP 를 서포트한다. OCP 는 자주 변화되는 부분을 추상화하고 다형성을 이용함으로써 기능 확장에는 용이하되 기존 코드의 변화에는 보수적이도록 만들어 준다. 여기서 '변화되는 부분을 추상화'할 수 있도록 도와주는 원칙이 DIP 이고, 다형성 구현을 도와주는 원칙이 LSP 인 것이다.



💡 Spring의 역할

다형성 만으로는 OCP, DIP를 지킬 수 없다.
Spring의 DI를 통해 다형성 + OCP, DIP를 가능하게 한다.



Ref.

https://jaeyeong951.medium.com/%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-5%EC%9B%90%EC%B9%99-solid-ac7d4d660f4d
https://velog.io/@kyle/%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-SOLID-%EC%9B%90%EC%B9%99-%EC%9D%B4%EB%9E%80
https://velog.io/@haero_kim/SOLID-%EC%9B%90%EC%B9%99-%EC%96%B4%EB%A0%B5%EC%A7%80-%EC%95%8A%EB%8B%A4

profile
log.info("공부 기록 블로9")

0개의 댓글