외부 세부사항이 도메인 코드에 영향을 미치는 것을 막아야 하는 이유테스트 방해: 외부 세부 사항은 구성 요소를 모의 객체(Mock)로 교체하여 테스트하는 것을 어렵게 만듭니다.예제 코드: 테스트가 어려운 코드 vs 쉬운 코드// Worst: 메서드 내부에서 직접 외부 라이브러리 객체를 생성 (테스트 불가)public class UserService { public void createUser(String name) { // 외부 라이브러리에 강하게 결합되어 Mocking이 어려움 ThirdPartyAuthClient client = new ThirdPartyAuthClient("api-key"); client.register(name); }}// Best:..
전체 글
아주 그냥 얕고 얕고 얕게, 그러나 필요한 정보는 담는추상화에 대한 여러가지 정의개념, 기능, 프로세스를 설명하되, 클라이언트가 내부 메커니즘을 알지 못해도 이해할 수 있는 방식입니다.본질적인 특성에 집중하고, 비본질적인 특성은 무시합니다.구체적인 구현에 신경 쓰지 않습니다.5.1 추상화와 확장 지점을 디자인하라추상화의 필요성 식별하기다양한 변형이 필요한 기능일 때 도입합니다.조합성 면에서 유연함이 필요한 기능일 때 도입합니다.향후 변경이 예상되는 부분에 도입합니다.시스템의 나머지 부분에서 숨기고 싶은 결정이나 코드가 있을 때 도입합니다.확장 지점 디자인하기다양한 할인 정책(정액 할인, 정률 할인, 특정 기간 할인 등)을 기존 코드 수정 없이 확장할 수 있도록 설계합니다.// 고수준 추상화: "무엇"을 할 것인가 (할인 금액 계산)interface Disc..
4.1 고수준 코드와 저수준 코드를 분리하라장점코드를 유지보수할 때 고수준 코드부터 시작하면 기능을 더 빠르게 이해할 수 있다.고수준 코드는 어떻게(How) 가 아니라 무엇(What) 을 다루기 때문이다.고수준 코드와 저수준 코드를 분리하면 각각 따로 변경하고 발전시킬 수 있다.고수준 코드는 일반적으로 더 추상적이고, 결과적으로 더 안정적이다.요약하자면, DI(Dependency Injection)에 관한 내용이다.그렇다고 모든 기능을 고수준, 저수준으로 분리할 필요는 없다.기능의 복잡성과 관계없이, 절대 섞지 말아야 할 것은 인프라 코드와 비즈니스 코드이다.비즈니스 로직이 SQL 쿼리나 웹 서비스에서 가져오는 HTTP 호출 코드와 섞이지 않도록 해야 함.예제 코드: 이커머스 결제 수단 활용// 고수준 ..
3.1 항상 일관성을 유지하라캡슐화를 쉽게 만드는 패턴클래스가 스스로 일관성을 책임지게 하라일관성 검사는 반드시 클래스 내부에 구현되어야함.예를 들어 Offering 이라는 클래스는 허용된 최대 참가수 수를 초과하지 않도록 보장해야 한다.빈 자리를 줄이는 작업도 Offering 클래스 내에서 이뤄져야한다.전체 작업과 복잡한 일관성 검사를 캡슐화 하라DB의 테이블을 참고해야하는 것과 같이 상황 따라서 객체만으로 일관성을 유지하기 힘들 수 있다.그래서 주석으로 개발자가 히스토리를 파악할 수 있게 주의하라고 한다.3.2 효과적인 데이터 유효성 검사 메커니즘을 디자인하라데이터 유효성 검사를 처리하는 방법사전 조건은 코드 단위가 올바르게 실행되기 위한 최소 요구사항을 나타낸다. 예를 들어 '이 속성은 null이 ..
2.1 코드 단위를 작게 만들라비즈니스 규칙을 빠르게 반영할 때 흔히 쓰이는 빠른 임시방편은 기존 메서드에 코드를 덧붙이거나 클래스에 메서드를 추가하는 식으로 코드를 추가하는 것이다.아무리 잘 디자인한 클래스나 메서드도 몇 천줄이 되면 유지보수가 쉽지않다.언제 코드를 메서드와 클래스로 나눌지 정하는 몇 가지 휴리스틱을 살펴보자.2.1.1 복잡한 메서드를 비공개 메서드로 나눠라응집도가 높은 클래스나 메서드는 하나의 명확한 책임을 가진다. 응집도가 높을 수록 코드가 단순해진다.비공개 메서드는 자신이 선언된 클래스 내부에서만 호출할 수 있는 메서드를 말한다. 아래와 같은 요소들로 비공개 메서드를 도입하는 게 적합한지, 코드 세그먼트가 독립된 단위를 될 수 있는지를 결정할 수 있다.새 비공개 메서드의 목적을 설..
1.1 객체지향 디자인과 시간이 주는 시련개발자들은 아래와 같은 객체지향에 관한 고민을 한다.이 구현이 충분히 단순한가 ? 아니면 더 추상화 해야하나 ?클래스가 생명 주기상 여러 가지 상태를 거치는데 어떻게 이 클래스의 인스턴스 들이 일관된 상태를 유지 및 보장할까 ?내 시스템과 외부의 웹 앱 사이의 상호작용을 어떻게 모델링 할까 ?단순한 디자인을 만들기도 어렵지만, 계속 단순한 디자인을 유지해나가는 것도 어렵다.1.2 단순한 객체지향 시스템 디자인여전히 소프트웨어 시스템의 유지보수성은 어렵다.본질적으로 유지 보수성이란 비즈니스 규칙 수정, 기능 추가, 버그 확인, 시스템 패치 같은 작업을 완료하기 위해 투입하는 노력임유지 보수성에 영향을 미치는 요소는 복잡한 코드, 의존성 관리, 잘못 디자인된 추상화,..
1.1 시스템 설계의 정의1.1.1 소프트웨어 시스템특정 작업이나 일련의 작업을 수행하려고 함께 동작하는 컴포넌트나 모듈, 프로그램의 집합일반적으로 데이터 관리, 트랜잭션 처리, 최종 사용자를 위한 서비스 제공 등 원하는 기능을 실행할 수 있는 소프트웨어 애플리케이션 으로 구성1.1.2 분산 소프트웨어 시스템여러 독립적인 컴포넌트나 프로세스 노드로 구성할 수 있는데, 이들은 서로 통신을 주고받으며 하나의 공동 목표를 달성하려고 함.각 구성 요소끼리 RPC, Message Passing, Pub/Sub 등의 다양한 통신 프로토콜을 통해 서로 소통주로 확장성, 가용성, 장애 허용이 중요한 요구 사항으로 등장하는 대규모 애플리케이션을 구축할 때 사용함.클라우드 컴퓨팅 플랫폼, P2P 네트워크, 분산 데이터베이..
airflow 스케줄러Airflow 스케줄러의 역할Airflow 스케줄러는 모든 태스크와 DAG를 모니터링하며, 해당 DAG가 실행될 수 있는지 주기적으로 확인한다.주기적으로 (매분 또는 설정된 주기에 따라) 활성화된 태스크들을 검사하여 실행할 수 있는지 확인한다.스케줄링 간격에 따른 실행schedule_interval을 1일로 설정한 DAG이 있을 경우, 실행되는 실제 실행 시간은 그 기간이 끝난 후에 시작된다.예를 들어, 2023-01-01에 실행되도록 설정된 DAG은 2023-01-01 23:59가 지나야 실행되며, 실행된 시각은 2023-01-02로 찍힌다. 즉, Airflow는 주어진 기간이 끝난 후, 1번의 주기가 지난 후에 작업을 실행한다.실행 시간 (Execute Time)start_dat..
주요 포인트:ProviderProvider 정의Airflow Provider는 Apache Airflow 내에서 특정 기능이나 외부 시스템과의 통합을 의미한다.Providers는 Airflow가 다양한 외부 시스템, 서비스, 또는 기술과 상호작용하고 지원할 수 있도록 한다.Provider의 목적:Airflow의 Providers는 Airflow가 외부 시스템, 서비스, 기술과 상호작용할 수 있도록 하여 기본 기능을 넘어서는 작업을 처리할 수 있게 한다.모듈화된 아키텍처:Airflow는 모듈화된 아키텍처로 설계되어 있어 다양한 Providers를 쉽게 추가할 수 있다. 이로 인해 Airflow의 기능이 외부 시스템과 상호작용하거나 특정 시스템에 맞게 확장될 수 있다.Providers는 일반적으로 다음과 같..
파이썬 내장 딕셔너리 타입을 사용하면 객체의 생명 주기 동안 동적인 내부 상태를 잘 유지할 수 있다.여기서 동적이라는 말은 어떤 값이 들어올지 미리 알 수 없는 식별자를 유지해야한다는 뜻아래는 학생 별 성적을 리스트로 추가하는 코드 예시이다.class SimpleGradebook: def __init__(self): self._grades = {} def add_student(self, name): self._grades[name] = [] def report_grade(self, name, score): self._grades[name].append(score) def average_grade(self, name): grades =..