C#

C# 기초부터 고급까지 Chapter 2.10. 프로젝트 구조 패턴 – Layered vs Clean Architecture 소개

Juan_ 2025. 5. 4. 18:41
728x90

📘 Chapter 2.10: 프로젝트 구조 패턴 – Layered vs Clean Architecture 소개


✅ 이 챕터에서 배울 것

  • 왜 프로젝트 구조가 중요한가?
  • Layered Architecture란?
  • Clean Architecture란?
  • 두 구조의 코드 예제 비교 (C# 콘솔앱 기준, 레이어 주석 포함)
  • 언제 어떤 구조를 써야 하는가?

1️⃣ 왜 프로젝트 구조가 중요한가?

✅ 설계가 잘 안 되어 있으면…

  • 클래스가 이리저리 흩어져 유지보수 지옥
  • 기능이 섞이고 결합이 심해 테스트가 어려움
  • 신입이 보면 "뭐가 뭔지 모르겠는데요…"

✅ 설계가 잘 돼 있으면…

  • 역할이 딱딱 나뉘고
  • 각 계층 책임이 명확하고
  • 테스트도, 교체도, 확장도 쉬워진다!

2️⃣ Layered Architecture

✅ 계층별로 수평 분리된 구조. 직관적이고 빠르게 시작 가능!

📦 기본 계층 구조

[Presentation] → [Application] → [Domain] → [Infrastructure]

🔧 Layered 예제 코드 (C# 콘솔 기준)

📂 Domain Layer

// File: Product.cs
// Layer: Domain
public class Product
{
    public string Name { get; set; }
    public decimal Price { get; set; }
}

📂 Application Layer

// File: OrderService.cs
// Layer: Application
public class OrderService
{
    public decimal CalculateFinalPrice(Product product)
    {
        return product.Price; // 비즈니스 로직은 단순함
    }
}

📂 UI Layer

// File: Program.cs
// Layer: UI (Presentation)
var product = new Product { Name = "모니터", Price = 200000 };

var service = new OrderService();
var price = service.CalculateFinalPrice(product);

Console.WriteLine($"최종 결제 금액: {price}원");

✅ 한줄평

항목평가
구조단순하고 빠름
유지보수비즈니스 로직이 Service에 몰리면 곤란
테스트구조적 제약은 없음, 단 테스트 어려워짐

3️⃣ Clean Architecture

✅ 계층 보호 + 의존성 역전!
안쪽 계층은 절대 바깥 계층을 몰라야 함!

📦 구조

/Domain
    - Product.cs
    - IDiscountPolicy.cs

/Application
    - OrderService.cs

/Infrastructure
    - FixedDiscountPolicy.cs

/ConsoleApp
    - Program.cs

🔧 Clean 예제 코드 (레이어 주석 포함)

📂 Domain Layer

// File: Product.cs
// Layer: Domain
public class Product
{
    public string Name { get; set; }
    public decimal Price { get; set; }
}
// File: IDiscountPolicy.cs
// Layer: Domain
public interface IDiscountPolicy
{
    decimal GetDiscountRate();
}

📂 Infrastructure Layer

// File: FixedDiscountPolicy.cs
// Layer: Infrastructure
using Domain;

public class FixedDiscountPolicy : IDiscountPolicy
{
    public decimal GetDiscountRate() => 0.1m;
}

📂 Application Layer

// File: OrderService.cs
// Layer: Application
using Domain;

public class OrderService
{
    private readonly IDiscountPolicy _policy;

    public OrderService(IDiscountPolicy policy)
    {
        _policy = policy;
    }

    public decimal CalculateFinalPrice(Product product)
    {
        var discount = _policy.GetDiscountRate();
        return product.Price * (1 - discount);
    }
}

📂 UI Layer

// File: Program.cs
// Layer: UI (ConsoleApp)
using Domain;
using Infrastructure;
using Application;

var product = new Product { Name = "모니터", Price = 200000 };

IDiscountPolicy policy = new FixedDiscountPolicy(); // 인프라 구현체
var service = new OrderService(policy);              // 애플리케이션 서비스

var price = service.CalculateFinalPrice(product);
Console.WriteLine($"할인 적용 금액: {price}원");

✅ 구조 요약 비교

항목LayeredClean
설계 난이도쉬움높음
테스트 용이성낮음높음
비즈니스 분리약함강함
DI 사용약함기본
실무 유연성중간최고

✅ 정리 요약

항목요약
Layered단순하고 빠르게 구현할 수 있음. 변경에 취약
Clean Architecture초반 설계는 복잡하지만, 유지보수·확장성 탑티어
핵심 차이"의존성 방향"과 "인터페이스 분리 여부"
실무 팁소규모는 Layered, 중장기/테스트중심은 Clean 추천

📢 다음 챕터 예고 🎓

다음 챕터주제
Chapter 3.1윈도우/리눅스에서 IP 설정 실습 – 수동/자동 IP 잡아보기
728x90