본문 바로가기
SW 공부/Design Patterns

SOLID PRINCIPLES

by 꼬냉상 2022. 8. 23.

Hierarchy of Pattern Knowledge

패턴 지식의 계층화

- Design Pattern은 OO Principle (설계 원칙을 따른 것)이고, 그 OO Basic(기본) 개념이 아래에 있다.

예시)

 

Design smells 

- various signs and symptoms of bad design (디자인 불량 징후 및 증상)

- Rigidity(경직성), Fragility(취약성), Immobility(부동성), Viscosity(점착성), Needless Complexity (불필요한 복잡성), Needless Repetition (불필요한 반복), Opacity(불투명성)

- Design smells are resulted from mismanaged dependencies (spaghetti code)

 

SOLID principles by R.C. Martin

The Single-Responsibility Principle (SR.P)

- 단일책임 원칙 : 모든 클래스는 각각 하나의 책임만 가져야 한다. 클래스는 그 책임을 완전히 캡슐화해야 함을 말한다.

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

- A class should have one, and only one, reason to change
소프트웨어 모듈은 변경의 이유가 단 하나여야만 한다.

 변경의 이유가 단 하나여야만 한다라는 것은 하나의 모듈은 오직 하나의 액터만 책임져야 한다는 뜻

→ 소스 파일에 다양하고 많은 메서드를 포함하고 서로 다른 액터를 책임진다면 병합이 발생할 가능성은 높아짐
=> 이 문제를 해결하는 방법은 서로 다른 액터를 뒷받침하는 코드를 분리하는 것!

 

The Open-Closed Principle (OCP)

- 개방-폐쇄 원칙  : 확장에는 열려있고 수정에는 닫혀있는. 기존의 코드를 변경하지 않으면서( Closed), 기능을 추가할 수 있도록(Open) 설계가 되어야 한다는 원칙을 말한다.

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

- 확장에는 열려있고, 수정은 적게!

- Software entities (classes, modules, functions, etc.) should be open for extension but closed for modification
→  소프트웨어 개체는 확장에 열려 있어야 하고, 변경에는 닫혀 있어야 한다.

→  소프트웨어 개체의 행위는 확장될 수 있어야 하지만, 이때 개체를 변경해서는 안된다는 원칙

=> Abstraction is the key!

 

The Liskov Substitution Principle (LSP)

- 리스코프의 치환 원칙 : 자식 클래스는 언제나 자신의 부모 클래스를 대체할 수 있다는 원칙이다. 즉 부모 클래스가 들어갈 자리에 자식 클래스를 넣어도 계획대로 잘 작동해야 한다.

자식클래스는 부모 클래스의 책임을 무시하거나 재정의하지 않고 확장만 수행하도록 해야 LSP를 만족한다.

- Subtypes must be substitutable for their base types

→ 프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀수 있어야 한다.

- LSP를 상속을 쓸지 말지의 근거로 사용!

- 상속을 써서 하위 타입이 항상 대신할 수 있는지 확인 → 아니면 composition 고려

→  상호 대체 가능한 구성요소를 이용해 SW를 만들 때, 이들 구성 요소는 반드시 서로 치환 가능해야 한다.

The Interface Segregation Principle (ISP)

- 인터페이스 분리 원칙 : 한 클래스는 자신이 사용하지않는 인터페이스는 구현하지 말아야 한다. 하나의 일반적인 인터페이스보다 여러개의 구체적인 인터페이스가 낫다.

- Clients should not be forced to depend on methods they do not use

- Fat interface→  Break the interface into cohesive groups (응집력 있는 그룹으로 나눠라)

→  사용하지 않는 것에 의존하지 말아야 한다.

→  인터페이스 분리 원칙은 클래스에 의해 구현되는 더 작고 더 구체적인 일련의 인터페이스를 작성해야 한다고 명시

→  쉽게 말해, 필요 이상으로 많은 걸 포함하는 모듈은 인터페이스를 분리해서 동작을 제공해야 한다!

 

The Dependency Inversion Principle (DIP)

- 의존 역전 원칙 : 의존 관계를 맺을 때 변화하기 쉬운 것 또는 자주 변화하는 것보다는 변화하기 어려운 것, 거의 변화가 없는 것에 의존하라는 것이다. 한마디로 구체적인 클래스보다 인터페이스나 추상 클래스와 관계를 맺으라는 것이다.

- High-level modules (Interfaces and abstract classes) should not depend on low-level modules(Concrete classes). Both should depend on abstractions

  Client (upper-level) layer가 owns the interface, not th low-level-layers.
  고수준 정책을 구현하는 코드는 저수준 세부사항을 구현하는 코드에 절대 의존해서는 안 된다.

  의존성 역전 원칙은 구체적이며 변동성이 큰 코드는 절대로 언급하지 말아야 한다는 것입니다.

  유연성이 극대화된 시스템은 소스 코드 의존성이 abstraction에 의존하며 concretion에는 의존하지 않는 시스템

  더 구체적으로 말하면 import, include와 같은 구문은 인터페이스나 추상 클래스 같은 추상적인 선언만을 참조해야 한다는 뜻

Design Principles

- 설계 원리

- Help manage dependency
- Better maintainability, flexibility, robustness, and reusability

-  Abstraction is important

 

 

Quiz) LSP에 대한 설명으로 옳지 않은 것은?

1. 클래스 간 상속관계가 올바른지 체크해 볼 수 있는 원칙이다.

2. 문법적 규칙이기 때문에 위반하면 컴파일러가 에러를 검출한다.

3. LSP를 위반하는 경우 상속 대신 객체 합성(object composition)을 고려해 볼 수 있다.

4. 부모 클래스의 인스턴스 대신에 자식 클래스의 인스턴스가 쓰일 수 있어야 한다는 의미이다.  

 

Quiz) 다음 각 문장이 옳은지 O/X 로 답하시오

- (X) 모듈 설계에 OCP를 적용하면 일반적으로 수행 속도가 향상된다

- (O) OCP를 위반하면 다른 설계 원칙이 또한 위반되는 경우가 있다

- (X) 코드상에서 제작자의 의도를 알기 어렵게 만드는 것은 캡슐화 (Encapsulation)에 해당한다.

- (X) SOLID 원칙은 아키텍쳐 설계에는 적용되기 어렵고 상세 설계에만 유용하다.

- (O) 설계 원칙의 준수는 바람직한 모듈간 의존관계로 이끌어준다.

- (X) SOLID 설계 원칙 중에서도 OCP는 특히 중요하기 때문에 모든 모듈의 설계에서 항상 지켜야 한다. 

- (O) 템플릿 메쏘드(Template Method) 패턴은 OCP를 적용한 예이다.
- (X) 장식자(Decorator) 패턴에서 ISP를 적용했기 때문에 새로운 장식자의 추가가 쉽다.
- (X) 단일체(Singleton) 패턴에서 객체의 생성을 제어하는 것은 ISP의 적용 예이다.

 

Quiz) ClassB를 ClassA로부터 상속하여 만들었다. (즉, ClassA는 ClassB의 super class 혹은 parent class). 메쏘드 m은 다음과 같이 ClassA타입의 파라미터를 받는데, 해당 파라미터에 ClassB 인스턴스를 전달하면 제대로 동작하지 않기 때문에 ClassB인스턴스가 들어오면 예외 처리를 하고 있다. 이 설계에서 위반된 SOLID 설계원칙은?

- LSP (Liskov Substitution Principle/ 리스코프의 치환 원리 )

 

Quiz) "클래스는 변화하기 쉬운 것보다 변화하기 어렵거나 거의 변화가 없는 것에 의존 관계를 맺어야 한다" 와 가장 관련 있는 SOLID 설계 원칙은?

- Dependency Inversion Principle (DIP) / 의존 역전 원칙

 

본 글은 개인의 S/W 구조설계 역량 강화를 위한 학습 목적으로 정리된 내용입니다.
일부 타/개인 단체에 저작권이 있는 자료를 포함하고 있으므로, 절대 영리 목적으로 사용하실 수 없습니다.

 

반응형

댓글