[Java] - SOLID 5원칙

링딩·2023년 4월 7일
0

Computer Science

목록 보기
22/49




먼저 이 글은 정말정말 많은 도움이 된 헤로님의 글이 출처입니다.





객체지향 프로그래밍의 특성과 장점을 최대한 끌어올리기 위한 설계 방법은 무엇이 있을까?


1. 객체지향 설계 과정

  1. 요구사항 (제공해야 할 기능) 을 찾고 세분화 한다. 그리고 그 기능을 알맞은 객체로 할당한다.
  2. 기능을 구현하는 데에 필요한 데이터를 객체에 추가한다.
  3. 해당 데이터를 이용하는 기능을 구현한다. (기능은 최대한 캡슐화)
  4. 객체 간에 어떻게 메소드 호출을 주고받을 지 결정한다.




2. 객체지향 5가지 설계원칙(SOLID)


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

◽ 정리

  • 클래스는 단 한개의 책임을 가져야 함
  • 클래스를 변경하는 이유는 단 하나여야 함
  • 이를 지키지 않으면, 한 책임의 변경에 의해 다른 책임과 관련된 코드에 영향을 미칠 수 있음
    → 이렇게 되면 유지보수가 매우 비효율적

우리가 앞서 말한 것처럼 객체지향적인 설계는 응집도가 높고, 결합도는 낮은 프로그램 설계가 되어야 한단 것이다.


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

◽ 정리

  • 확장에는 열려있어야 하고, 변경에는 닫혀 있어야 함
  • 즉, 기존의 코드를 변경하지 않고 기능을 수정하거나 추가할 수 있도록 설계해야 함
  • 이를 지키지 않으면 instanceof 와 같은 연산자를 사용하거나, 다운 캐스팅 발생

한 모듈의 기능을 수정할 때마다 그와 관련된 다른 모듈 또한 줄줄이 소세지처럼 다 고쳐야 한다면 과연 이게 유지보수가 좋은걸까?
No. 그렇기 때문에 OCP를 통해 기존 코드를 수정하지 않고기능을 확장할 수 있게 하여 유연성을 높이자는 것이다.
=> 추상화(인터페이스)상속(다형성) 통해 구현.


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

◽ 정리

  • 하위 타입 객체는 상위 타입 객체에서 가능한 행위를 수행할 수 있어야 함
    → 즉, 상위 타입 객체를 하위 타입 객체로 치환해도 정상적으로 동작해야 함
  • 상속관계에서는 꼭 일반화 관계 (IS-A) 가 성립해야 한다는 의미 (일관성 있는 관계인지)
  • 상속관계가 아닌 클래스들을 상속관계로 설정하면, 이 원칙이 위배 (재사용 목적으로 사용하는 경우)

이 말은 'LSP 원칙'을 지키지 않으면
=> 위의 OCP 원칙을 위반하게 되는 것이다.
이렇게 되면 기능확장을 위하여 기존의 코드를 여러번 수정해야만 할 것이다...
그렇기에 상속 관계를 잘 정의하여 LSP 원칙이 위배되지 않도록 설계하자


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

◽ 정리

  • 클라이언트는 자신이 사용하는 메소드에만 의존해야 한다는 원칙
  • 한 클래스는 자신이 사용하지 않는 인터페이스는 구현하지 않아야 함
    → 하나의 통상적인 인터페이스보다는 차라리 여러 개의 세부적인 (구체적인) 인터페이스가 나음
  • 인터페이스는 해당 인터페이스를 사용하는 클라이언트를 기준으로 잘게 분리되어야 함

각 클라이언트가 필요로 하는 인터페이스들을 분리함으로써, 클라이언트가 사용하지 않는 인터페이스에 변경이 발생하더라도 영향을 받지 않도록 만들어야 하는 것이 핵심


5. DIP (Dependency Inversion) 의존 역전 원칙

◽ 정리

  • 의존 관계를 맺을 때, 변하기 쉬운 것 (구체적인 것) 보다는 변하기 어려운 것 (추상적인 것)에 의존해야 함
  • 고수준 모듈은 저수준 모듈의 구현에 의존해서는 ❌
    -> 저수준 모듈이 고수준 모듈에서 정의한 추상 타입에 의존해야함
    => 저수준 모듈이 변경되어도 고수준 모듈은 변경이 필요 없는 형태여야 함.

구체화된 클래스에 의존하기 보다는 추상 클래스나 인터페이스에 의존해야 한다는 뜻



최종적으로!!

"SRP 와 ISP 는 객체가 커지는 것을 막아준다."

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

"LSP 와 DIP 는 OCP 를 서포트한다."

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

profile
초짜 백엔드 개린이

0개의 댓글