소프트웨어 디자인 원칙들
좋은 디자인의 특징
코드 재사용
모든 SW 제품을 개발할 때 가장 중요한 두 가지 지표는 비용과 시간이다. 이런 개발 비용을 줄이는 가장 일반적인 방법 중 하나가 코드 재사용이다.
디자인 패턴을 사용하면 SW 컴포넌트의 유연성을 높이고 재사용을 쉽게 하는데, 이 방법들은 때때로 컴포넌트들을 더 복잡하게 만든다.
확장성
앱의 아키텍처를 설계할 때 미래에 변경이 가능하게 하도록 노력하자.
디자인 원칙들
앱에서 변경되는 부분을 식별하고 변하지 않는 부분과 구별하라.
변화하는 내용을 캡슐화하라.
메서드 수준에서의 캡슐화
변경되지 않는 부분, 변경되는 부분을 구분해 메서드로 추출하자.
클래스 수준에서의 캡슐화
메서드 수준의 캡슐화에서 더 분리해서 같은 의도를 갖는 메서드끼리 묶어 클래스를 추출하자.
구현이 아닌 인터페이스에 의존하라
구현이 아닌 인터페이스에 의존하라.
구상 클래스에 의존하는 대신 추상화에 의존하라.
상속보다 합성을 사용하라
상속에는 여러 문제가 존재한다.
자식 클래스는 상위 클래스의 인터페이스를 줄일 수 없다.
메서드를 오버라이드할 때 새 행동이 기초 행동과 호환되는지 확인해야 한다.
상속은 부모 클래스의 캡슐화를 깨뜨린다.
자식 클래스들은 부모 클래스들과 밀접하게 결합한다.
상속을 통해 코드를 재사용하려고 하면 병렬 상속 계층구조들이 생성될 수 있다. -- "조합의 폭발"
상속에는 합성이라는 대안이 있다.
SOLID 원칙들
로버트 마틴이 자신의 책 <소프트웨어 개발의 지혜: 원칙, 디자인 패턴, 실천방법>에서 소개한 5가지 원칙이다.
SOLID는 소프트웨어 디자인을 보다 이해하기 쉽고 유연하며 유지 관리할 수 있도록 만드는 5가지 설계 원칙에 대한 연상 기호이다.
하지만 인생이 그렇듯 아무 생각 없이 적용하면 득보다 실이 많을 수 있다.
프로그램이 필요 이상으로 복잡해질 수 있다.
이 모든 원칙이 동시에 적용되는 성공적인 소프트웨어 제품이 있는지도 의심스럽다.
항상 실용적이려고 노력하고 모든 것을 교리로 받아들이지 말자.
Single Responsibility Principle (단일 책임 원칙)
클래스는 한 가지 이유로 변경되어야 한다.
각각의 클래스가 프로그램이 제공하는 한 부분을 책임지도록 하고, 그 책임을 캡슐화해서 클래스 내부에 숨겨라.
이 원칙의 주요 목적은 복잡성을 줄이는 것이다.
Open/Closed Principle (개방/폐쇄 원칙)
클래스는 확장에는 열려있어야 하지만 변경에는 닫혀 있어야 한다.
이 원칙의 주요 목적은 새로운 기능을 구현할 때 기존 코드가 깨지지 않도록 하는 것이다.
Liskov Substitution Principle (리스코프 치환 원칙)
클래스를 확장할 때 클라이언트 코드를 손상하지 않고 자식 클래스의 객체들을 부모 클래스의 객체들로 교체(치환)할 수 있어야 한다.
자식 클래스의 메서드의 매개변수 유형들은 부모 클래스의 메서드의 매개변수 유형들보다 더 추상적이거나 추상화 수준이 같아야 한다.
자식 클래스의 메서드의 반환 유형은 부모 클래스의 메서드의 반환 유형의 하위유형이거나 일치해야 한다.
자식 클래스의 메서드는 기초 메서드에서 던질 거라 예상되지 않는 예외 유형들을 던져서는 안 된다. (대부분 컴파일 단계에서 잡아주는 규칙이다.)
자식 클래스는 사전 조건들을 강화해서는 안 된다. (원래 작동하던 코드가 작동하지 않게 된다.)
자식 클래스는 사후 조건들을 약화해서는 안 된다.
부모 클래스의 불변속성들은 반드시 보존되어야 한다.
자식 클래스는 부모 클래스에 있는 비공개 필드의 값을 변경해서는 안 된다.
Interface Segregation Principle (인터페이스 분리 원칙)
클라이언트들은 자신이 사용하지 않는 메서드들에 의존하도록 강요되어서는 안 된다.
클라이언트 클래스가 불필요한 행동을 구현할 필요가 없도록 인터페이스를 적당히 작게 만들자.
Dependency Inversion Principle (의존성 역전 원칙)
상위 계층 클래스들은 하위 계층 클래스들에 의존해서는 안 된다. 둘 다 추상화에 의존해야 한다. 추상화는 세부 정보들에 의존해서는 안 된다. 세부 정보들이 추상화에 의존해야 한다.
하위 계층 클래스들: 디스크 작업, 네트워크를 통한 데이터 전송, 데이터베이스 연결 등 기본 작업 구현
상위 계층 클래스들: 복잡한 비즈니스 로직
Last updated