[Design Pattern] MVC 패턴
MVC 패턴이란?
MVC(Model-View-Controller)는 소프트웨어 디자인 패턴으로, 애플리케이션의 데이터(Model), UI(View), 그리고 사용자 입력 및 비즈니스 로직(Control)를 분리하여 구현하는 구조입니다. 이 패턴은 유지보수성과 확장성을 높이고, 역할을 명확히 나눔으로써 코드의 복잡성을 줄이는 데 목적이 있습니다.
구성요소
- Model
- 애플리케이션의 데이터와 로직을 담당.
- 데이터 상태를 관리하고, 데이터베이스와 직접 상호작용합니다.
- 독립적으로 동작하며, View나 Controller에 대해 알지 못합니다.
- 역할: 데이터의 CRUD(Create, Read, Update, Delete)를 수행.
- View
- UI와 사용자에게 보여지는 화면을 담당.
- Model에서 데이터를 받아 화면에 렌더링.
- 사용자 입력은 처리하지 않으며, 입력을 Controller로 전달합니다.
- 역할: 데이터를 시각적으로 표현.
- Controller
- 사용자 입력을 처리하고, Model과 View를 연결하는 중간 역할.
- 입력된 데이터를 해석하고, 비즈니스 로직에 따라 Model을 업데이트하거나 View를 변경합니다.
- 역할: 애플리케이션의 흐름 제어.
MVC의 동작 흐름
- 사용자 입력: 사용자가 UI(View)를 통해 이벤트(클릭, 키 입력 등)를 발생시킵니다.
- Controller 처리: Controller가 입력을 받아 적절한 로직을 처리하고, 필요하면 Model의 데이터를 갱신합니다.
- Model 업데이트: Model이 데이터를 변경하고, 상태를 유지합니다.
- View 갱신: 변경된 Model의 데이터를 기반으로 View가 업데이트됩니다.
장단점
장점
- 유지보수성
- 역할이 분리되어 있어 특정 부분(Model, View, Controller)을 독립적으로 수정할 수 있습니다.
- 재사용성
- Model과 View가 독립적이기 때문에 서로 다른 View에서 동일한 Model을 재사용 가능.
- 테스트 용이성
- Model은 독립적이므로 단위 테스트가 쉽습니다.
- 확장성
- 새로운 View나 Controller를 추가하기가 쉽습니다.
단점
- 복잡성 증가
- 작은 프로젝트에서는 패턴을 적용하면 구조가 지나치게 복잡해질 수 있습니다.
- 초기 설계 비용
- 설계를 제대로 하지 않으면 역할 분리가 모호해져 MVC의 장점을 살리지 못할 수 있습니다.
- 설계를 제대로 하지 않으면 역할 분리가 모호해져 MVC의 장점을 살리지 못할 수 있습니다.
샘플 코드
Model
using System;
public class CalculatorModel
{
public double Result { get; private set; }
public void Add(double a, double b)
{
Result = a + b;
}
public void Subtract(double a, double b)
{
Result = a - b;
}
public void Multiply(double a, double b)
{
Result = a * b;
}
public void Divide(double a, double b)
{
if (b == 0)
{
throw new DivideByZeroException("Cannot divide by zero!");
}
Result = a / b;
}
}
View
using System;
public class CalculatorView
{
public void DisplayResult(double result)
{
Console.WriteLine($"Result: {result}");
}
public void DisplayError(string message)
{
Console.WriteLine($"Error: {message}");
}
public (double, double, string) GetUserInput()
{
Console.Write("Enter first number: ");
double num1 = Convert.ToDouble(Console.ReadLine());
Console.Write("Enter second number: ");
double num2 = Convert.ToDouble(Console.ReadLine());
Console.Write("Enter operation (+, -, *, /): ");
string operation = Console.ReadLine();
return (num1, num2, operation);
}
}
Controller
using System;
public class CalculatorController
{
private readonly CalculatorModel _model;
private readonly CalculatorView _view;
public CalculatorController(CalculatorModel model, CalculatorView view)
{
_model = model;
_view = view;
}
public void PerformCalculation()
{
try
{
// 사용자 입력 받기
var (num1, num2, operation) = _view.GetUserInput();
// 연산 처리
switch (operation)
{
case "+":
_model.Add(num1, num2);
break;
case "-":
_model.Subtract(num1, num2);
break;
case "*":
_model.Multiply(num1, num2);
break;
case "/":
_model.Divide(num1, num2);
break;
default:
throw new InvalidOperationException("Invalid operation!");
}
// 결과 표시
_view.DisplayResult(_model.Result);
}
catch (Exception ex)
{
// 에러 처리
_view.DisplayError(ex.Message);
}
}
}