공부/설계

[OOP 설계 원칙]SOLID 원칙

개발의 피 2023. 11. 25. 01:07

(클린 코드 - 로버트 C. 마틴)

+) 데메테르 법칙(최소 지식의 원칙) : SOLID 원칙에 포함 x, 객체 지향 설계에서 매우 중요 

-> 직접적인 친구(클래스)와만 관련한다. (= 친구의 친구와는 놀지 말기) 

=> 자기 자신, 자신이 가지는 클래스, 매개 변수로 전달한 클래스, 멤버 함수 내부에서 실체화한 클래스

 

1. SRP(Single Responsibility Principle, 단일 책임 원칙) : 클래스를 변경해야할 이유는 한 가지여야 한다

하나의 클래스는 하나의 책임만 가져야 한다 (클래스의 응집도와 관련)

=> 책임이 하나뿐인 응집도 높은 클래스 만들기! 

 

2. OCP(Open-Closed Principle, 개방·폐쇄 원칙) : 소프트웨어의 구성 요소는 확장에 관해서는 열려있어야 하고, 변경에 대해서는 닫혀있어야 한다 

변화하지 않는 부분(닫힌 부분, 부모 클래스)과 변화하는 부분(열린 부분, 자식 클래스) 분리하여 설계하기

  닫힌 부분 열린 부분
상속 부모 클래스 자식 클래스
추상 인터페이스 추상 인터페이스를 사용하는 클래스 추상 인터페이스를 구현하는 클래스

=> 닫힌 부분을 변경하지 않아도, 열린 부분을 변화시키면 확장시킬 수 있음 (재사용 구조와 관련)

 

3. LSB(Liskov Substitution Principle, 리스코프 치환 법칙) : 파생 자료형은 기본 자료형과 치환할 수 있어야 한다

부모 클래스로 치환한 상태에서도 정상 작동해야 한다

정확한 상속 관계 구현 = 원칙 위배 x / 상속 관계가 복잡해지면 이 원칙을 위반하는 클래스 만들어질 가능성 커짐

다중 상속 or 깊은 상속 관계 만드는 일 되도록 피하기 

=> 상속보다는 이양을 우선! (상속에 의존한 설계 x)

 

cf. C#

- 다중 상속 : 불가능 

- 다중 인터페이스 : 가능

- 상속 vs 이양 관련 글

https://snowdeer.github.io/c++/2016/04/24/inheritance-and-composition/

 

Inheritance vs Composition · snowdeer's Code Holic

Inheritance vs Composition 24 Apr 2016 | C++ CleanCode 개발을 하다보면 남발하는 것 중 하나가 ‘상속(Inheritance)’입니다. 여러 클래스가 있을 때 공통되는 부분을 부모 클래스로 만들어서 상속으로 구현하

snowdeer.github.io

- composition 관련 개념 :  인터페이스, DI(상속성 주입), 컴포지션(다른 클래스 필드에 선언), 대리자(delegate), 이벤트

 

https://yeko90.tistory.com/entry/c-%EC%9D%98%EC%A1%B4%EC%84%B1-%EC%A3%BC%EC%9E%85dependency-Injection

 

[c#] 의존성 주입(dependency Injection) 이란?

의존성 주입에 대한 추상적인 정의는 일단 접어두고 의존성 주입이라는 낯선 개념이 왜 필요한지 먼저 알아보겠습니다. 이 글을 읽기 전 선수 지식 포스팅 [c#] 업 캐스팅이란? [c#] 인터페이스란?

yeko90.tistory.com

 

4. ISP (Interface Segregation Principle, 인터페이스 분리 원칙) : 클라이언트가 사용하지 않는 멤버 함수의 의존을 클라이언트에 강요하면 안 된다

클래스 사용자에게 불필요한 인터페이스는 공개하지 말라

=> 클래스는 최소한의 멤버 함수로만 구성되어야 (멤버 함수가 많은 큰 클래스일수록 원칙 위반 쉬움)

 

cf. 범용적으로 쓸 수 있게 설계된 클래스 = 다수의 멤버 함수 보유

-> 필요한 멤버 함수만으로 한정한 전용 클래스를 따로 만들어 간접적으로 사용하기

 

5. DIP (Dependency Inversion Principle, 의존 관계 역전 원칙) : 상위 모듈은 하위 모듈에 의존하지 않는다, 두 모듈 모두 별도의 추상화된 것에 의존한다 

문제 : 상위 모듈이 하위 모듈에 직접 결합 -> 하위 모듈의 변경이 상위 모듈에 영향을 미침

=> 상위 모듈/하위 모듈 관계를 역전시켜 소결합하기 

 

1) 상위 레벨 모듈의 요구에 맞춰 추상 인터페이스 작성

2) 상위 모듈이 소유한 추상 인터페이스를 거쳐 하위 모듈 사용 

 

프로그램 전체를 계층화, 분리할 때 사용