-
C# Dictionary와 LINQ로 구현하는 고객 유형별 상품 타입 필터링 패턴닷넷/C# 2025. 6. 30. 11:56반응형
1. 개요
고객 유형(CustomerType)에 따라 시스템에서 제공해야 하는 ItemType 목록을 동적으로 필터링하는 로직을 구현한 경험을 공유한다.
- 목표: VIP, Regular 등 고객 유형별로 기본 제공되는 상품 타입을 정의하고, 특정 권한(Permission) 값에 따라 필터링 규칙을 적용
- 장점: 타입 안전성 보장, 유지보수성 향상, 코드 가독성 및 확장성 확보
2. 요구사항
- 고객 유형별 기본 상품 타입
- Regular: A, B, C, D
- VIP: A, B, E, F, G, H, I, J
- Permission이 “20”인 경우
- 위 허용 목록에 포함된 ItemType만 노출
- 그 외 Permission
- 전체 ItemType 노출
- 향후 고객 유형 추가나 허용 항목 변경이 용이해야 함.
3. 설계 아이디어
- 고객 유형별 허용 ItemType을 Dictionary<CustomerType, HashSet<ItemType>>로 중앙집중 관리
- 데이터베이스에서 가져온 Code 객체(CodeID: string, Permission: string)를 LINQ로 간단히 필터링
- Enum.TryParse + HashSet.Contains 조합으로 엄격한 타입 검증 및 빠른 조회
- 조건문(Permission != "20" || …) 하나로 “그 외” 케이스도 자연스럽게 처리
4. 주요 코드 예시
/// <summary> /// 고객 타입별 기본 상품 타입 목록을 정의합니다. /// </summary> private readonly Dictionary<CustomerType, HashSet<ItemType>> _allowedItemTypes; public MyServiceConstructor() { _allowedItemTypes = new() { [CustomerType.Regular] = new HashSet<ItemType> { ItemType.A, ItemType.B, ItemType.C, ItemType.D }, [CustomerType.Vip] = new HashSet<ItemType> { ItemType.A, ItemType.B, ItemType.E, ItemType.F, ItemType.G, ItemType.H, ItemType.I, ItemType.J } }; } public IEnumerable<ItemType> GetItemTypeList(CustomerType customerType) { // 1) DB에서 전체 코드 리스트 조회 IEnumerable<Code> codes = _codeService.Value .SelectCode(SystemConstants.ModuleTypeA, SystemConstants.CodeTypeA); // 2) 고객 유형에 매핑된 허용 목록이 있으면 필터링 적용 if (_allowedItemTypes.TryGetValue(customerType, out var allowedEnums)) { codes = codes.Where(x => // Permission이 "20"이 아니면 모두 포함 x.Permission != "20" // Permission이 "20"이면, 파싱 성공 & 허용 목록에 포함된 항목만 포함 || (Enum.TryParse<ItemType>(x.CodeID, ignoreCase: true, out var parsed) && allowedEnums.Contains(parsed)) ); } // 3) Code → ItemType 변환 var result = codes .Select(code => (ItemType)Enum.Parse(typeof(ItemType), code.CodeID, ignoreCase: true)) .ToList(); return result; }
5. 코드 설명
- 맵 초기화
- 생성자에서 Dictionary<CustomerType, HashSet<ItemType>>를 초기화
- 신규 고객 유형 추가 시 이곳만 수정하면 됨
- 필터 로직
- TryGetValue로 고객 유형에 대한 허용 목록을 가져옴
- LINQ Where 내부에서 한 줄로 두 가지 케이스를 처리
- x.Permission != "20": 모든 코드 통과
- x.Permission == "20": Enum.TryParse로 CodeID를 ItemType으로 변환 후, 허용 목록 검사
- 최종 반환
- 필터링된 Code 리스트를 ItemType 리스트로 변환
6. 장단점 및 확장 포인트
구분장점유의/확장 포인트유지보수성 중앙집중형 맵으로 허용 항목 관리 → 변경 시 한 곳만 수정 가능 맵이 커지면 초기화 코드가 길어질 수 있음 성능 HashSet → O(1) 포함 검사, Enum.TryParse 오버헤드 최소화 아주 큰 규모(수만 건 이상)라면 DB 레벨 필터링 고려 타입 안정성 string → enum 파싱 후 검사 → 잘못된 값 걸러짐 Enum.Parse 실패 시 예외 방지 로직 추가 고민 가능 확장성 신규 CustomerType 추가/허용 목록 변경 손쉽게 대응 고객별 커스텀 로직이 복잡해지면 전략 패턴 도입 고려
7. 결론
이 방식은 간단한 사전(Dictionary) + LINQ 조합만으로도 복잡한 비즈니스 로직을 깔끔하게 표현할 수 있었다.
- 소규모 프로젝트: 코드 한 줄, 맵 수정만으로 요구사항 반영 가능
- 대규모 시스템: 이후 DB 매핑 테이블이나 Specification 패턴 등으로 리팩토링해도 기반 아이디어는 동일
반응형'닷넷 > C#' 카테고리의 다른 글
C# 이중 반복문(중첩 루프) 개선 방법 (1) 2025.06.30 NullReferenceException, Null 참조 오류 등 Null 예외 처리에 대한 고찰과 지침서 (1) 2024.07.12 Microsoft의 Text-to-Speech (TTS), Azure Cognitive Services를 C#에서 사용하는 방법 (0) 2023.07.27 C# Interlocked.Increment에 대한 고찰 (0) 2023.07.20 C# 기초지식, 정보 정리 (면접 질문 대비, 꼭 알아야 하는 것) (0) 2023.04.11