[OOP] 객체지향 설계 5원칙 SOLID

calm0_0·2023년 9월 6일
0

OOP

목록 보기
5/6

SOLID 원칙이란 객체지향 설계에서 지켜야할 5가지 소프트웨어 개발 원칙을 말한다.

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


모든 객체는 하나의 책임만을 가져야 한다는 것으로 '단일 책임 원리'라고 한다.

객체가 제공하는 모든 기능은 단 하나의 책임을 수행하는 데 집중되어 있어야 한다.

각 클래스의 수정 이유가 오직 하나라면, 설계자는 단일 책임의 원리를 정확히 구현한 것이다.

예를 들어, 사칙연산 함수를 가지고 있는 계산 클래스가 있다. 이 클래스는 오직 사칙연산 기능만을 책임진다. 이 클래스를 수정한다고 한다면 그 이유는 사칙연산 함수와 관련된 문제일 뿐이다.


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


기존에 개발된 기능을 수정하거나, 새로운 기능을 확장하는 요구사항이 생겼을 때, 가장 직관적인 수정 방법은 기존 클래스 안 메서드의 내부 로직을 변경하는 것이다. 그러나 이것은 '사이드 이펙트'가 발생하기 쉽다. 또한, 수정한 코드의 정상작동 유무뿐만 아니라 사이드 이펙트 발생 유무도 번거롭게 테스트해야 한다.

그래서 기존에 개발된 클래스에 수정 사항이 발생하면 기존 클래스를 수정하지 않는 것이 좋다. 대신 새로운 클래스나 기능을 만들어 확장해야 한다.

클래스는 기능 확장에 대해서는 열려있지만 코드 수정에 대해서는 닫혀있어야 한다. 이것이 OCP의 원리이다.

예를 들어, 케릭터 하나를 생성한다고 할 때, 각각의 케릭터가 움직임이 다를 경우, 움직임의 패턴 구현을 하위 클래스에 맡긴다면 케릭터 클래스의 수정은 필요가 없고(Closed) 움직임의 패턴만 재정의 하면 된다.(Open)


리스코프 치환 원칙, LSP(Liskov Substitution Principle)


LSP란 '자식 클래스는 부모 클래스가 사용되는 곳(이 클래스 그룹을 사용하는 다른 클래스)에 대체될 수 있어야 한다.'는 원칙이다.

부모 클래스가 들어갈 자리에 자식 클래스를 넣어도 잘 작동해야 한다.

부모 클래스의 타입으로 객체를 선언하여 하위 클래스의 인스턴스를 받으면, 업캐스팅된 상태에서 부모의 메서드를 사용해도 동작이 의도대로 흘러가야 하는 것을 의미한다.

상속과 폴리모피즘을 깔끔하게 적용하고 싶을 때 고려해야 할 중요한 원칙이다.


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


인터페이스를 각각 사용에 맞게 분리해야 한다는 설계 원칙이다. 인터페이스를 사용하는 클라이언트를 기준으로 분리함으로써, 클라이언트의 목적과 용도에 적합한 인터페이스만을 제공하는 것이 목표이다.

인터페이스는 제약 없이 자유롭게 다중 상속(구현)이 가능하므로, 분리할 수 있으면 분리하여 각 클래스 용도에 맞게 implements 하라는 설계 원칙.

SRP는 클래스 관점에서 클래스가 하나의 일만 해야 한다는 것이고, ISP는 인터페이스 관점에서 '클래스는 자신이 사용하지 않는 메서드에 의존하면 안 된다'는 것이다.


DRY(Don't Repeat Yourself)


DRY는 '공통되는 부분을 추출하여 추상화하고 한 곳에 두어 중복 코드를 피하라'는 원칙이다.

중복된 코드가 존재한다면,

  1. 이 코드를 사용하는 클라이언트 클래스들은 어느 코드를 사용해야 할지 혼란스럽다.
  2. 개발자가 중복된 코드를 동시에 관리하지 못한다면, 추가 요구사항을 반영하지 못한 이전 코드가 남게 되는 경우가 발생한다.
  3. 그렇다면 두 코드를 사용하는 클라이언트 클래스 중 일부는 잘못된 코드를 사용하기 때문에, 조만간 버그가 발생한다.

그래서 DRY, 반복 금지 원리를 지켜야 한다.


의존 관계 역전 원칙, DIP(Dependency Inversion Principle)


의존 관계를 맺을 때 변화하기 쉬운 것 또는 자주 변화하는 것보다 변화하기 어려운 것, 거의 변화가 없는 것에 의존하라는 것이다.

즉, 구체적인 클래스 대신 추상적인 클래스에 의존하라는 뜻이다.
(구현 클래스에 의존하지 말고, 인터페이스에 의존)

ArrayList list = new ArrayList()  // x

List list = new ArrayList()   // o

이는 폴리모피즘에서의 '클라이언트 클래스에서는 부모 클래스만 의존하고 자식 클래스를 인자로 넘겨받아 저장한다.'와 동일한 원리이다.



Reference
한 번 읽으면 두 번 깨닫는 객체지향 프로그래밍
https://hckcksrl.medium.com/solid-%EC%9B%90%EC%B9%99-182f04d0d2b
https://inpa.tistory.com/entry/OOP-%F0%9F%92%A0-%EA%B0%9D%EC%B2%B4-%EC%A7%80%ED%96%A5-%EC%84%A4%EA%B3%84%EC%9D%98-5%EA%B0%80%EC%A7%80-%EC%9B%90%EC%B9%99-SOLID

profile
공부한 내용들을 정리하는 블로그

0개의 댓글