아키텍처 패턴


잘 설계된 자원 및 비용 최적화에 대해 자세히 알아보기 → 최적화 책임

이 페이지에서는 기능 단위, 문제 분리, 상태 관리, API 관리, 메시징 등 아키텍처 문제에 대한 포괄적인 패턴 지침을 제공합니다. 해당 패턴은 서비스 경계, 데이터 액세스 패턴, 구성 요소 책임에 대한 의도한 설계 결정을 통해 장기적인 솔루션 성공을 구축합니다.

패턴

찾을 위치유사성
Apex 클래스✅ 서비스 클래스는 이름이 명확하게 목적을 나타내는 단일 책임 원칙을 따릅니다(AccountService, OrderProcessor, InventoryManager). 각 서비스 클래스는 하나의 도메인 또는 비즈니스 기능에 초점을 맞춥니다. 서비스 클래스 내의 메서드에는 20행 미만의 단일 집중형 책임이 있습니다.
트리거✅ 트리거는 비즈니스 논리를 직접 포함하는 대신 처리기 클래스에 위임합니다. 트리거 처리기 패턴은 컨텍스트별로 명확한 메서드 이름과 일관되게 사용됩니다(handleBeforeInsert, handleAfterUpdate). 처리기 클래스는 트리거 이벤트를 통해 논리를 구성하며, 메서드당 단일 책임이 있습니다.
Lightning 웹 구성 요소✅ 구성 요소는 구성에 대해 명확한 prop 인터페이스와 함께 단일 책임 원칙을 따릅니다. 각 LWC는 하나의 UI 문제(데이터 표시, 사용자 입력, 탐색)에 초점을 맞춥니다. 단일 구현이 아닌 구성용으로 설계된 구성 요소입니다.
서비스 계층✅ 서비스 클래스는 입력 지점(트리거, API, 플로, 배치)과 무관하게 비즈니스 논리를 캡슐화합니다. 동일한 서비스 클래스는 중복 없이 여러 호출 컨텍스트를 처리합니다. 서비스 계층은 비즈니스 규칙을 프레젠테이션 및 데이터 액세스 문제와 구분합니다.
재사용 가능한 부품✅ 여러 프로젝트 및 팀에서 재사용하도록 설계된 구성 요소 사용자 정의 메타데이터 유형을 사용하는 구성 중심 동작을 사용하면 코드 배포 없이 동작을 변경할 수 있습니다. 호출 가능한 작업은 플로 및 외부 오케스트레이션에서 사용할 수 있는 선언적 빌딩 블록으로 Apex 논리를 노출합니다.

안티 패턴

찾을 위치불만 사항
신 클래스⚡️ 단일 클래스에 과도한 책임이 누적되지 않도록 방지합니다. 대규모 클래스(여러 줄 이상)를 단일 책임이 있는 집중 클래스로 분할합니다. 여러 가지 관련 없는 우려 사항을 처리할 때 클래스를 재구성합니다(OrderProcessor는 이메일 전송 및 보고도 처리해서는 안 됩니다).
복합적인 우려 사항⚡️ 단일 클래스에서 트리거 논리, 비즈니스 규칙 및 데이터 액세스를 혼합하지 마십시오. 컨트롤러의 비즈니스 논리에서 프레젠테이션 논리를 구분합니다. 통합 문제를 핵심 도메인 논리와 구분합니다.
트리거의 트리거 논리⚡️ 트리거 파일에 비즈니스 논리를 직접 포함하지 마십시오. 중첩된 조건으로 300개가 넘는 행 트리거를 사용하지 마십시오. 항상 트리거 컨텍스트별로 명확한 메서드 구성으로 처리 클래스에 위임하십시오.

패턴

찾을 위치유사성
비즈니스 논리✅ 비즈니스 규칙은 서비스 클래스에서 중앙 집중화되며 트리거, 컨트롤러 및 배치 클래스에 분산되지 않습니다. 도메인 클래스는 레코드 수준 동작(확인, 기본값, 파생 값)을 시스템에 입력하는 방법에 관계없이 일관되게 캡슐화합니다. 진입점에서 복제되지 않고 서비스 계층을 통해 재사용되는 논리입니다.
데이터 액세스✅ 리포지토리 또는 선택기 패턴 클래스 뒤에 추상화된 데이터 액세스 선택기 클래스(AccountSelector, OpportunitySelector)에서 중앙 집중화된 SOQL 쿼리는 필드 목록 및 WHERE 절의 일관성을 보장합니다. 리포지토리 패턴을 사용하면 비즈니스 논리를 변경하지 않고 모의 데이터 소스를 사용하여 테스트할 수 있습니다.
인터페이스 계약✅ 구성 요소는 구현 세부 사항이 아닌 명시적 인터페이스를 통해 통신합니다. Apex 인터페이스는 레이어 간의 계약을 정의합니다. 사용자 정의 메타데이터 구성은 동작 경계를 정의합니다. 플랫폼 이벤트는 프로듀서와 소비자 간의 Messaging 계약을 제공합니다.
모듈 경계✅ 바운드된 컨텍스트는 데이터 모델 및 비즈니스 규칙에 대한 명확한 소유권 경계를 정의합니다. 각 모듈은 데이터, 자동화, 비즈니스 논리를 소유합니다. 모듈은 데이터베이스 개체를 직접 공유하는 대신 정의된 API를 통해 상호 작용합니다. 문서에서 어떤 팀이 어떤 개체 및 서비스를 소유하고 있는지 명확하게 식별합니다.
종속성 흐름✅ 종속성은 한 방향(프레젠테이션 → 비즈니스 → 데이터)으로 흐릅니다. 핵심 비즈니스 논리는 외부에 의존하지 않으므로 독립적인 진화가 가능합니다. 인프라스트럭처 문제(로그, 캐싱, 외부 API)는 인터페이스를 통한 비즈니스 논리에 따라 다릅니다. 그 반대의 경우는 마찬가지입니다.

안티 패턴

찾을 위치불만 사항
논리적 복제⚡️ 트리거, API 끝점, 배치 클래스에서 중복되는 비즈니스 논리를 피하십시오. 서비스 계층에서 중앙 집중화하고 입력 지점에서 재사용합니다. 여러 클래스에 동일한 비즈니스 규칙이 나타날 때마다 공유 서비스로 추출합니다.
데이터 액세스 분산트리거, 컨트롤러, 필드 목록 및 WHERE 절이 일관되지 않은 배치 클래스 전체에 분산된 SOQL 쿼리를 방지합니다. 선택기 클래스에서 쿼리를 중앙 집중화하여 일관된 패턴을 보장하고 단일 위치에서 LDV 최적화를 활성화합니다.
트리거의 비즈니스 논리⚡️ 트리거 코드에 직접 포함된 확인 규칙, 필드 계산, 워크플로 오케스트레이션을 피하십시오. 서비스 클래스 또는 도메인 클래스로 이동합니다. 트리거를 얇게 유지하고 적절한 처리기에 위임에만 초점을 맞춥니다.
컨트롤러의 비즈니스 논리⚡️ Aura/LWC 컨트롤러 메서드에서 복잡한 계산, 확인 또는 데이터 조작을 피하십시오. 컨트롤러는 비즈니스 규칙을 직접 구현하지 않고 서비스 계층에 대한 호출을 오케스트레이션해야 합니다.
순환 종속성A는 B에 종속되고 B는 A에 종속되는 원형 종속성이 있는 패키지 또는 클래스를 피하십시오. 공유된 우려 사항을 별도의 모듈에 추출하거나 종속 방향을 반전하거나 이벤트 중심 커뮤니케이션을 사용하여 커플링을 끊어 해결합니다.

패턴

찾을 위치유사성
플랫폼 캐시(조직 파티션)✅ 자주 액세스하는 참조 데이터는 사용자 정의 메타데이터 조회, 선택 목록 값, 구성 설정, 비용이 많이 드는 작업의 계산된 결과를 포함하여 조직 파티션에 캐싱됩니다. 데이터 변동률을 기반으로 구성된 기본 TTL(매월 변경되는 참조 데이터의 경우 시간, 자주 업데이트되는 구성의 경우 분) 캐시 키 전략은 다양한 데이터 유형의 충돌을 방지합니다.
플랫폼 캐시(세션 파티션)✅ 세션 캐시에 저장된 사용자별 기본 설정, 계산된 개인 설정 데이터, 세션 범위 상태 세션 캐시는 사용자 간에 공유해야 하는 데이터에 사용되지 않습니다. 캐시 무효화 전략은 사용자 기본 설정 업데이트를 적절하게 처리합니다.
Lightning 데이터 서비스✅ LDS는 Lightning 웹 구성 요소에 대한 자동 클라이언트측 레코드 캐싱을 제공합니다. 표준 CRUD 작업은 사용자 정의 Apex 컨트롤러가 아닌 LDS를 사용합니다. LDS는 중복 서버 순환을 방지하고 최적의 UI 업데이트를 제공합니다. 구성 요소는 페이지 전체에서 공유 LDS 캐시를 활용합니다.
사용자 정의 메타데이터 유형✅ 클래스에 하드 코드되지 않고 사용자 정의 메타데이터 유형에 저장된 구성 및 동작 규칙입니다. 변경 집합 또는 소스 중심 개발을 통해 환경 전체에서 배포할 수 있는 사용자 정의 메타데이터입니다. 사용자 정의 메타데이터를 변경하려면 전체 배포 주기가 필요하지 않습니다. 성능을 위해 플랫폼 캐시에 사용자 정의 메타데이터 쿼리를 캐시합니다.

안티 패턴

찾을 위치불만 사항
루프 쿼리⚡️ 반복 루프 내에서 SOQL을 실행하지 마십시오. 루프 외부의 단일 SOQL 문에서 모든 필요한 레코드를 쿼리합니다. 반복 중 조회를 위해 상위 ID별로 결과를 Maps로 정리합니다. 이는 가장 일반적인 단일 Salesforce 안티 패턴입니다.
반복 쿼리⚡️ 트랜잭션당 동일한 사용자 정의 메타데이터, 사용자 정의 설정을 쿼리하거나 데이터를 여러 번 참조하지 마십시오. 쿼리 한 번, 플랫폼 캐시 또는 트랜잭션 정적 변수에 캐시하고 트랜잭션 전체에서 재사용합니다.
누락된 캐시 전략⚡️ 캐싱하지 않고 자주 액세스하는 참조 데이터를 반복적으로 쿼리하지 마십시오. 사용자 정의 메타데이터, 구성, 계산된 결과에 대해 플랫폼 캐시를 구현합니다. 데이터 변동성을 기반으로 적절한 TTL을 정의합니다.
유효하지 않음 캐시⚡️ 무효화 전략을 고려하지 않고 데이터를 캐싱하지 마십시오. 빈도를 업데이트하는 데 적합한 캐시 TTL을 정의합니다. TTL만이 부족할 경우 소스 데이터가 변경될 때 수동 캐시 해제를 구현합니다.
비관리 세션 상태⚡️ 확인 없이 페이지 탐색 전체에서 세션 상태가 유지되는 것을 가정하지 마십시오. Lightning 구성 요소는 페이지 로드 시 상태 새로 고침을 처리해야 합니다. Lightning 데이터 서비스를 사용하여 자동 상태 동기화

패턴

찾을 위치유사성
솔루션 아키텍처 계획✅ 아키텍처 계획은 요구 사항 분석(기능 및 비기능), 예상 데이터 용량에 대한 총괄자 제한 분석, 요구 사항에 적합한 패턴 선택, 주요 구성 요소 및 인터페이스를 정의하는 구성 요소 설계를 포함한 상당한 빌드 투자 이전에 수행됩니다.
설계 패턴 선택✅ 지속적으로 적용된 검증된 Salesforce 설계 패턴: 비즈니스 논리 재사용을 위한 서비스 계층 패턴, 데이터 액세스 추상을 위한 리포지토리/선택기 패턴, 상호 교환 가능한 알고리즘을 위한 전략 패턴, 레코드 수준 동작을 위한 도메인 패턴, 일관된 트리거 조직을 위한 트리거 처리기 패턴
아키텍처 결정 기록✅ 버전 관리에 저장된 ADR에 문서화된 중요한 아키텍처 결정 ADR은 컨텍스트(비즈니스 동인, 기술 제약), 결정(선택된 항목), 고려된 대안(기타가 거부된 이유) 및 결과(거래, 기술 부채, 재방문 트리거)를 수집합니다.
구축 대 구매 평가✅ AppExchange 평가는 총 소유 비용 분석을 사용하여 사용자 정의 개발 결정을 앞에 놓습니다. 평가 기준에는 전략적 가치(경쟁 차별화 요소와 상품 비교), TCO 비교(구축 노력, 서비스 점검, 업그레이드 비용), 통합 복잡성, 솔루션이 부적절한 경우 종료 비용이 포함됩니다.
총리 한도 분석✅ 아키텍처 계획은 예상 데이터 용량 및 트랜잭션 패턴에 따라 가장 제한적인 설계를 제한하는 총괄자를 식별합니다. 최대 조건에서 단일 총괄자 제한의 80% 미만을 소비하도록 설계된 트랜잭션 성장, 향후 기능, 예기치 않은 사용 패턴에 맞춰 작성된 마진입니다.
위험 평가✅ 플랫폼 경계를 푸시하는 아키텍처 접근 방식에 대해 식별된 기술 위험 각각의 중요 위험에 대해 정의된 경감 전략입니다. 시제품 또는 개념 증명 작업은 전체 구축 서약 전에 고위험 기술 접근 방식에 대한 가정을 확인합니다.

안티 패턴

찾을 위치불만 사항
계획 없음데이터 용량, 총괄자 제한 영향 또는 패턴 선택 항목을 분석하지 않고 구축을 시작하지 마십시오. 아키텍처 계획 워크숍은 구축을 시작하기 전에 주요 제약을 식별하고 패턴을 선택하고 총괄자 제한에 대한 유효성을 검사해야 합니다.
문서 없는 결정⚡️ 컨텍스트, 근거, 대안, 결과를 수집하지 않고 회의에서 아키텍처적 결정을 내리지 마십시오. 버전 제어에 저장된 아키텍처 의사 결정 레코드를 사용하여 향후 팀 구성원을 위한 의사 결정 컨텍스트를 유지합니다.
구축 및 구매 분석 없음⚡️ AppExchange 평가 없이 맞춤형 솔루션을 구축하지 마십시오. 사용자 정의 개발 전에 상위 3-5개의 관련 패키지를 평가합니다. 구현 노력, 서비스 점검, 업그레이드 비용, 종료 비용을 포함한 TCO를 비교합니다.
비엔지니어링⚡️ 성장 예상 없이 현재 데이터 볼륨에 대해서만 설계하지 마십시오. 2-3년 동안 프로젝트 데이터 증가 현재 볼륨의 5-10배에 대해 선택성을 검사한 쿼리 패턴을 설계합니다. 성장에 대한 아키텍처 마진을 구축합니다.

패턴

찾을 위치유사성
2세대 관리형 패키지(2GP)✅ 2GP는 네임스페이스 분리, AppExchange 배포 및 IP 보호가 필요한 새 관리 패키지에 사용됩니다. 모듈식 응용 프로그램 개발이 포함된 소스 중심 개발 워크플로 명시적으로 관리되는 패키지 종속성 시맨틱 버전 관리로 릴리스된 버전입니다.
잠금 해제 패키지✅ 네임스페이스 제약 없이 모듈화가 필요한 내부 엔터프라이즈 응용 프로그램에 사용되는 잠금 해제 패키지입니다. 조직에 종속된 아티팩트 없이 패키지의 독립적 배포 적절한 배포 순서를 위해 추적되는 패키지 종속성. 내부 패키지에 대해 정의된 버전 관리 전략입니다.
모듈 경계✅ 각 패키지에 대해 정의된 소유권 경계를 지웁니다. 각 패키지에는 데이터 모델, 비즈니스 규칙 및 자동화가 있습니다. 패키지는 직접 개체 액세스가 아닌 정의된 인터페이스를 통해 상호 작용합니다. 문서에서 패키지 소유권 및 패키지 간 계약을 식별합니다.