소프트웨어 디자인 원칙들

좋은 디자인의 특징

  • 코드 재사용

    • 모든 SW 제품을 개발할 때 가장 중요한 두 가지 지표는 비용과 시간이다. 이런 개발 비용을 줄이는 가장 일반적인 방법 중 하나가 코드 재사용이다.

    • 디자인 패턴을 사용하면 SW 컴포넌트의 유연성을 높이고 재사용을 쉽게 하는데, 이 방법들은 때때로 컴포넌트들을 더 복잡하게 만든다.

  • 확장성

    • 앱의 아키텍처를 설계할 때 미래에 변경이 가능하게 하도록 노력하자.

디자인 원칙들

앱에서 변경되는 부분을 식별하고 변하지 않는 부분과 구별하라.

변화하는 내용을 캡슐화하라.

  • 메서드 수준에서의 캡슐화

    • 변경되지 않는 부분, 변경되는 부분을 구분해 메서드로 추출하자.

  • 클래스 수준에서의 캡슐화

    • 메서드 수준의 캡슐화에서 더 분리해서 같은 의도를 갖는 메서드끼리 묶어 클래스를 추출하자.

구현이 아닌 인터페이스에 의존하라

  • 구현이 아닌 인터페이스에 의존하라.

  • 구상 클래스에 의존하는 대신 추상화에 의존하라.

상속보다 합성을 사용하라

상속에는 여러 문제가 존재한다.

  • 자식 클래스는 상위 클래스의 인터페이스를 줄일 수 없다.

  • 메서드를 오버라이드할 때 새 행동이 기초 행동과 호환되는지 확인해야 한다.

  • 상속은 부모 클래스의 캡슐화를 깨뜨린다.

  • 자식 클래스들은 부모 클래스들과 밀접하게 결합한다.

  • 상속을 통해 코드를 재사용하려고 하면 병렬 상속 계층구조들이 생성될 수 있다. -- "조합의 폭발"

상속에는 합성이라는 대안이 있다.

SOLID 원칙들

로버트 마틴이 자신의 책 <소프트웨어 개발의 지혜: 원칙, 디자인 패턴, 실천방법>에서 소개한 5가지 원칙이다.

SOLID는 소프트웨어 디자인을 보다 이해하기 쉽고 유연하며 유지 관리할 수 있도록 만드는 5가지 설계 원칙에 대한 연상 기호이다.

  • 하지만 인생이 그렇듯 아무 생각 없이 적용하면 득보다 실이 많을 수 있다.

  • 프로그램이 필요 이상으로 복잡해질 수 있다.

  • 이 모든 원칙이 동시에 적용되는 성공적인 소프트웨어 제품이 있는지도 의심스럽다.

  • 항상 실용적이려고 노력하고 모든 것을 교리로 받아들이지 말자.

Single Responsibility Principle (단일 책임 원칙)

클래스는 한 가지 이유로 변경되어야 한다.

각각의 클래스가 프로그램이 제공하는 한 부분을 책임지도록 하고, 그 책임을 캡슐화해서 클래스 내부에 숨겨라.

이 원칙의 주요 목적은 복잡성을 줄이는 것이다.

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

클래스는 확장에는 열려있어야 하지만 변경에는 닫혀 있어야 한다.

이 원칙의 주요 목적은 새로운 기능을 구현할 때 기존 코드가 깨지지 않도록 하는 것이다.

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

클래스를 확장할 때 클라이언트 코드를 손상하지 않고 자식 클래스의 객체들을 부모 클래스의 객체들로 교체(치환)할 수 있어야 한다.

  • 자식 클래스의 메서드의 매개변수 유형들은 부모 클래스의 메서드의 매개변수 유형들보다 더 추상적이거나 추상화 수준이 같아야 한다.

feed(BengalCat c)
// v.s.
feed(Animal c)
  • 자식 클래스의 메서드의 반환 유형은 부모 클래스의 메서드의 반환 유형의 하위유형이거나 일치해야 한다.

  • 자식 클래스의 메서드는 기초 메서드에서 던질 거라 예상되지 않는 예외 유형들을 던져서는 안 된다. (대부분 컴파일 단계에서 잡아주는 규칙이다.)

  • 자식 클래스는 사전 조건들을 강화해서는 안 된다. (원래 작동하던 코드가 작동하지 않게 된다.)

  • 자식 클래스는 사후 조건들을 약화해서는 안 된다.

  • 부모 클래스의 불변속성들은 반드시 보존되어야 한다.

  • 자식 클래스는 부모 클래스에 있는 비공개 필드의 값을 변경해서는 안 된다.

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

클라이언트들은 자신이 사용하지 않는 메서드들에 의존하도록 강요되어서는 안 된다.

클라이언트 클래스가 불필요한 행동을 구현할 필요가 없도록 인터페이스를 적당히 작게 만들자.

Dependency Inversion Principle (의존성 역전 원칙)

상위 계층 클래스들은 하위 계층 클래스들에 의존해서는 안 된다. 둘 다 추상화에 의존해야 한다. 추상화는 세부 정보들에 의존해서는 안 된다. 세부 정보들이 추상화에 의존해야 한다.

  • 하위 계층 클래스들: 디스크 작업, 네트워크를 통한 데이터 전송, 데이터베이스 연결 등 기본 작업 구현

  • 상위 계층 클래스들: 복잡한 비즈니스 로직

Last updated