20231211_SOLID원칙, LayerMask, 싱글톤

2023. 12. 11. 22:58IT/TIL

오늘의 TIL은 스탠다드 특강에서 배웠던 내용들이다.

지난 시간에 이어서 SOLID 원칙의 LID와 LayerMask, 싱글톤의 내용이다.

 

SOLID원칙

L : 리스코프 치환 원칙(Liskov Substitution Principle)

하위 클래스는 상위 클래스의 기능을 완전히 대체할 수 있어야 한다는 원칙.

이는 상속 관계에서 어떤 클래스든지 자신의 부모 클래스로 취급될 수 있어야 함을 의미한다.

(상속을 통해서 함수의 취급이 달라지면 안된다)

리스코프 치환 원칙을 어기는 사례

  • 자식 클래스를 만들면서 피처를 제거하는 경우
  • 자신 클래스의 일부를 예외로 처리하는 경우
  • 구현은 있으나 구현이 공백인 경우

리스코프 치환 원칙을 지키는 방법

  • 추상화 간단하게 유지
  • 하위 클래스에서 public 멤버 추가 지양
  • 현실의 분류에 몰두하지 않는다.
  • 컴포지션을 적극적으로 활용
  • 인터페이스를 사용한다.

 

I : 인터페이스 분리 원칙(Interface Segregation Principle)

클라이언트는 자신이 사용하지 않는 인터페이스에 의존하지 않아야 한다는 원칙.

여러 개의 인터페이스로 분리함으로써 클라이언트는 필요한 기능에만 의존할 수 있다.

 

D : 의존 역전 원칙(Dependency Inversion Principle)

의존 관계는 추상화에 의존해야 하며, 구체화에는 의존해서는 안된다는 원칙.

즉, 상위 수준의 모듈은 하위 수준의 모듈에 의존해서는 안되며, 추상화에 의존해야 한다.

 

예시) Switch와 Door

Switch의 Toggle에 따라서 Door가 Open되거나 Close된다.

(Switch - HigherLevel, Door - LowerLevel)

이후에 다른 Switch를 사용하는 것(Laser, Button 등)이 추가된다면,

ISwitchable 이라는 새로운 interface를 만들어서

Toggle 시에 Open, Close, Light, Pushed 등의 기능을 추가해주는 것이 좋다.

 

 

절차지향 vs 객체지향 vs 함수형 프로그래밍

위의 SOLID 원칙은 절차지향에서 객체지향을 위해 만든 원칙들이지만,

무조건 객체지향이 좋은 것이 아니고, 절차지향이 나쁜 것이 아니다.

이후에 추가로 함수형 프로그래밍까지 만들어졌는데,

좋은 코드는 상황에 맞춰서 위의 3가지를 잘 활용하여 코드를 만드는 것이다.

 

 

 

LayerMask

유니티에서는 레이어에 대한 처리를 훨씬 효율적으로 하는 방법으로 LayerMask를 활용한다.

유니티에서는 총 32개(0 ~ 31)의 레이어를 활용할 수 있으며, 이를 한 번에 처리하기 위해 정수형 변환의 각 비트

(32비트)를 할당하여 처리한다. 예를 들어, 카메라에서 특정 레이어에 있는 객체만 촬영하는 Culling Mask를 생각해보면

이를 아래의 이미지처럼 구현할 수도 있다.

하지만 이렇게 하는 경우, 32개의 데이터를 저장할 때 32바이트가 필요하며,

32개의 비교연산을 하게 되어 매우 불필요하게 연산량이 커질 수 있다.

그래서 이를 2진법으로 표현하여 훨씬 더 편리하게 효율적으로 처리할 수 있다.

즉, 하나의 큰 수에 여러 개의 0과 1값을 저장하는 기법이 비트 연산법이다.

 

비트 연산

1. 비트 옮기기(Shift)

비트를 왼쪽으로 옮긴다는 의미에서 비트 시프트연산은 << 처럼 나타내고,

오른쪽으로 옮기는 시프트연산은 >> 처럼 나타낸다.

1 << 2 는 1을 왼쪽으로 2칸 이동한다는 뜻이다.(왼쪽으로 2칸 이동하면 2^2배 커진다)

만약 1 << 8의 연산이 있다면 아래의 이미지처럼 나타낼 수 있다.

 

2. OR 연산

둘 중 하나만 1이여도 1의 값을 반환하게 만드는 방법.

(두 개의 레이어를 적층하는 효과)

이를 통해 어떤 한 비트가 1이 되도록 할 수 있다.

 

3. AND 연산

AND 연산은 자신이 1인 경우에, 상대가 1인지 확인할 수 있는 연산이다.

 

4. 비트 뒤집기(NOT)

 

LayerMask 메소드들

-  LayerMask.GetMask(params string[] layerNames);
LayerName들을 넣어서 비트마스크를 만듭니다.

-  LayerMask.value
비트마스크 값을 도출합니다(실제 이진수를 십진수로 바꿔서 계산) 예) 1025 = 1024 + 1
[QUIZ] LayerMask.value -> 레이어 인덱스를 하려면 어떤 변환을 해야할까요?
-> 2로 나눈 나머지 연산을 해서 그 값을 가지고 붙이면 된다.

-  LayerMask.NameToLayer(string layerName)
레이어의 이름을 통해 레이어의 인덱스(비트 마스크 값이 아님)를 도출합니다. 예) 9

-  LayerMask.Contains(int layerIndex)
LayerMask가 특정한 레이어 인덱스를 포함하고 있는지 확인합니다.

 

비트마스크 상태 이상 시스템

System.Flags를 사용해서 중첩 비트마스크를 부여할 수 있다.

이를 활용해 아래와 같은 상태이상 시스템을 구현할 수 있다.

 

[System.Flags]  // enum을 사용하여 동시에 여러가지 상태를 부여할 수 있게 하는 것
public enum StatusEffects
{
	None = 0,
	Poisoned = 1 << 0, // 0001
	Burned = 1 << 1, // 0010
	Fronzen = 1 << 2, // 0100
	Paralyzed = 1 << 3, // 1000
}

public class StatusEffectManager
{
	private StatusEffects currentEffects = StatusEffects.None;

	public void AddEffect(StatusEffects effect)
	{
		currentEffects |= effect; // or 연산
	}

	public void RemoveEffect(StatusEffects effect)
	{
		currentEffects &= ~effect;  // and 연산 후에 ~로 제거
	}

	public void ClearEffects()
	{
		currentEffects = StatusEffects.None;
	}

	public bool HasEffect(statusEffects effect)
	{
		return (currentEffects & effect) != StatusEffects.None;  // not 연산
	}

	public void PrintEffects()
	{
		Console.WriteLine("Current Status Effects : " + currentEffects);
	}
}

 

 

싱글톤

싱글톤이란 하나의 인스턴스만 생성하고, 어디서든 그 인스턴스에 접근할 수 있는 디자인 패턴이다.

대부분의 사람들이 싱글톤을 쓰는 이유는 객체 간 접근이 용이해지고, 중앙집중식 관리를 위해서 이다.

 

1. 전역적인 상태나 리소스에 접근

싱글톤은 어디서든 접근할 수 있는 전역적인 상태나 리소스에 대한 중앙 집중적인 접근을 제공한다.

예를 들어, 게임의 설정, 오디오 관리자, 이벤트 매니저 등을 싱글톤으로 구현할 수 있다.

-> 한 가지의 상태로 하나가 주가 되어 관리했으면 좋을 경우에 사용할 수 있다.

 

2. 중복 인스턴스 방지

싱글톤 패턴을 사용하면 오직 한 개의 인스턴스만 생성되므로, 중복 인스턴스를 방지할 수 있다.

이는 리소스 낭비나 예기치 않은 동작을 방지하는데 도움이 된다.

 

3. 객체 간 편한 통신

싱글톤 인스턴스는 어디서든 접근할 수 있으므로 객체 간의 통신이 편리해진다.

다른 객체에서 싱글톤 인스턴스를 사용해 데이터를 공유하거나 매서드를 호출할 수 있다.

 

4. 유지보수 및 확장성

싱글톤 패턴은 코드의 유지보수성과 확장성을 향상시킨다. 인스턴스에 대한 접근이

중앙 집중화되므로, 코드의 변경이나 기능의 추가/변경이 용이해진다.

또한, 싱글톤 인스턴스를 사용하는 객체들 사이의 결합도를 낮출 수 있어 유지보수성이 향상된다.

 

싱글톤 사용시 주의사항

1. 상호의존성 증가

싱글톤 인스턴스가 여러 부분에서 사용될 경우, 클래스 간의 상호의존성이 증가하며,

이는 시스템의 결합도를 높이고 응집도를 낮출 수 있다.

 

2. 코드의 복잡성

싱글톤을 과도하게 사용하면 시스템 전반에 걸쳐 복잡도가 증가할 수 있으며,

이는 유지보수를 어렵게 만든다.

 

잘못된 싱글톤 케이스

1. 여러 개 존재하는 싱글톤

static, 중복검사 등을 사용하여 중복이 발생하는 싱글톤은 만들지 않도록 한다.

 

2. 일반적인 클래스에 Manager라는 이름 붙이기

싱글톤은 대부분 XManager로 작성하므로 싱글톤이 아닌 경우에는 Manager라는 이름은 붙이지 않는 것이 좋다.

 

3. 모든 문제를 싱글톤으로 해결하려는 경우(SRP)

 

 

ObjectPool은 사용하면 성능면에서 이득을 보므로 무조건 사용하는 것이 좋지만,

싱글톤은 사용하는 경우의 장단점이 존재하기 때문에,

작업자의 선택에 따라서 추가해도 되고 추가하지 않아도 된다.

'IT > TIL' 카테고리의 다른 글

20231213_Class  (0) 2023.12.14
20231212_ScriptableObject  (0) 2023.12.12
20231208_Generic, 오브젝트풀, SOLID원칙  (0) 2023.12.08
20231207_팀 프로젝트 회고  (1) 2023.12.07
20231206_StringBuilder  (2) 2023.12.06