아키텍처 설계가 후순위가 된다면 시스템을 개발하는 비용이 더 많이 들고, 일부 또는 전체 시스템에 변경을 가하는 일이 현실적으로 불가능해진다. 이렇나 상호아이 발생하도록 용납했다면, 이는 결국 소프트웨어 개발팀이 스스로 옳다고 믿는 가치를 위해 충분히 투쟁하지 않았다는 뜻이다.
소프트(soft) 웨어(ware) 부드러운 제품이라는 뜻으로 동작하는 방향을 쉽게 변경할 수 있어야 한다.
그렇지 못한다면 하드(hard) 웨어(ware) 라고 불려야 할 것이다.
무분별한 점프(goto 문장)는 프로그램 구조에 해롭다는 사실을 직시하고 구조적으로 프로그래밍을 해야 한다고 생겨난 패러다임, if/then/else, do/while/until 등이 생겨났다.
구조적 프로그래밍에서는 증명 가능한 세부 기능 집합으로 재귀적으로 분해할 것을 강요한다. 그러고 나서 테스트를 통해 증명 가능한 세부 기능들이 거짓인지를 증명하려고 시도한다. 이처럼 거짓임을 증명하려는 테스트가 실패한다면 이 기능들은 목표에 부합할 만큼은 충분히 참이라고 여길 수 있는 것이다.
그러나 아무곳으로나 이동이 가능한 무분별한 점프는 재귀적 함수가 불가능하게 만든다. 또한 프로그램의 테스트를 불가능하게 만든다. 프로그램이 잘못됐는지 증명하기 위해 테스트를 진행하는데, 그런 테스트를 할 수 조차 없게 만드는 goto문은 현재 프로그래밍에서는 잘못된 방향인 것이다.
소프트웨어 아키텍트는 모듈, 컴포넌트, 서비스가 쉽게 반증 가능하도록(테스트 하기 쉽도록) 만들기 위해 분주히 노력해야 한다.
절차적 프로그래밍(C)에서 관행적으로 사용되던 캡슐화나 다형성 같은 개념들을, 언어 차원에서 class라는 문법으로 체계화하여 프로그래머가 더 안전하고 일관되게 사용하도록 유도(또는 강제)하는 패러다임
기존 언어(C 언어)도 캡슐화나 다형성을 구현할 수 있었다. 그러나 언어가 제공하는 기능이 아니기에 한계가 명확했다. 그렇기에 사용하지 않는 프로그래머도 많았고 사용하지 않으면 프로그래밍에 많은 문제가 생기게 되었다(캡슐화 하지 않아 변경되면 안 되는 변수가 변경된다거나, 다형성을 구현하지 않아 비슷한 코드가 수도 없이 많아지는 등). 그래서 객체 지향 프로그래밍에서는 캡슐화, 다형성을 더 쉽게 구현할 수 있도록 해주고 이를 강제할수도 있게 해준다.

절차지향적 프로그램들은 위와 같은 모습이었다. 갖아 상위 함수가 여러 다른 함수들을 호출하는 전형적인 트리구조이다. 이러한 제약 조건은 소프트웨어 아키텍트가 선택할 수 있는 선택지를 줄게 만든다.

그러나 객체지향에서는 인터페이스를 통해 호출하는 함수와 호출 당하는 함수가 모두 하나의 인터페이스를 의존하게 만든다. 또한 소스 코드가 인터페이스를 구현하면서 인터페이스를 의존하게 되는데 이를 의존성 역전이라고 부른다.
이렇게 기존에 정해진대로 흘러가는 의존성이 아닌 의존성을 반대로 역전시키면서 개발자는 선택할 수 있는 아키텍트의 폭이 넓어지게 되는 것이다. 이렇게 다형성을 이용하여 소스 코드 의존성에 대한 절대적인 제어 권한을 갖는 것이 객체지향이다.
변수의 값이 계속 변하는 것을 방지하기 위해 재할당을 없애자는 패러다임, 불변성으로 심볼의 값이 변경되지 않게 만든다는 개념이다. 함수형 프로그래밍에서 변수는 한 번 할당이 되면 그 값이 절대 변하지 않는다.
변수의 값이 변함으로 인해 경합, 조건, 교착상태, 동시 업데이트 등의 많은 문제가 생긴다. 만약 어떤 변수도 갱신되지 않는다면 이런 문제가 일어나지 않는다. 그러나 완전한 불변성은 실현 가능하지 않다. 우리의 자원은 한정되어 있기 때문이다. 그렇기에 다음과 같은 개념들이 나온다.
가변성 분리

위 세 가지 프로그래밍 패러다임은 모두 개발자에게 새로운 권한을 부여하기는 커녕 권한을 박탈하는데 목적을 둔다. 즉 패러다임은 무엇을 해야 할지를 말하기 보다는 무엇을 해서는 안 되는지를 말해준다.
단일 모듈은 변경의 이유가 하나, 오직 하나뿐이어야 한다.

위 클래스는 SRP를 위반한다. 왜냐하면 CFO 보고를 위해 사용되는 calculatePay(), COO 보고를 위해 사용되는 reportHours(), CTO 보고를 위해 사용되는 save() 총 3개의 서로 다른 엑터가 하나의 객체로 통합되었기 떄문이다.
만약 caculatePay(), reportHours() 함수의 코드가 겹치는 부분이 있어 개발자가 regularHours()라는 함수로 분리해서 두 개의 함수가 하나의 함수를 의존하는 상황일때 CFO 팀에서 초과 근무를 제외한 업무 시간을 계산하는 방식을 수정하기 위해 regularHours() 함수를 수정하게 되면 그 영향이 COO 팀에서 사용하는 reportHours() 함수에도 가게 되고 이는 큰 에러를 일으키게 된다.
그뿐만 아니라 이렇게 서로 다른 엑터가 하나로 묶여있다면 코드를 수정하고 병합하는 과정에서도 에러가 생기게 된다. CFO 팀에서 코드를 수정하고 CTO 팀에서 코드를 수정했을때 두 개의 코드가 충돌은 나겠지만 결국 병합 될 것이고 그 병합으로 인해 이상한 코드가 탄생하게 될 것이다.
해결책

아무런 메서드 없는 간단한 데이터 구조인 EmployeeData 클래스를 만들어서 세 개의 클래스가 공유하도록 한다. 각 클래스는 서로의 존재를 몰라야 한다.
그러나 이런 경우 개발자가 세 가지 클래스를 인스턴스화 하고 추적해야 한다는 단점이 있다.

그런 경우 Facade 패턴을 적용하여 문제를 해결한다.
public class EmployeeFacade {
private final PayCalculator payCalculator = new PayCalculator();
private final HourReporter hourReporter = new HourReporter();
private final EmployeeSaver employeeSaver = new EmployeeSaver();
private final EmployeeData employeeData; // 예시 데이터
public EmployeeFacade(EmployeeData employeeData) {
this.employeeData = employeeData;
}
// 클라이언트에게 제공되는 단순화된 메서드
public void calculatePay() {
payCalculator.calculatePay(this.employeeData);
}
public void reportHours() {
hourReporter.reportHours(this.employeeData);
}
public void save() {
employeeSaver.saveEmployee(this.employeeData);
}
}
public class Client {
public static void main(String[] args) {
EmployeeData data = new EmployeeData();
EmployeeFacade facade = new EmployeeFacade(data);
// 클라이언트는 파사드의 단순한 메서드만 호출하면 된다.
facade.calculatePay();
facade.save();
}
}
즉 모듈을 변경할때 변경의 이유가 하나여야 한다는건 변경하는 주체도 하나여야 한다는 것이다.
소프트위에 개체는 확장에는 열려 있어야 하고, 변경에는 닫혀 있어야 한다.


보호의 계층 구조가 수준이라는 개념을 바탕으로 어떻게 생성되는지 바라보면 Interactor는 가장 높은 수준의 개념이며 따라서 최고의 보호를 받고 View는 가장 낮은 수준의 개념으로 거의 보호를 받지 못한다.
아키텍처 수준에서 OCP가 동작하는 방식은 기능을 어떻게, 왜, 언제, 발생하는지에 따라서 분리하고 분리한 기능을 컴포넌트의 계층구조로 조직화한다. 그리고 저수준 컴포넌트에서 발생한 변경이 고수준 컴포넌트에 영향이 없어야 한다.



System S ---> Framework F ---> Datbase D
시스템 S가 F라는 프레임워크를 사용하고 F라는 프레임 워크는 D라는 데이터베이스를 사용한다고 가정하면 시스템 S와 아무런 상관도 없는 기능이 D에서 변경될 경우 F를 재배포해야 하고 그로 인해 S까지 재배포해야 한다. 이러한 상황을 위해 인터페이스로 분리하는 것이 좋다.
위 규칙들은 모두 구체 클래스, 구체 함수 등 구체화 된 것에 의존하지 말고 항상 추상화 된 것에 의존하라는 말이다. 그러나 여기서 말하는 구체적인 것은 그냥 구체적이만 한 것이 아니라 구체적이면서 변동성도 큰 클래스를 말한다.

| ⌈책 리뷰⌋ 메이오 오신 ⎹ 러닝 랭체인 ⎹ 2부 (1) | 2025.10.03 |
|---|---|
| ⌈책 리뷰⌋ 메이오 오신 ⎹ 러닝 랭체인 ⎹ 1부 (0) | 2025.09.24 |
| ⌈책 리뷰⌋ 찰스 두히그 ⎹ 습관의 힘 ⎹ ⭐️ (4) | 2025.07.29 |
| ⌈책 리뷰⌋ 제임스 클리어 ⎹ 아주 작은 습관의 힘 ⎹ (4) | 2025.07.08 |
| ⌈책 리뷰⌋ 미하이 칙센트미하이, ⎹ 몰입의 기술 ⎹ ⭐️ (0) | 2025.04.22 |