캡슐화를 위한 프로퍼티
Coddy C# 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 70개 중 32번째.
프로퍼티는 C#에서 캡슐화를 구현하기 위한 주요 도구입니다. 필드를 직접 노출하는 대신, 데이터가 액세스되고 수정되는 방식을 제어하는 프로퍼티로 필드를 감쌉니다.
이 패턴은 프라이빗 필드와 접근자(accessor)에 유효성 검사 또는 로직을 포함하는 퍼블릭 속성을 결합합니다:
public class Temperature
{
private double celsius;
public double Celsius
{
get { return celsius; }
set
{
if (value < -273.15)
celsius = -273.15; // 절대 영도 최소값
else
celsius = value;
}
}
}이제 외부 코드에서 불가능한 온도를 설정할 수 없습니다. 이 속성은 게이트키퍼 역할을 하여 객체가 항상 유효한 상태를 유지하도록 보장합니다. 이것이 바로 캡슐화의 실제 사례입니다. 내부 데이터는 보호되면서도 제어된 인터페이스를 통해 여전히 접근할 수 있습니다.
프로퍼티를 사용하여 값을 계산하거나 사이드 이펙트를 트리거할 수도 있습니다:
public double Fahrenheit
{
get { return celsius * 9 / 5 + 32; }
set { celsius = (value - 32) * 5 / 9; }
}외부에서는 두 개의 프로퍼티를 보지만, 내부적으로는 오직 하나의 필드만 존재합니다. 프로퍼티를 사용하면 클래스를 사용하는 코드를 망가뜨리지 않고도 구현 세부 사항을 변경할 수 있습니다. 이는 적절한 캡슐화(encapsulation)의 핵심적인 이점입니다.
챌린지
쉬움데이터 무결성을 보호하기 위해 속성(properties)을 사용하는 제품 인벤토리 시스템을 구축해 보겠습니다. 가격이 절대 음수가 될 수 없고 수량이 항상 유효한 범위 내로 유지되는 클래스를 만들게 됩니다. 이는 속성이 데이터의 게이트키퍼(gatekeeper) 역할을 하는 방식을 보여줍니다.
코드는 두 개의 파일로 구성됩니다:
Product.cs:Inventory네임스페이스 안에 속성을 통한 유효성 검사로 제품 정보를 관리하는Product클래스를 만듭니다. 제품에는 다음이 필요합니다:- 프라이빗 필드
price(decimal)와 퍼블릭Price속성: 가격이0미만으로 내려가지 않도록 보장해야 합니다. 누군가 음수 가격을 설정하려고 하면 대신0으로 저장되어야 합니다. - 프라이빗 필드
quantity(int)와 퍼블릭Quantity속성: 값을0에서1000사이로 유지합니다. 0 미만의 값은 0이 되고, 1000을 초과하는 값은 1000이 됩니다. - 퍼블릭 자동 구현 속성
Name(string) Price * Quantity를 반환하는 계산된 읽기 전용 속성TotalValue
- 프라이빗 필드
Program.cs: 메인 파일에서 입력 값을 사용하여Product를 생성합니다. 그런 다음 유효하지 않을 수 있는 추가 입력 값을 사용하여 가격과 수량을 수정해 봅니다. 생성 후와 각 수정 후의 제품 상태를 출력하여 속성이 데이터를 어떻게 보호하는지 확인하세요.
다섯 개의 입력을 받게 됩니다:
- 제품 이름
- 초기 가격 (decimal)
- 초기 수량 (integer)
- 새로 설정할 가격 (decimal, 음수일 수 있음)
- 새로 설정할 수량 (integer, 범위를 벗어날 수 있음)
출력은 다음 형식으로 하세요:
After creation:
{Name}: Price={Price}, Qty={Quantity}, Total={TotalValue}
After modifications:
{Name}: Price={Price}, Qty={Quantity}, Total={TotalValue}예를 들어, 입력값이 Laptop, 999.99, 50, -100, 1500인 경우 출력은 다음과 같아야 합니다:
After creation:
Laptop: Price=999.99, Qty=50, Total=49999.50
After modifications:
Laptop: Price=0, Qty=1000, Total=0음수 가격이 0이 되고 1500이라는 수량이 1000으로 제한된 방식에 주목하세요. 속성이 객체를 유효하지 않은 상태로부터 보호하고 있습니다. 이것이 바로 캡슐화(encapsulation)의 원리입니다!
치트 시트
프로퍼티는 get 및 set 접근자를 통한 제어된 액세스로 프라이빗 필드를 래핑하여, 유효성 검사 및 캡슐화를 가능하게 합니다:
public class Temperature
{
private double celsius;
public double Celsius
{
get { return celsius; }
set
{
if (value < -273.15)
celsius = -273.15;
else
celsius = value;
}
}
}프로퍼티는 내부 필드를 기반으로 값을 계산할 수 있습니다:
public double Fahrenheit
{
get { return celsius * 9 / 5 + 32; }
set { celsius = (value - 32) * 5 / 9; }
}읽기 전용 프로퍼티는 set 접근자를 생략하여, 계산되거나 저장된 값의 검색만 허용합니다.
직접 해보기
using System;
using Inventory;
class Program
{
public static void Main(string[] args)
{
// 입력 읽기
string name = Console.ReadLine();
decimal initialPrice = Convert.ToDecimal(Console.ReadLine());
int initialQuantity = Convert.ToInt32(Console.ReadLine());
decimal newPrice = Convert.ToDecimal(Console.ReadLine());
int newQuantity = Convert.ToInt32(Console.ReadLine());
// TODO: 초기값을 사용하여 Product 생성
// TODO: 생성 후 제품 상태 출력
Console.WriteLine("After creation:");
// 출력 형식: {Name}: Price={Price}, Qty={Quantity}, Total={TotalValue}
// TODO: 새로운 값으로 가격과 수량 수정
// TODO: 수정 후 제품 상태 출력
Console.WriteLine("After modifications:");
// 출력 형식: {Name}: Price={Price}, Qty={Quantity}, Total={TotalValue}
}
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.