Notice
Recent Posts
Recent Comments
Link
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

Luna

[TIL Day44] Unity 3D 강의 ~ing (2) 본문

🎮 Unity_7 TIL WIL

[TIL Day44] Unity 3D 강의 ~ing (2)

fociend 2025. 3. 6. 16:36

오늘의 학습 키워드

- 강의 내용 중 중요개념 정리

- 강의 계속 잘 듣기! 


공부한 내용 본인의 언어로 정리하기

🎮 Unity에서 알아두면 유용한 기능들 

1️⃣ TryGetComponent 🛠️

TryGetComponent는 Unity에서 게임 오브젝트의 특정 컴포넌트를 가져오는 기능을 제공합니다. 이 메서드를 사용하면 컴포넌트가 게임 오브젝트에 연결되어 있는지 확인하고, 연결되어 있다면 해당 컴포넌트를 안전하게 가져올 수 있습니다.

📌 TryGetComponent 메서드 형식

public bool TryGetComponent<T>(out T component) where T : Component;

🔹 매개변수 설명

  • T: 가져오려는 컴포넌트의 타입 (예: Rigidbody, Collider 등)
  • component: 가져온 컴포넌트를 저장할 out 매개변수

✅ 사용 예시

using UnityEngine;

public class ExampleScript : MonoBehaviour
{
    private void Start()
    {
        Rigidbody rb;
        if (TryGetComponent<Rigidbody>(out rb))
        {
            rb.AddForce(Vector3.up * 100f);
        }
        else
        {
            Debug.Log("Rigidbody component not found.");
        }
    }
}

🎯 TryGetComponent의 장점

✔️ 컴포넌트가 없을 경우 예외가 발생하지 않음
✔️ 불필요한 GetComponent 호출을 줄여 성능 최적화 가능


2️⃣ 카메라 절두체(뷰 절두체) 🎥

📷 카메라 절두체란?

카메라 절두체(Frustum)는 피라미드 형태의 윗부분을 자른 입체 형상으로, 카메라가 렌더링할 수 있는 공간을 의미합니다. 이 공간을 벗어난 객체는 렌더링되지 않습니다.

🔍 카메라 절두체의 주요 구성 요소

1️⃣ 시야각(FOV, Field of View): 카메라가 포착하는 시야 범위
2️⃣ Near Clipping Plane: 카메라에서 가까운 절단면
3️⃣ Far Clipping Plane: 카메라에서 먼 절단면

💡 카메라 절두체 활용

  • 🎯 뷰 절두체 컬링(View Frustum Culling): 카메라 시야 밖에 있는 오브젝트를 렌더링하지 않아 성능 최적화
  • ☀️ 광원 처리 및 그림자 연산: 빛과 그림자가 특정 영역에 영향을 미치는지 판단하는 데 사용

3️⃣ Coroutine (코루틴) ⏳

🌀 Coroutine이란?

코루틴(Coroutine)은 특정 작업을 여러 프레임에 걸쳐 실행할 수 있도록 하는 기능입니다. 코루틴을 사용하면 특정 시점에서 실행을 일시 정지하고, 다음 프레임에서 다시 실행을 재개할 수 있습니다.

⚡ Coroutine의 특징

🔸 비동기적 작업 수행 가능 (ex. 일정 시간 후 작업 실행)
🔸 멀티스레딩이 아님 (메인 스레드에서 실행됨)

🎯 Coroutine의 활용

  • ⏳ 일정 시간 후 동작 수행 (WaitForSeconds)
  • 🎬 특정 프레임이 끝난 후 실행 (WaitForEndOfFrame)
  • ⏲️ 특정 조건이 충족될 때까지 대기 (WaitUntil, WaitWhile)

동기와 비동기

코루틴은 동기? 비동기?

 


코루틴에 대한 개념을 좀 더 알아보기 위해 정리한 글 ↓

🌀 Unity Coroutine(코루틴) 정리 

1️⃣ Coroutine(코루틴)이란? 🤔

코루틴(Coroutine)은 Unity에서 특정 작업을 여러 프레임에 걸쳐 실행할 수 있도록 하는 기능입니다. 일반적인 함수는 한 번 호출되면 모든 코드가 즉시 실행되지만, 코루틴은 실행을 중단했다가 이후 특정 조건이 충족되면 다시 실행을 재개할 수 있습니다.

💡 코루틴의 핵심 개념

  • 비동기적 실행 가능: 특정 시간 동안 대기하거나 조건을 만족할 때까지 실행을 멈출 수 있음
  • 멀티스레드가 아님: 여전히 메인 스레드에서 실행됨
  • 게임 루프와 자연스럽게 연동됨: 애니메이션, 로딩, 시간 지연 등에 효과적

2️⃣ Coroutine 기본 사용법 

코루틴을 사용하려면 IEnumerator를 반환하는 메서드를 정의하고, yield return 키워드를 사용해야 합니다.

using UnityEngine;
using System.Collections;

public class CoroutineExample : MonoBehaviour
{
    void Start()
    {
        StartCoroutine(MyCoroutine());
    }

    IEnumerator MyCoroutine()
    {
        Debug.Log("코루틴 시작");
        yield return new WaitForSeconds(2f); // 2초 대기
        Debug.Log("2초 후 실행");
    }
}

📝 설명:

  1. StartCoroutine(MyCoroutine())을 호출하면 MyCoroutine이 실행됨
  2. yield return new WaitForSeconds(2f);에서 2초 동안 대기
  3. 2초 후 Debug.Log("2초 후 실행")이 출력됨

3️⃣ 다양한 yield return 키워드 활용법 

yield return 키워드 설명

WaitForSeconds(x) x초 동안 대기
WaitForEndOfFrame() 현재 프레임이 끝날 때까지 대기
WaitForFixedUpdate() 다음 FixedUpdate() 실행까지 대기
WaitUntil(condition) 특정 조건이 참이 될 때까지 대기
WaitWhile(condition) 특정 조건이 거짓이 될 때까지 대기

✅ WaitUntil과 WaitWhile 활용 예시

IEnumerator WaitForPlayerHealth()
{
    yield return new WaitUntil(() => playerHealth <= 0);
    Debug.Log("플레이어 사망!");
}

💡 설명: playerHealth가 0 이하가 될 때까지 대기한 후 실행됩니다.


4️⃣ 코루틴 중지 및 관리 

🛠️ 코루틴 중지 방법

메서드 설명

StopCoroutine(method) 특정 코루틴 중지
StopAllCoroutines() 현재 실행 중인 모든 코루틴 중지
void StopMyCoroutine()
{
    StopCoroutine(MyCoroutine());
}

💡 StopCoroutine()을 사용하려면, StartCoroutine()에서 반환된 IEnumerator를 저장하는 것이 좋습니다.

private Coroutine myCoroutine;

void Start()
{
    myCoroutine = StartCoroutine(MyCoroutine());
}

void StopManually()
{
    if (myCoroutine != null)
    {
        StopCoroutine(myCoroutine);
    }
}

5️⃣ 코루틴을 활용한 응용 예제 

 1. 점진적인 오브젝트 이동

IEnumerator MoveObject(Transform obj, Vector3 target, float duration)
{
    Vector3 start = obj.position;
    float elapsed = 0f;
    
    while (elapsed < duration)
    {
        obj.position = Vector3.Lerp(start, target, elapsed / duration);
        elapsed += Time.deltaTime;
        yield return null; // 한 프레임 대기
    }
    obj.position = target;
}

 Vector3.Lerp를 사용하여 duration 동안 부드럽게 이동합니다.

2. 페이드 인/아웃 효과

IEnumerator FadeCanvasGroup(CanvasGroup canvasGroup, float targetAlpha, float duration)
{
    float startAlpha = canvasGroup.alpha;
    float elapsed = 0f;
    
    while (elapsed < duration)
    {
        canvasGroup.alpha = Mathf.Lerp(startAlpha, targetAlpha, elapsed / duration);
        elapsed += Time.deltaTime;
        yield return null;
    }
    canvasGroup.alpha = targetAlpha;
}

 CanvasGroup.alpha 값을 조정하여 부드러운 페이드 효과를 만듭니다.

6️⃣ 코루틴을 사용할 때 주의할 점 ⚠️

남발하지 않기: 너무 많은 코루틴을 사용하면 성능 저하 발생 가능
StopCoroutine을 활용: 불필요한 코루틴은 중지하여 리소스 낭비 방지
무한 루프 주의: 조건 없이 while(true)를 사용할 경우 주의
코루틴은 메인 스레드에서 실행됨: 멀티스레딩이 필요한 경우 Task나 Thread 활용 고려


코루틴과 동기(Synchronous) & 비동기(Asynchronous) 처리

1. 동기(Synchronous)와 비동기(Asynchronous)란?

동기(Synchronous)란?🤔

  • 하나의 작업이 끝나야 다음 작업이 실행됨
  • 코드가 순차적으로 실행되므로 예측하기 쉬움
  • 단점: 시간이 오래 걸리는 작업이 있으면 전체 흐름이 멈출 수 있음

비동기(Asynchronous)란?🤔

  • 여러 작업이 동시에 실행될 수 있음
  • UI 응답성 향상, 멀티태스킹 가능
  • 단점: 복잡한 제어 흐름을 관리해야 함

2. Unity 코루틴과 동기 & 비동기

코루틴은 일반적인 비동기 프로그래밍처럼 멀티스레딩이 아닌 메인 스레드에서 실행되지만,

특정 작업을 지연시키거나 여러 프레임에 걸쳐 실행할 수 있도록 만들어줍니다.

동기적 실행 예시

void NormalFunction()
{
    Debug.Log("작업 A 시작");
    TaskA();
    Debug.Log("작업 A 종료 후 작업 B 실행");
    TaskB();
    Debug.Log("모든 작업 완료");
}

 

출력 결과:

작업 A 시작
작업 A 종료 후 작업 B 실행
모든 작업 완료

모든 작업이 순차적으로 실행됩니다.


코루틴을 활용한 비동기적 실행 예시

IEnumerator CoroutineExample()
{
    Debug.Log("작업 A 시작");
    yield return new WaitForSeconds(2f);
    Debug.Log("작업 A 종료 후 작업 B 실행");
    yield return new WaitForSeconds(1f);
    Debug.Log("모든 작업 완료");
}

void Start()
{
    StartCoroutine(CoroutineExample());
    Debug.Log("메인 루프 계속 실행 중");
}

출력 결과:

작업 A 시작
메인 루프 계속 실행 중
(2초 후)
작업 A 종료 후 작업 B 실행
(1초 후)
모든 작업 완료

메인 루프가 중단되지 않고 계속 실행되면서 특정 작업만 대기하며 실행됩니다.


3. 코루틴 vs 비동기 프로그래밍(Async/Await) 비교

비교 항목 코루틴 (Coroutine) 비동기 프로그래밍 (Async/Await)

실행 방식 단일 스레드에서 실행됨 멀티스레드 활용 가능
제어 방식 yield return을 통해 흐름 제어 await를 통해 비동기 실행
사용 목적 Unity의 프레임 기반 실행 관리 네트워크, 파일 I/O 등의 비동기 처리
중단 가능 여부 가능 (프레임 단위로 실행) 가능 (완료 시까지 대기)

Unity의 코루틴은 동기적 코드 실행을 비동기적 방식으로 연장하는 역할을 하지만,

네트워크 요청 같은 진정한 비동기 작업에는 async/await가 적절합니다.

 

Light와 AnimationCurve 정리

1. Unity의 Light 기능

Light란?🤔

Unity에서 Light는 3D 공간에서 조명을 설정하여 오브젝트를 밝히고 그림자를 생성하는 중요한 요소입니다.

다양한 조명 유형과 설정을 통해 씬의 분위기와 현실감을 조절할 수 있습니다.

Light의 주요 유형

유형 설명

Directional Light 태양광과 같은 무한한 거리에서 평행하게 오는 빛
Point Light 전구처럼 모든 방향으로 빛을 방출하는 광원
Spot Light 손전등과 같이 원뿔 형태로 빛을 비추는 광원
Area Light 직사각형 또는 원형 면적에서 빛을 방출하는 광원 (Realtime 지원 안됨)

Light의 주요 속성

  • Intensity: 빛의 밝기를 조절
  • Range: 빛이 영향을 미치는 거리 (Point, Spot Light에서 사용)
  • Spot Angle: 스포트라이트의 각도 (Spot Light 전용)
  • Color: 빛의 색상을 변경 가능
  • Shadows: 그림자 활성화 여부 및 품질 설정 가능

Light 활용 예시

using UnityEngine;

public class LightControl : MonoBehaviour
{
    public Light sceneLight;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.L))
        {
            sceneLight.enabled = !sceneLight.enabled; // 조명 ON/OFF
        }
    }
}

2. AnimationCurve 기능

AnimationCurve란?🤔

AnimationCurve는 시간에 따라 값이 변화하는 곡선을 정의하는 기능으로, 애니메이션, 물리 효과, 조명 변화 등에 활용됩니다. 보통 float 값의 변화량을 그래프 형태로 제어할 때 사용됩니다.

AnimationCurve 생성 및 사용 방법

using UnityEngine;

public class CurveExample : MonoBehaviour
{
    public AnimationCurve curve;
    private float time = 0f;

    void Update()
    {
        time += Time.deltaTime;
        float value = curve.Evaluate(time); // 현재 시간에 따른 곡선 값 반환
        Debug.Log("Curve Value: " + value);
    }
}

AnimationCurve의 주요 활용 예시

활용 분야 설명

UI 애니메이션 버튼 크기 변화, 투명도 조절 등
카메라 움직임 부드러운 줌 효과, 이동 경로 조절
물리 엔진 조작 점프 곡선, 힘의 변화 적용
조명 변화 조명의 점멸 또는 서서히 밝아지는 효과

AnimationCurve 직접 설정하기

AnimationCurve myCurve = new AnimationCurve(
    new Keyframe(0f, 0f),
    new Keyframe(1f, 1f)
);
  • Keyframe(시간, 값): 특정 시간에서의 값을 정의
  • Evaluate(시간): 해당 시간의 값을 가져옴

AnimationCurve 활용 예시 (빛의 강도 변화)

using UnityEngine;

public class LightAnimation : MonoBehaviour
{
    public Light sceneLight;
    public AnimationCurve lightCurve;
    private float time = 0f;

    void Update()
    {
        time += Time.deltaTime;
        sceneLight.intensity = lightCurve.Evaluate(time % 1f); // 0~1 구간 반복
    }
}

 

코드 분석

이 코드는 Unity에서 주기적인 낮과 밤의 변화(주야 시스템, Day-Night Cycle)를 구현하는 스크립트입니다.
태양(sun)과 달(moon)의 색상과 밝기를 조절하여 시간의 흐름에 따른 조명 변화를 시뮬레이션하는 역할을 합니다.

🔹 DayNightCycle 코드 분석

1. 변수 선언

[Range(0.0f, 1.0f)]
public float time;
public float fullDayLength;
public float startTime = 0.4f;
private float timeRate;
public Vector3 noon;
  • time: 현재 시간(0.0f ~ 1.0f 사이의 값, 하루를 기준으로 0은 자정, 0.5는 정오)
  • fullDayLength: 하루가 얼마나 오래 지속되는지를 초 단위로 정의
  • startTime: 시뮬레이션이 시작될 때의 시간 (기본값 0.4, 아침과 낮 사이)
  • timeRate: fullDayLength를 기반으로 시간이 흐르는 속도를 계산하는 내부 변수
  • noon: 정오의 태양 방향을 나타내는 벡터

2. Light 및 조명 관련 변수

[Header("Sun")]
public Light sun;
public Gradient sunColor;
public AnimationCurve sunIntensity;

[Header("Moon")]
public Light moon;
public Gradient moonColor;
public AnimationCurve moonIntensity;

[Header("Other Lighting")]
public AnimationCurve lightingIntensityMultiplier;
public AnimationCurve reflectionIntensityMultiplier;
  • sun: 태양을 나타내는 Light 컴포넌트
  • sunColor: 태양의 색 변화를 정의하는 Gradient(예: 낮에는 노란색, 저녁에는 붉은색)
  • sunIntensity: 태양 밝기의 변화를 나타내는 AnimationCurve
  • moon: 달을 나타내는 Light 컴포넌트
  • moonColor: 달의 색 변화를 정의하는 Gradient
  • moonIntensity: 달의 밝기를 조절하는 AnimationCurve
  • lightingIntensityMultiplier: 전체적인 광원의 강도를 조절하는 AnimationCurve
  • reflectionIntensityMultiplier: 반사광의 강도를 조절하는 AnimationCurve

3. Start() 메서드: 초기화

private void Start()
{
    timeRate = 1.0f / fullDayLength; // 하루 길이에 따라 시간 흐름 속도 설정
    time = startTime; // 시작 시간을 설정
}
  • timeRate를 하루 길이에 맞춰 시간의 흐름을 조절하는 비율로 설정
  • time을 startTime 값으로 초기화하여 특정 시간에서 시작

4. Update() 메서드: 시간 흐름 및 조명 업데이트

private void Update()
{
    time = (time + timeRate * Time.deltaTime) % 1.0f;
  • timeRate * Time.deltaTime을 더하여 시간이 지속적으로 흐르도록 설정
  • % 1.0f를 통해 time이 1을 넘어가면 다시 0으로 순환 (하루가 반복됨)
    UpdateLighting(sun, sunColor, sunIntensity);
    UpdateLighting(moon, moonColor, moonIntensity);
  • 태양과 달의 조명을 업데이트하는 UpdateLighting() 메서드를 호출
    RenderSettings.ambientIntensity = lightingIntensityMultiplier.Evaluate(time);
    RenderSettings.reflectionIntensity = reflectionIntensityMultiplier.Evaluate(time);
}
  • lightingIntensityMultiplier와 reflectionIntensityMultiplier를 이용하여 환경광과 반사광의 강도를 조절
    (예: 밤에는 어두워지고, 낮에는 밝아짐)

5. UpdateLighting() 메서드: 태양과 달의 조명 업데이트

void UpdateLighting(Light lightSource, Gradient colorGradiant, AnimationCurve intensityCurve)
{
    float intensity = intensityCurve.Evaluate(time);
  • intensityCurve.Evaluate(time)을 사용하여 현재 시간에 따른 조명의 밝기를 가져옴
    lightSource.transform.eulerAngles = (time - (lightSource == sun ? 0.25f : 0.75f)) * noon * 4.0f;
  • 태양과 달의 회전 방향을 설정
    • 태양: 0.25f (새벽 6시 기준)
    • 달: 0.75f (오후 6시 기준)
    • noon * 4.0f를 곱해 하루 동안 360도 회전하도록 조절
    lightSource.color = colorGradiant.Evaluate(time);
    lightSource.intensity = intensity;
  • colorGradiant.Evaluate(time): 현재 시간에 따른 색상 변화를 설정
  • intensity: 밝기를 조절
    GameObject go = lightSource.gameObject;
    if (lightSource.intensity == 0 && go.activeInHierarchy)
        go.SetActive(false);
    else if (lightSource.intensity > 0 && !go.activeInHierarchy)
        go.SetActive(true);
}
  • 조명의 밝기가 0이면 꺼지고, 밝기가 있으면 켜짐
    (예: 낮에는 달을 끄고, 밤에는 태양을 끄는 역할)

🔹 코드 실행 흐름

  1. Start(): 하루 길이에 맞춰 timeRate를 설정하고 초기 시간을 지정
  2. Update():
    • time 값을 증가시켜 낮과 밤의 주기를 만듦
    • 태양(sun)과 달(moon)의 조명을 업데이트
    • RenderSettings를 변경하여 전체적인 조명 환경을 조절
  3. UpdateLighting():
    • 태양과 달의 회전, 색상, 밝기를 조절
    • 태양과 달의 활성화 여부를 결정

🔹 코드의 주요 기능

✅ Gradient와 AnimationCurve를 활용하여 자연스러운 색상 및 밝기 변화 구현
✅ RenderSettings를 조절하여 환경광 및 반사광의 변화 적용
✅ 태양과 달을 회전 및 활성/비활성 처리하여 낮과 밤의 주기적 변화 구현
✅ 낮이 되면 태양이 활성화되고, 밤이 되면 달이 활성화됨

 

// 전체 코드

using UnityEngine;

public class DayNightCycle : MonoBehaviour
{
    [Range(0.0f, 1.0f)] // time 값이 0~1 사이에서 조정될 수 있도록 함
    public float time; // 현재 시간 (0 = 자정, 0.5 = 정오, 1 = 다시 자정)
    public float fullDayLength; // 하루의 길이 (초 단위)
    public float startTime = 0.4f; // 시작 시간 (기본적으로 오전 10시 정도로 설정)
    private float timeRate; // 시간 진행 속도
    public Vector3 noon; // 정오의 태양 방향을 나타내는 벡터

    [Header("Sun")]
    public Light sun; // 태양 조명
    public Gradient sunColor; // 태양의 색상 변화
    public AnimationCurve sunIntensity; // 태양 밝기 변화 곡선

    [Header("Moon")]
    public Light moon; // 달 조명
    public Gradient moonColor; // 달의 색상 변화
    public AnimationCurve moonIntensity; // 달 밝기 변화 곡선

    [Header("Other Lighting")]
    public AnimationCurve lightingIntensityMultiplier; // 전체 광원 강도 조절 곡선
    public AnimationCurve reflectionIntensityMultiplier; // 반사광 강도 조절 곡선

    private void Start()
    {
        timeRate = 1.0f / fullDayLength; // 하루 길이에 따라 시간 진행 속도 설정
        time = startTime; // 시작 시간을 초기화
    }

    private void Update()
    {
        time = (time + timeRate * Time.deltaTime) % 1.0f; // 시간이 계속 흐르도록 설정 (0~1 범위 유지)

        // 태양과 달의 조명 업데이트
        UpdateLighting(sun, sunColor, sunIntensity);
        UpdateLighting(moon, moonColor, moonIntensity);

        // 환경광 및 반사광 강도 조절
        RenderSettings.ambientIntensity = lightingIntensityMultiplier.Evaluate(time);
        RenderSettings.reflectionIntensity = reflectionIntensityMultiplier.Evaluate(time);
    }

    void UpdateLighting(Light lightSource, Gradient colorGradiant, AnimationCurve intensityCurve)
    {
        float intensity = intensityCurve.Evaluate(time); // 현재 시간에 따른 광원 밝기 값 가져오기

        // 태양과 달의 회전 (정오를 기준으로 360도 회전하도록 설정)
        lightSource.transform.eulerAngles = (time - (lightSource == sun ? 0.25f : 0.75f)) * noon * 4.0f;
        
        lightSource.color = colorGradiant.Evaluate(time); // 현재 시간에 따른 광원 색상 설정
        lightSource.intensity = intensity; // 광원 밝기 설정

        GameObject go = lightSource.gameObject;
        if (lightSource.intensity == 0 && go.activeInHierarchy) // 밝기가 0이면 비활성화
            go.SetActive(false);
        else if (lightSource.intensity > 0 && !go.activeInHierarchy) // 밝기가 있으면 활성화
            go.SetActive(true);
    }
}

 

인터페이스 복습 (정석 정리 ...)

1. 인터페이스란?

인터페이스를 통해 클래스들은 공통적인 동작을 정의하고,

이를 구현하는 클래스들은 해당 인터페이스를 구현함으로써 공통 규약을 준수할 수 있습니다.

인터페이스의 주요 특징

  1. 추상화: 인터페이스는 메서드의 시그니처만을 가지며, 실제 구현이 없습니다.
  2. 메서드 시그니처 제공: 인터페이스는 구현 클래스가 반드시 구현해야 할 메서드를 정의합니다.
  3. 다중 상속 가능: 여러 인터페이스를 동시에 구현할 수 있어 다중 상속을 흉내낼 수 있습니다.
  4. 강제적 구현: 인터페이스를 구현한 클래스는 반드시 모든 메서드를 구현해야 합니다.
  5. 인터페이스 확장 가능: 하나의 인터페이스가 다른 인터페이스를 확장(extends)할 수 있습니다.

2. 인터페이스를 사용하는 이유

결합도를 낮추고 유연성을 높이기 위해

  • 클래스 간의 의존도가 높으면 유지보수와 확장이 어려워짐 → 인터페이스를 활용하여 결합도를 낮추자!
  • 구체적인 구현 클래스가 아닌 작은 단위의 여러 인터페이스를 활용하면 코드가 더욱 유연해짐.

협업 관점에서의 장점

  1. 개발 기간 단축: 인터페이스만 작성해 두면, 각 구현 클래스에서 개발을 병렬적으로 진행 가능.
  2. 표준화 가능: 여러 개발자가 작업해도 일관된 구조로 유지할 수 있음.
  3. 독립적인 프로그래밍 가능: 인터페이스가 선언부를 담당하고, 구현부는 별도로 작성할 수 있음.

3. 인터페이스 예제

인터페이스 정의

public interface Payment
{
    void Pay();
}

인터페이스 구현 클래스

public class Card : Payment
{
    public void Pay()
    {
        Console.WriteLine("카드 결제 완료");
    }
}

public class Cash : Payment
{
    public void Pay()
    {
        Console.WriteLine("현금 결제 완료");
    }
}

public class QR : Payment
{
    public void Pay()
    {
        Console.WriteLine("QR 결제 완료");
    }
}

잘못된 설계 (결합도가 높은 경우)

public class Store
{
    Card card;
    Cash cash;
    QR qr;
}
  • Store 클래스가 구체적인 결제 방식(Card, Cash, QR)에 직접 의존하고 있어 확장성이 떨어짐.
  • 새로운 결제 방식이 추가될 경우 Store 클래스를 수정해야 함.

올바른 설계 (인터페이스를 활용한 결합도 낮추기)

public class Store
{
    Payment payment;
    
    public Store(Payment payment)
    {
        this.payment = payment;
    }
    
    public void ProcessPayment()
    {
        payment.Pay();
    }
}
  • Store 클래스는 Payment 인터페이스만 알면 되므로, 구체적인 결제 방식에 의존하지 않음.
  • 새로운 결제 방식이 추가되어도 Store 코드를 수정할 필요 없이 Payment 인터페이스만 구현하면 됨.

사용 예시

Store store1 = new Store(new Card());
store1.ProcessPayment(); // 카드 결제 완료

Store store2 = new Store(new Cash());
store2.ProcessPayment(); // 현금 결제 완료

4. 마무리

  • 인터페이스를 활용하면 코드의 결합도를 낮추고 유지보수를 쉽게 할 수 있음.
  • 구현을 강제함으로써 일관성을 유지할 수 있으며, 다형성을 활용하여 유연한 설계가 가능함.
  • 협업 시 인터페이스를 활용하면 표준화된 방식으로 개발 가능, 독립적인 프로그래밍이 용이해짐.


에러사항