ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 소프트웨어 설계 5원칙 - SOLID
    IT/Design Patterns 2022. 5. 22. 16:50

    출처 : unsplash

     

    1. 개념

    - SOLID는 SRP, OCP, LSP, ISP, DIP 의 앞 글자를 딴 용어이다.

     

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

    - 책임의 기본 단위 => '객체'

    - '책임'의 의미 => '해야 하는 것' 혹은 '할 수 있는 것'

      즉, 객체에 책임을 할당할 때는 어떤 객체보다도 작업을 잘 할 수 있는 객체에 책임을 할당해야 한다는 것

    - 예) Student(학생) 클래스가 수강 과목을 추가/조회하거나 데이터베이스에 객체 정보 저장/읽기 작업을 하거나 성적표와 출석부를 출력하는 기능을 한다면.. 너무 많은 책임을 수행해야 하기 때문에 불합리하다. Student 클래스는 수강 과목을 추가/조회하는 '책임'만 수행하고 다른 기능은 다른 클래스로 넘기는 것. 이것이 '단일 책임 원칙'이다.

    - 정의: 하나의 객체에 하나의 '책임'만 부여한다.

    - 좋은 설계는 시스템에 새로운 요구사항이나 '변경'이 있을 때 가능한 영향 받는 부분이 적은 경우를 말한다.

    - 산탄총 수술 (shotgun surgery)

       하나의 총알에 여러 개의 산탄이 들어 있어 총을 쏘면 산탄이 사방으로 퍼지며 날아간다. 이를 맞은 동물은 온 몸에 여러 발의 총알을 맞은 것과 같은 상태가 되며, 의사가 산탄총을 맞은 동물을 치료하는 상황처럼 어떤 변경이 있을 때 하나가 아닌 여러 클래스를 변경해야 한다는 점에 착안한 용어.

    - 여러 개의 클래스에 책임이 분산된 경우, 변경이 생기면 클래스 하나하나를 모두 변경하지 않으면 에러가 발생한다. 

    - 주로 로깅, 보안, 트랜잭션과 같은 횡단 관심(cross-cutting concern)으로 분류할 수 있는 기능이 대표적이다. -> 해결 방안으로 관심지향 프로그래밍(Aspect-Oriented Programming, AOP)

     

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

    - 정의: 기존의 코드를 변경하지 않으면서 기능을 추가할 수 있도록 설계가 되어야 한다

    - 클래스를 변경하지 않고도(closed) 대상 클래스의 환경을 변경할 수 있는(open) 설계가 되어야 한다.

    - interface를 두고 새로운 구현체가 나오더라도 기존 클래스에 영향이 가지 않도록 함

     

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

    - 일반화 관계(속성)에 대한 이야기이며, 서브 클래스는 슈퍼 클래스에서 가능한 행위는 수행 가능해야 한다

    - 슈퍼 클래스의 인스턴스 대신에 서브 클래스의 인스턴스로 대체해도 프로그램 의미는 변화하지 않는다.

       즉, 슈퍼 클래스와 서브 클래스 사이의 행위가 '일관성'이 있어야 한다는 의미.

    - 일반화 관계는 'is a kind of 관계' 라고도 함

       ex) 원숭이 is a kind of 포유류 => 슈퍼 클래스: 포유류, 서브 클래스: 원숭이

             TV is a kind of 가전제품 => 슈퍼 클래스: 가전제품, 서브 클래스: TV

    - '포유류'는 알을 낳지 않고 새끼를 낳아 번식한다. => '원숭이'는 알을 낳지 않고 새끼를 낳아 번식한다. (LSP 만족)

    - 서브 클래스에서 슈퍼 클래스의 메서드를 오버라이드(=재정의)하면 슈퍼 클래스의 결과의 상이하게 된다.

       즉, LSP를 만족시키는 간단한 방법은 재정의(=오버라이드)하지 않는 것이다.

     

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

    - 정의: 인터페이스를 클라이언트에 특화되도록 분리시키는 원칙

     

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

    - 정의: 의존 관계를 맺을 때 변화하기 쉬운 것 또는 자주 변화하는 것보다는 '변화하기 어려운 것', '거의 변화가 없는 것'에 의존하라는 원칙

    - '변하기 쉬운 것'과 '변하기 어려운 것'은 어떻게 구분하는가? 

       => 추상적인 것은 '변하기 어려운 것'에 해당하고, 구체적인 방식/사물 등은 '변하기 쉬운 것'으로 구분한다.

    - 객체지향 관점에서는 변하기 어려운 추상적인 것을 표현하기 위한 수단으로 '추상 클래스'와 '인터페이스'를 사용한다.

    - DIP를 만족하려면 구체적인 클래스보다는 추상 클래스나 인터페이스와 의존 관계를 맺도록 설계되어야 한다.

    - DIP를 만족하는 경우, 의존성 주입(dependency injection)을 통해 변화를 쉽게 수용 가능한 코드 작성 가능

     

    'IT > Design Patterns' 카테고리의 다른 글

    [java] Factory Method 디자인 패턴  (0) 2022.07.09
    [UML] 시퀀스 다이어그램 (Sequence Diagram)  (0) 2022.06.10
    GoF 디자인패턴  (0) 2022.05.22

    댓글

Designed by Tistory.