Menu
Coddy logo textTech

세터에서의 유효성 검사

Coddy C 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 61개 중 20번째.

이전 수업에서는 단순히 값을 할당하는 기본 setter를 만들었습니다. 하지만 이렇게 하면 캡슐화의 핵심 이점인 데이터를 보호하는 기능을 놓치게 됩니다. 이 기능은 유효성 검사 로직을 추가하여 구현할 수 있습니다.

음수가 되어서는 안 되는 Counter를 생각해 보세요. 캡슐화가 없다면 누구나 c->value = -50을 작성하여 상태를 손상시킬 수 있습니다. 세터를 사용하면 어떤 값이 허용되는지 제어할 수 있습니다:

// counter.c
void counter_set_value(Counter *c, int new_value) {
    if (new_value < 0) {
        return;  // 잘못된 입력을 조용히 거부합니다
    }
    c->value = new_value;
}

이제 음수 값은 단순히 무시됩니다.

성공 또는 Failure를 나타내기 위해 상태 코드를 반환하도록 선택할 수도 있습니다:

int counter_set_value(Counter *c, int new_value) {
    if (new_value < 0) {
        return 0;  // 실패
    }
    c->value = new_value;
    return 1;  // 성공
}

이 패턴을 사용하면 호출자는 작업이 성공했는지 알 수 있습니다. 핵심은 세터가 단순히 값을 할당하는 역할만 하는 것이 아니라, 객체의 상태가 가질 수 있는 값에 대한 규칙을 적용하는 문지기라는 점입니다. 이것이 바로 캡슐화의 진정한 힘입니다. 외부 코드가 무엇을 하려고 하든 객체는 자신의 무결성을 스스로 유지합니다.

challenge icon

챌린지

쉬움

setter에서 유효성 검사를 사용하여 데이터를 보호하는 Temperature 모듈을 만들어 보겠습니다. 유효한 범위 내의 값만 accept하는 온도 추적기를 만들면서, setter가 객체 상태의 gatekeeper 역할을 하는 방식을 살펴봅니다.

세 개의 파일을 만듭니다:

  • temperature.h: opaque pointer pattern을 사용하는 public interface입니다. forward declaration만 사용하여 Temperature type을 Declare합니다. 다음 functions를 Declare합니다:
    • create_temperature: initial degrees를 integer로 받고 Temperature pointer를 반환합니다
    • free_temperature: allocated memory를 해제합니다
    • temp_get_degrees: current temperature value를 반환하는 getter입니다
    • temp_set_degrees: int를 반환하는 setter입니다 (성공 시 1, failure 시 0)
    TEMPERATURE_H symbol을 사용하여 include guards를 사용합니다.
  • temperature.c: hidden int degrees member를 포함하는 actual struct Temperature를 Define합니다. 모든 functions를 Implement합니다. 핵심은 setter입니다. setter는 -50과 150 (inclusive) 사이의 값만 accept해야 합니다. 값이 이 범위를 벗어나면 0을 반환하고 temperature를 변경하지 않은 채 leave합니다. 유효하면 값을 update하고 1을 반환합니다.
  • main.c: valid temperature와 invalid temperature를 모두 설정해 보면서 validation을 시연하고, invalid 값은 거부되는 반면 valid 값은 accept되는 것을 보여 줍니다.

세 개의 inputs를 받습니다: initial temperature, 설정할 valid temperature (범위 내), 시도할 invalid temperature (범위 밖)입니다.

main file에서 initial value로 Temperature를 Create하고 출력합니다. 그런 다음 invalid temperature는 거부되어야 하므로 설정을 시도하고, result를 출력하여 value가 unchanged 상태로 유지되는 것을 보여 줍니다. 마지막으로 valid temperature를 설정하고, success result를 출력한 뒤 updated value를 보여 줍니다. memory를 Free하고 cleanup을 확인합니다.

다음 형식으로 output을 출력합니다:

Initial: {degrees}
Set {invalid}: {0 or 1}
After invalid: {degrees}
Set {valid}: {0 or 1}
After valid: {degrees}
Freed

예를 들어 inputs가 25, 100, 200이면 output은 다음과 같습니다:

Initial: 25
Set 200: 0
After invalid: 25
Set 100: 1
After valid: 100
Freed

이는 encapsulation의 진정한 power를 보여 줍니다. setter가 무엇이 valid temperature인지에 대한 rules를 enforce하므로, external code가 어떤 values를 assign하려고 하더라도 object의 integrity를 보호합니다.

직접 해보기

#include <stdio.h>
#include "temperature.h"

int main() {
    // 입력 읽기
    int initial, valid_temp, invalid_temp;
    scanf("%d", &initial);
    scanf("%d", &valid_temp);
    scanf("%d", &invalid_temp);
    
    // TODO: 초기 값으로 Temperature 생성
    
    // TODO: 초기 온도 출력
    // 형식: "Initial: {degrees}"
    
    // TODO: 유효하지 않은 온도 설정 시도
    // 결과를 출력하고 값이 변경되지 않았음을 표시
    // 형식: "Set {invalid}: {0 or 1}"
    // Format: "After invalid: {degrees}"
    
    // TODO: 유효한 온도 설정
    // 성공 결과를 출력하고 업데이트된 값 표시
    // 형식: "Set {valid}: {0 or 1}"
    // 형식: "After valid: {degrees}"
    
    // TODO: 메모리를 해제하고 "Freed" 출력
    
    return 0;
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 C 컴파일러