소프트웨어 아키텍처 - 9(SOLID Design Principle)

박승현·2023년 10월 8일
0

아키텍처

목록 보기
9/30
post-thumbnail

SOLID Design Principles

  • SOLID

The Single Responsibility Principle (SRP)

  • 클래스는 한 개의 책임을 가져야 한다
  • 클래스를 변경하는 이유는 한 개여야한다
    • 클래스가 한 개의 이유로만 변경되려면 클래스가 한 개의 책임만을 가져야함
  • 지켜지지 않은 사례
    • 데이터를 읽고 화면에 보여주는 두 개의 책임이 한 클래스에 밀접하게 결합되어 있어서 코드 수정시 연쇄적으로 코드 수정이 일어남
    • 코드를 절차 지향적으로 만들었기 때문에 변경이 어려움
    • 2개의 클래스로 책임을 분리

The Open / Closed Principle (OCP)

  • 확장에는 열려있고 변경에는 닫혀 있어야 한다
    • Open - 기능을 변경하거나 확장 가능하도록 한다.
    • Closed - 그 기능을 사용하는 코드는 수정하지 않는다
  • 상속을 활용해 상위 클래스의 기능을 그대로 사용하면서 하위 클래스에서 일부 구현을 오버 라이딩 하는 방법을 제공
    • 데이터를 압축해서 보내고 싶을때 하위 클래스에서 sendHeader, sendBody를 압축해서 보내는 기능으로 오버라이딩
    • responseSender 클래스는 확장에는 열려있으면서 변경에는 닫혀있게됨
  • 개방 폐쇄 원칙을 어기는 코드
    • 다운 캐스팅
      • character 파라미터의 타입이 Missile인 경우 별로 처리하는데 이 함수는 Character 클래스가 확장될 때 함께 수정되어야 함
      • 변경에 닫혀 있지 않다
    • 비슷한 if-else 블록이 존재
      • 새로운 경로를 추가할 경우 draw 메서드에 새로운 if블록이 추가됨 -> 경로를 추가하는데 Enemy 클래스가 닫혀 있지 않다.
      • pathpatter의 추상화 타입을 사용해 새로운 경로를 추가할때 Enemy의 draw메서드는 변경되지 않고 pathpattern 클래스만 추가해주면 됨

The Liskov Substitution Principle (LSP)

  • 리스코프 치환 원칙
  • 개방 폐쇄 원칙을 받쳐주는 다형성에 관한 원칙 제공
  • 상위 타입의 객체를 하위 타입의 객체로 치환해도 상위 타입을 사용하는 프로그램은 정상적으로 동작해야한다

  • addTaxes()함수가 ITaxCalculatorAdapter의 구체적인 구현에 의존하지 않고, 어떤 종류의 세금 계산기 구현체를 전달하더라도 올바르게 동작해야 한다는 것을 의미

리스코프 치환 원칙 위배 사례

  • 직사각형, 정사각형
    • 여기서 직사각형에 width와 height를 비교해 높이를 더 길게 만드는 기능을 제공하면 정사각형의 setheight는 두 값을 같게 만들기 떄문에 해당 헤더스를 실행하더라도 높이가 더 길어지지 않는다
    • 이를 해결하기 위해 정사각형에 해당하는 타입이 들어오면 새롭게 구현하는 것은 리스코프 치환원칙을 위반하면서도 Rectangle의 확장에 열려있지 않게 됨
    • 실제 구현에서는 정사각형을 직사각형의 상속을 받기보다 별개의 타입으로 구현해주는 것이 좋음
  • 상위 타입에서 지정한 리턴 값의 범위에 해당하지 않는 값을 리턴하는 것
    • 입력 데이터를 읽어 출력 스트림에 복사하는 기능 구현
    • CopyUtil.copy()는 inputstream의 read()가 -1일때 반복문을 멈춤
    • SatanlnputStream의 read() 메서드는 데이터가 없을때 0을 리턴하기 때문에 실행이 끝나지 않는다
  • 특정 타입을 사용하는 코드에서는 다른 타입이 존재하는지 알 필요 없이 상위타입만 사용해야 한다
    • 코드에서 SpecialItem의 존재여부를 알 필요가 없어야함
    • 아이템 클래스에서 구현
    • 코드에서는 instanceof 연산자를 제거하고 메서드만 사용
  • 리스코프 치환 원칙 정리

The Interface Segregation Principle (ISP)

  • 인터페이스는 사용하는 클라이언트를 기준으로 분리해야 한다
  • 클라이언트는 자신이 사용하는 메서드에만 의존해야 함

  • 단일 책임 원칙이 지켜지면 인터페이스와 클래스의 재사용 가능성이 향상됨
  • 클라이언트 입장에서 인터페이스를 분리한다는 것이 중요한 관점

The Dependency Inversion Principle (DIP)

  • 고수준 모듈은 저수준 모듈의 구현에 의존하면 안됨
  • 저수준 모듈이 고수준 모듈에 의한 추상 타입에 의존해야함

  • 의존 역전 원칙을 적용해 클래스가 추상화 타입에 의존하게 만듬
  • 코드에서의 의존은 역전 되었지만 런타임에서의 의존은 고수준에서 저수준으로 향함
  • 런타임이 아닌 코드에서 의존을 역전시킴으로써 변경의 유연함을 확보
  • 타입의 소유도 역전 시킴
    • 각 패키지를 독립적으로 배포할 수 있도록 만들어준다
  • 개방 폐쇄 원칙을 클래스 수준뿐만 아니라 패키지 수준까지 확장시켜준다

profile
KMU SW

0개의 댓글