"소프트웨어를 만든 이유는 기계의 행위를 쉽게 변경할 수 있도록 하기 위해서다."
시시각각 변화하는 요구사항으로 소프트웨어의 본질은 변화한다.이러한 소프트웨어가 쉽게 변화할 수 있도록 만드는 것이 소프트웨어 개발자의 사명이다.소프트웨어 개발자는 유연한 소프트웨어를 위해 적절히 코드를 나누고, 적절한 곳에 책임을 주어 나누어진 코드끼리 적절한 의존성을 가지게 해야한다.
작업의 정도와 상관없이 요구사항은 언제나 바뀔 수 있다.이때문에 불분명한 요구사항들은 불분명한 채로 나두어 나중에 이를 선택하여(view model) 쉽게 반영(view) 할 수 있도록 좋은 아키텍처와 좋은 설계가 필요로 하다.
쉽게 변화하는 소프트웨어를 만드는 방법1. 바꾸어야 할 부분을 쉽고 명확하게 파악할 수 있어야 한다.2. 변경이 최소한으로 일어나야 한다.
프로젝트의 전체적인 설계도여러 가지 컴퓨터 구성 요소들에 대한 전반적인 기계적 구조를 설계하는 방법
"하나의 서비스가 어떻게 구성이 되며 동작되는지 서비스의 동작 원리를 나타내는 것"
시스템의 구조(structure), 행위(behavior), 뷰(views)를 정의하는 개념 모델이다.시스템의 목적을 달성하기 위해 각 컴포넌트가 어떻게 상호작용하고 정보가 어떻게 교환되는 지를 설명한다.

⬅️(좌) 스파게티 아키텍쳐 / 클린아키텍쳐 (우)➡️
깔끔하고 직관적인 설계도로 클린 아키텍쳐가 많이 쓰여지고 있다.

좋은 아키텍처는 이 영역 간의 "경계"(중요한 것과 중요하지 않은 것)를 잘 긋는거부터 시작된다.
컴포넌트 사이에 클래스나 파일을 분리한다.코드가 물리적으로 나누어지고 관리가 쉬워진다.
=> 외부로 부터 영향을 받지 않으며 모든 면에서 독립적인 사용이 가능해서 유지보수가 편리하다.

layer는 Business Rules(비즈니스 로직이 들어가는 핵심기능)이 존재하는 영역이다.예를들어, 쇼핑몰은 상품만 팔고 번역앱은 번역을 하는 것. 이처럼 비즈니스 본질과 핵심기능이이 쉽게 바뀌지 않으므로 Business Rule은 잘 변하지 않는 안정된 영역이다.추상화된 개념(데이터를 저장한다, 비용을 정산 한다.)
layer는 UI, Database, web APIs, Frameworks 등이 존재하는 영역이다.추상화된 개념을 실제 어떻게 구현할지에 대한 세부 개념이다.예를들어, 쇼핑몰 상품 구입에 대한 비용 정산을 실행 시킬 버튼 UI. UI버튼 모양은 수시로 변경 가능. 저수준 정책
(inner circle 에 해당하는 Domain과 outer circle 에 해당하는 Infrastructure 사이에 경계가 생겨 도메인은 인프라에 대해서 아무것도 모른다)
요소들간의 경계로 이루어진 클린아키텍쳐

도메인의 영역인(코어영역) entity, use case 그리고 View영역인 최상층 Infrastructure, 이 두가지 계층 사이를 이어주는 adaptor가 있다.
// 데이터 구조 Movie가 Entities이다.
struct Movie: Equatable, Identifiable {
typealias Identifier = String
enum Genre {
case adventure
case scienceFiction
}
let id: Identifier
let title: String?
let genre: Genre?
let posterPath: String
let overview: String?
let releaseDate: Date? } struct MoviesPage: Equatable {
let page: Int
let totalPages: Int
let movies: [Movie] }
이렇게 관심사를 분리 한 규칙을 의존성 규칙으로 설명할 수 있다.
Dependency rule (종속성 규칙)
Abstraction principle (추상화 원리)
SOLID (객체 지향 설계 원칙)
SRP - 단일 책임 원칙: 한 클래스는 하나의 책임만 가져야 한다.
OCP - 개방-폐쇄 원칙: 소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다.
LSP - 리스코프 치환 원칙: 프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다.
ISP - 인터페이스 분리 원칙: 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다.
DIP - 의존성 역전 원칙: 프로그래머는 추상화에 의존해야지, 구체화에 의존하면 안된다