728x90
1. 응집도 (Cohesion)
정의
- 하나의 모듈(클래스, 스크립트)이 단일 책임 혹은 밀접하게 관련된 기능들만을 모아 수행하는 정도
특징
- 높을수록 유지보수, 확장이 쉬워짐
- 한 모듈의 변경이 내부 기능에만 영향을 주므로 부작용이 적음
예시
/// <summary>
/// 플레이어 체력 관리만 담당하는 클래스 (응집도 높음)
/// 체력 계산에만 집중하고 화면표시나 사망 이펙트 등은 별도 모듈이 담당하도록 분리
/// </summary>
public class PlayerHealth : MonoBehaviour
{
[SerializeField] private int maxHealth = 100;
private int currentHealth;
void Awake()
{
currentHealth = maxHealth;
}
/// <summary>
/// 데미지를 받아 체력을 감소
/// </summary>
public void TakeDamage(int damage)
{
currentHealth -= damage;
currentHealth = Mathf.Max(currentHealth, 0);
// 이 클래스는 UI 업데이트나 사망 처리 로직을 직접 수행하지 않음
}
/// <summary>
/// 현재 체력을 반환
/// </summary>
public int GetCurrentHealth() => currentHealth;
}
2. 결합도 (Coupling)
정의
- 한 모듈이 다른 모듈에 얼마나 강하게 의존하는지 나타내는 척도
특징
- 낮을수록 모듈 변경 시 연쇄적인 수정 범위가 줄고 재사용성과 테스트 용이성 높아짐
- 높을수록 한 클래스 수정 시 다른 클래스 다수 수정 발생, 단위 테스트 어려움
예시
/// <summary>
/// 높은 결함도 예시
/// PlayerController가 EnemyController 내부 구현에 직접 의존
/// </summary>
public class PlayerController : MonoBehaviour
{
public EnemyController enemy; // EnemyController에 직접 참조
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
enemy.TakeDamage(10); // 적 체력 메서드 직접 호출
}
}
}
/// <summary>
/// 낮은 결함도 예시
/// 발행자와 구독자가 인터페이스(이벤트)로만 연결되어 서로 내부 구현 몰라도 동작
/// 데미지 이벤트를 발행(Publisher)하는 클래스
/// </summary>
public class DamagePublisher : MonoBehaviour
{
public static event Action<int> OnDamage;
public void DealDamage(int amount)
{
OnDamage?.Invoke(amount);
}
}
/// <summary>
/// 데미지 이벤트를 구독(Subscriber)하여 체력 처리하는 클래스
/// </summary>
public class EnemyHealth : MonoBehaviour
{
private int health = 100;
void OnEnable()
{
DamagePublisher.OnDamage += HandleDamage;
}
void OnDisable()
{
DamagePublisher.OnDamage -= HandleDamage;
}
/// <summary>
/// 이벤트를 통해 전달된 데미지를 처리
/// </summary>
private void HandleDamage(int dmg)
{
health -= dmg;
Debug.Log($"남은 체력: {health}");
}
}
3. 의존성 (Dependency)
정의
- 한 모듈이 작동하기 위해 다른 모듈이나 서비스, 데이터를 어떤방식으로 사용하는지를 의미
특징
- 명시적 의존성 : 생성자 주입(DI), 인터페이스 활용 -> 테스트 및 교체 용이
- 암시적 의존성 : 싱글톤, Static, FindObjectOfType 등 -> 숨겨진 연결, 가독성, 테스트성 저하
예시
/// <summary>
/// 암시적 의존성
/// 언제 어디서 AudioManager가 생성되는지 불분명, 데스트 어려움
/// </summary>
public class GameManager : MonoBehaviour
{
private AudioManager audioMgr;
void Start()
{
audioMgr = FindObjectOfType<AudioManager>(); // Find 탐색
audioMgr.PlayBgm();
}
}
/// <summary>
/// 명시적 의존성
/// 어떤 IAudioService 구현이 들어올지 모듈 간 결합도를 낮추고, 단위 테스트 시 모의(Mocking) 객체 주입 가능
/// </summary>
public interface IAudioService
{
void PlayBgm();
}
public class AudioManager : MonoBehaviour, IAudioService
{
public void PlayBgm() { /* ... */ }
}
/// <summary>
/// 생성자 주입 방식으로 IAudioService를 받는 예시
/// </summary>
public class GameManager : MonoBehaviour
{
private IAudioService _audioService;
// 의존성 주입(DI) 적용
public void Construct(IAudioService audioService)
{
_audioService = audioService;
}
void Start()
{
_audioService.PlayBgm();
}
}
정리
- 높은 응집도: 한 클래스가 하나의 책임에 집중 → 유지보수·이해 용이
- 낮은 결합도: 모듈 간 인터페이스·이벤트로만 연결 → 수정 충돌 최소화
- 명시적 의존성 관리: DI·인터페이스 활용 → 교체·테스트 편의성 향상
728x90
'개발 > Unity 3D' 카테고리의 다른 글
[Unity] Unity 듀얼 모니터 확장 출력 (1) | 2025.06.13 |
---|---|
[Unity] Unity에서의 SOLID 원칙 (0) | 2025.06.09 |
[Unity] 언어 변경 설정 Localization (0) | 2025.02.07 |
[Unity]MySQL 관련 dll 다운받기 or NuGet 패키지 설치하기 (0) | 2023.08.25 |
[Unity] 스크롤뷰 기본 세팅 (0) | 2023.08.25 |