////
Search
Duplicate
3️⃣

3. 소프트웨어 디자인 원칙

: 우리는 소프트웨어 설계에 관해 정말 제대로 배우지 못했다.

코드에 적용되는 설계원칙

KISS : 제발 간단하게 클래스나 메서드를 만들라는 법칙
DRY : 반복되는 기능이나 객체를 하나로 만들어서 관리하라는 법칙
YAGNI : 코드를 적어나가다 보면 갑자기 머릿속에서 떠오르는 중요한 기능이 있어서 막 적지만 결국 안 쓴다는 법칙
: 원칙이라고 이런 것들을 구호나 주문처럼 간직하면서 코드를 작성, 볼 때마다 꺼내들곤 한다.
: 이런 것들을 지키지 못하고 코드를 짜면 죄책감 마저 든다.

객체지향 프로그래밍에 적용되는 설계원칙

SRP : 각 클래스는 하나의 정보만을 책임지고 각 클래스에서 공통적인 특성을 뽑아낼 수 있다면 이는 하나의 슈퍼 클래스로 옮긴 다음 변화하는 특성만 상속이나 구현으로 처리하는 원칙
OCP : 확장에는 열려 있으며 변경에는 닫혀 있어야 한다는 원칙
LSP : 인터페이스의 서브타이핑은 인터페이스에 정의된 형태를 최대한 유지해야한다는 원칙
ISP : 인터페이스는 최소한으로 유지하라는 원칙
DIP : 상위 레벨의 모듈이나 인터페이스가 서브 클래스나 타이핑에 영향을 받아서는 안 된다는 원칙
: 위의 다섯가지 원칙은 소프트웨어의 ‘유연성, 확장성, 유지보수성’을 갖추게 해주는 원칙들, 이러한 원칙들을 지키지 않으면 디자인 악취가 발생한다고 함
⇒ 왜? 하나의 정보만 책임져야하는가? 왜 확장엔 열려있고 변경에는 닫혀있어야 하는가?

디자인 악취

경직성 : 프로그램 변경이 어려워진다. 변경하려면 시스템의 다른 부분까지 많이 변경해야하기 때문입니다.
취약성 : 프로그램을 변경하면 변경 부분과 논리적으로 아무런 연관이 없는 부분에서 장애가 발생합니다.
부동성 : 프로그램에서 재사용할 수 있는 컴포넌트로 구분하기가 어려워집니다.
점착성 : 기존 디자인에 적용된 철학이나 방식을 지속적으로 유지하는게 어렵거나 개발 환경 자체가 느리고 비효율적인 경우를 말합니다.
불필요한 복잡성 : 쓸데없는 기반 구조가 디자인에 포함되어 있습니다.
불필요한 반복 : 단일 추상 개념으로 추상화가 가능한 반복적인 구조가 디자인에 포함되어 있습니다.
불투명성 : 직접 만든 사람이 아닌 경우 다른 사람이 코드를 읽고 이해하기가 어렵습니다.
: 이는 ‘원인’이 아닌 ‘결과’다, 즉 위의 원칙들과 정확한 인과 관계를 설명해주지 않으므로 이해하기가 어렵다.

우리는 코드를 설계하는 과정에 있어서 지금까지 어떠한 결과에 대해서만 학습했다.

어떤 원인이 어째서 그러한 결과를 불러오는지 그 인과 관계를 학습하지 못했다. 이는 제대로 배우지 못한 것

디자인 악취를 위해하기 위한 가정

소프트웨어는 ‘제대로’ 디자인하고 만들기에 늘 시간과 사람이 부족하다.
소프트웨어는 한 사람이나 팀이 처음부터 끝까지 개발하지 않고 언젠가는 전혀 히스토리를 모르는 사람이 개발을 맡게 된다.
소프트웨어는 한번 만들어지고 나면 아주 오랫동안 사용된다.
이미 릴리즈된 소프트웨어는 다음 버전이나 개선 때 더 빨리 만들 수 있다고 믿는다.
소프트웨어에 세계에서 변하지 않는 건 ‘시간/사람/돈에 대한 결핍’ 외에는 아무것도 없다.
소프트웨어에 대한 요구사항은 의도적이든 아니면 자연적이든 시간이 지남에 따라 늘 변한다.
: 소프트웨어나 프로그램을 둘러싼 상황이 늘 가변적이고 리소스가 계속 부족한 상태에서 코드를 만들어 완성해야 하는 일이 세상 모든 곳에서 발생
: 많은 사람이 망각의 축복을 만끽하는 바람에 하나의 기능이나 완결된 버전의 소프트웨어를 만들고 나면 그 이후에 발생하는 많은 요구사항과 기능을 더 적은 리소스로 해결하려 함

소결론

: 소프트웨어 디자인 또는 소프트웨어 생성에는 작은 단위인 코드, 클래스 프로그래밍에 적용되는 원칙도 중요하고 그다음 단계라고 할 수 있는 객체지향 프로그래밍에 필요한 디자인 원칙도 중요하다. 하지만 이런 원칙들이 꼭 훌륭한 소프트웨어 제품으로 연결되는 것은 아니므로 소프트웨어 제품이 잘 완성될 수 있게 하는 ‘디자인 원칙’이 필요하다.

디자인이란 무엇인가?

: 디자인이란 설계다. 설계란 계획을 세움, 건축물 설립이나 토지 공사, 기계의 제작 따위에서 그 목적에 따라 실제적인 계획을 세우고 구체적으로 도면을 그려 명시하는 일
: 2번이 주로 우리가 소프트웨어 제품을 개발할 때, 적용해볼 수 있는 의미로, 그 ‘목적’에 따라 ‘실제적인 계획’을 세우고 ‘구체적으로 도면’을 그려 명시하는 일이 설계

소프트웨어 설계

: 테스트주도 개발, 동작 주도 개발, 도메인 주도 개발 개념이 들어있음.
: 대부분의 경우 개발은 코드를 만들거나 작성하는 행위 자체를 의미하기 때문에 제품 생산 기술에 더 가깝고 테스트나 동작이 주도하는 것은 아니므로 테스트는 설계의 서브 개념이거나 설계의 결과물에 가까움

소프트웨어 설계 원칙 : 통합적으로 설계하라

: 최대한 많은 정보를 기반으로 요구사항을 정리해야 한다.
명시적 소프트웨어 설계
: 명시적 소프트웨어 설계는 기본적으로 명시적으로 요구사항과 연결되는 설계, 만들 것이 명확하게 정의되기 때문에 비교적으로 단순하게 그리고 직관적으로 설계가 가능하며 테스트 및 증명도 쉬움, 기능, 성능, 유지보수, 미적 설계 4가지의 항목으로 구성됨
기능 설계
새로 만들거나 개선할 기능을 SRS(기획서) 기반으로 정의하고 기능을 만족하는지 수치적으로 증명할 수 있는 조건도 정의
대개는 이 과정에서 기능 정의와 관련된 데이터 종류, 클래스의 기능 테스트를 수행할 데이터나 방법을 정함
성능 설계
대부분의 기능 요구사항에 대응하는 설계의 결과물은 바이너리 형태가 되어서 기능을 만드는 사람과 사용자 모두 쉽게 파악할 수 있음
하지만 성능에 대한 설계를 시작하면 매우 골치아파진다. 하루에 100명 정도가 접근하는 서비스와 100만 명이 접근하는 소프트웨어의 기능은 같을 수 있다.
하지만 내부 구조는 완전히 바뀔 수 있다. 부하 분산기가 붙고 동시성을 보장하는 클래스/데이터/알고리즘이 추가되어야함
설계의 결과물로 반드시 성능과 관련된 부분들도 표시 또는 기록해야 함
유지보수 설계
다양한 환경에서의 서비스를 지원하기 위해 이런 테스트 환경을 모두 마무리한 후 릴리즈해야 한다.
이러한 설계는 배치뿐만 아니라 업그레이드, 컴퓨팅 용량 조절들도 가능하게 해야하며 유지보수에 필요한 수치적인 조건을 예상하고 정하는 일이 쉬워진다.
미적 설계
사용자에게 물리적, 심리적으로 즐거움과 편리함을 줄 수 있도록 제품을 미적으로 설계하는 것, 일반적으로 디자이너가 이 영역에서 작업
암묵적 소프트웨어 설계
서비스 지속성 설계
가용성 설계
용량 설계
연속성 설계
보안 설계
서비스 전환 설계
변환 설계
릴리즈 설계
설정 관리 설계
서비스 운영 설계
장애 대비 설계
요구 수행 설계
문제 대응 설계
서비스 개선 설계
서비스 리포팅 설계
서비스 측정 설계
서비스 레벨 설계