소프트웨어 개발자/SW 개발론

[클린코드] SOLID 객체 지향 설계 원칙

yubi5050 2022. 9. 12. 02:35

SOLID 객체 지향 설계 원칙

SOLID는 객체 지향 설계의 다섯가지 원칙을 지칭한다. 클린코드의 한 방법으로 SRP, OCP, LSP, ISP, DIP 원칙이 있다.

 

 

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

모든 클래스는 각자 하나의 책임만 가지며 클래스는 그 책임을 완전히 캡슐화 해야 된다는 의미이다. 

 

예로 DB를 1)생성 및 초기화 2) 데이터 삽입, 삭제 역할을 수행하는 A 클래스가 있다고 가정하면, 이를 우리는 SRP 원칙에 따라 A클래스의 역할을 B클래스로 분리할 수 있다. 

A클래스 : DB 생성 및 초기화
B클래스 : DB 데이터 삽입, 삭제

 

이렇게 SRP (단일 책임 원칙)을 지킨 경우, 클래스에 대한 외부 영향도를 최소화 할 수 있고, 유지보수나 확장면에서 유리하다. (ex. DB의 Setting 값을 바꾸기 위해 A클래스의 서비스를 중지하는 경우, B클래스의 역할 독립적으로 수행 가능)

 

또다른 예시로 1) A클래스가 인자에 따른 초기화와, 특정 기능을 수행하는 함수(C)의 if else에 따라 return 값이 다르다고 가정한다. (ex. Food 란 클래스에 type 인자를 초기화 (중식, 일식, 한식 등..) 하면서, C의 type에 따라 조건문(if-else) 가격을 return) 해당 케이스의 경우는 아래와 같이 SRP 원칙을 적용 할 수 있다.

 

A클래스 : 부모 클래스 (인자 제공, 공통 함수-가격 return 제공)
B1클래스 : A클래스 상속, (한식 클래스), 가격 return 함수
B2클래스 : A클래스 상속, (중식 클래스), 가격 return 함수
B3클래스 : A클래스 상속, (일식 클래스), 가격 return 함수, 일식 전용 기능 함수

 

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

OCP(Open/Close Principle, 개방/폐쇄 원칙)원칙 이란 소프트웨어 개체(클래스, 모듈, 함수 등)가 기능 확장에는 열려있지만, 기능 수정에 대해서는 닫혀있어야 한다는 원칙이다. 즉 신규 기능 추가시에는 해당 소스코드만 확장하면 오류가 없어야하며, 만약 기존 코드를 수정할 소요가 발생하게 되면 기존에 코드가 좋지 않게 디자인 되었다는 뜻으로 생각 할 수 있다.

(ex. 좀더 쉬운말로 기존 코드에 신규 기능을 추가 할 때 그 모듈로 인해, 다른 모듈을 줄줄이 고쳐야 한다면 이는 OCP 원칙을 따르지 못한 것으로 안좋은 코드라고 할 수 있다.)

 

예시로 독립적인 역할을 수행하는 A1, A2, A3 클래스가 이를 분기에 의해 해당 클래스의 객체를 호출하는 B클래스의 M1 메소드가 있다. 해당 함수는 if a1(), elif a2(), elif a3() ... 이런식으로 분기 코드가 작성 될꺼고, 만일 A4 클래스가 새로 생성된다면, B클래스의 M1 메소드에는 elif a4() 가 작성되어야 할 것이다. 

 

이는 A4 클래스 (신규 모듈)이 B클래스 (기존 모듈)에 수정 소요를 발생시키므로, OCP원칙에 어긋날 수 있다. 이런 경우 M1 메소드를 수정해 자동으로 A4클래스가 생성되도록 코드 로직을 구성하면 좋다.

  

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

LSP(Liskov Substitution Principle, 리스코프 치환 원칙)란 상위 객체를 하위 객체로 치환해도 정상적으로 동작해야 하는 원칙을 의미

 

예시로 A 클래스의 M1 메소드와 A클래스를 상속 받은 B클래스의 M2 메소드 (M2메소드는 M1메소드를 오버라이딩함)가 있을 때, 상위 M1 메소드에 들어오는 인자를 하위 M2메소드에 넘겨도 정상적으로 로직이 동작해야 되는 것을 의미한다.

 

 

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

ISP (Interface Segregation Principle, 인터페이스 분리 원칙) 이란 하나의 인터페이스는 그 책임에 맞는 함수만 가지고 있어야 한다는 뜻으로 SRP (단일 책임 원칙)과 유사하다.

 

둘의 차이점이라고 한다면 ISP는 대상이 Interface 라는 점이다.

 

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

DIP (Dependency Inversion Principle, 의존관계 역전 원칙)는 쉽게 말해 소스코드의 의존성은 추상화에 의존하며, 구체화에 의존하지 않는 원칙을 말한다. 

 

추상화에 의존하는 이유는 유연성이 높은 코드를 작성하기 위해서이고, 만약 현재 코드가 의존하고 있는 추상화된 부분이 새로 작성되는 코드로 인해 자주 변경이 된다면, DIP 원칙을 잘 고려하지 않은 것으로 생각 할 수 있다.

 

 

참고 문헌