[Spring] 좋은 객체지향의 5가지 원칙, SOLID

박준호·2023년 3월 27일
1
post-thumbnail

객체지향 프로그래밍의 특성과 장점을 끌어올리기 위해 프로그램을 설계할 때 필요한 5가지 원칙이 있다
원칙을 잘 지킨다면 유지보수하기 쉽고, 유연하고, 확장이 쉬운 소프트웨어를 만들수 있을것이다

객체지향 프로그래밍의 설계과정

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

💡 캡슐화란?

객체의 속성과 행위(메서드)를 하나로 묶고, 실제 구현 내용 일부를 외부에 감추어 은닉한다

객체지향 설계원칙, SOLID

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

  • 하나의 클래스는 하나의 책임만 가져야 한다
  • 클래스를 변경하는 이유는 단 하나여야 한다
  • 이를 지키지 않으면, 한 책임의 변경에 의해 다른 책임과 관련된 코드에 영향을 미칠 수 있다

🤨 책임이 어떤 의미이지

SRP에서 이야기하는 책임은, 기능 이라는 뜻으로 생각하면 된다
한 클래스가 수행할 수 있는 기능(책임)이 여러 개라면, 클래스 내부의 함수끼리 강한 결합을 발생할 가능성이 높아진다
위 내용은 객체지향 설계의 핵심 요소를 위반하는 행위가 되는 것이다
새로운 요구사항이나 프로그램 변경에 의해 클래스 내부의 동작들이 연쇄적으로 변경되어야 할 수도 있다
위 상황은 유지보수가 비효율적이므로, 책임을 잘게 쪼개어 분리시킬 필요가 있다

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

  • 확장에는 열려있어야 하고, 변경에는 닫혀 있어야 한다
  • 기존의 코드를 변경하지 않고 기능을 수정하거나 추가할 수 있도록 설계해야 한다

어떤 모듈의 기능을 하나 수정할 때, 그 모듈을 이용하는 다른 모듈들도 하나하나 고쳐줘야 한다면 유지보수가 매우 복잡할 것이다
개방 폐쇄 원칙을 잘 적용하여 기존 코드를 변경하지 않아도 기능을 새롭게 만들거나 변경할 수 있도록 해야한다

지키지 않으면, 객체지향 프로그래밍의 장점 유연성, 재사용성, 유지보수성 등을 잃어버린다

🤨 어떻게 OCP를 구현할까

추상화(인터페이스)상속(다형성) 등을 통해 구현할 수 있다.
변화가 잦은 부분들을 추상화 함으로써 기존 코드를 수정하지 않고 기능을 확장할 수 있도록 함으로써 유연성을 높이는 것이 OCP의 핵심이다

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

  • 하위 타입 객체는 상위 타입 객체에서 가능한 행위를 수행할 수 있어야 한다
    -> 상위 타입 객체를 하위타입 객체로 치환해도 정상적으로 동작해야 한다는 뜻
  • 상속관계에서는 꼭 일반화 관계 (IS-A)가 성립해야 한다
  • 상속관계가 아닌 클래스들을 상속관계로 설정하면 리스코프 치환 원칙에 위반된다

리스코프 치환 원칙을 지키지 않으면 개방 폐쇄 원칙을 위반하게 되는 것이다
기능 확장을 위해 기존의 코드를 여러 번 수정해야 할것이다
그러므로 상속 관계를 잘 정의하여 리스코프 치환 원칙이 위반되지 않도록 설계해야 한다

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

  • 클라이언트는 자신이 사용하는 메소드에만 의존해야 하는 원칙
  • 한 클래스는 자신이 사용하지 않는 인터페이스를 구현하지 않아야 한다
  • 인터페이스는 해당 인터페이스를 사용하는 클라이언트를 기준으로 잘게 분리되어야 한다

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

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

  • 의존 관계를 맺을 때, 변하기 쉬운 것(자세한 것) 보다는 변하기 어려운 것(추상적인 것)에 의존해야 한다
    -> 구체화된 클래스에 의존하기 보다는 추상 클래스나 인터페이스에 의존해야 한다는 의미
  • 저수준 모듈이 고수준 모듈에서 정의한 추상 타입에 의존해야 한다

정리

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

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

profile
클라우드 컴퓨팅 공부중입니다.

0개의 댓글