<컴포넌트 패턴>
상속: A is B
장점) 부모 클래스로부터 물려받은 부분은 다시 쓸 필요가 없으므로 재사용 면에 있어서 효율적임
단점)
- 부모, 조상 클래스가 될 공통된 최소 필수 집합을 개발자가 미리 예상하기 어려움
- 컴포넌트들끼리 커플링이 심함
컴포넌트: A has B
- 각자의 기능을 가지고 있는 스스로 동작하는 독립적인 부품
- 컴포넌트를 뗀다고 해서 오브젝트의 다른 컴포넌트에 영향이 가는 것은 없음
- 코드의 의존성을 줄이고 재활용성을 높임
- 인벤토리 기능은 컴포넌트로 구현하는 것이 좋음
컴포넌트란
: 로직을 기능별로 컴포넌트화하는 것, 기능들을 나누어 각각 독립적인 클래스로 분리
- 한 개체가 여러 분야를 서로 커플링 없이 다룰 수 있게 해줌
<전략 패턴>
인터페이스 & 다형성과 연관
: 여러 알고리즘을 하나의 추상적인 접근점(인터페이스)를 만들어 접근점에서 알고리즘이 서로 교환 가능하도록 하는 패턴
- 동일 목적 알고리즘의 선택 적용
인터페이스 구현
- 클래스 이름 앞엔 대문자 I를 붙여주어야 함
- 멤버 변수를 가질 수 없음
- 멤버 함수들은 전부 프로토타입만 명시해주며 구현하지 않음
<심플 팩토리 패턴>
Factory: 객체 생성을 처리하는 클래스
Factory Pattern: 객체를 생성하고자 할 때 사용하는 패턴
: 주어진 입력을 기반으로 다른 유형의 객체를 리턴하는 메소드가 있는 팩토리 클래스
- 하나의 클래스로 여러가지 타입의 객체(자식)를 찍어내어 리턴하는 함수를 가진 하나의 공장(부모클래스)를 만듦
- 여러 개의 자식 오브젝트들을 하나의 함수로 쉽게 한방에 생성하기 위해 사용하는 패턴
-> 적 생성 시 팩토리 패턴으로 구현해봐야겠음(spawning class)
<팩토리 메서드 패턴>
: 생성하는 공장은 딱 하나, 그러나 어떻게 생성할지에 대한 여러 방식들을 공장의 자식 클래스들로 구현
- 다양한 자식들을 생성하고 리턴하는 팩토리 클래스는 딱 하나만 두고
- 부모인 팩토리 클래스로 서브 팩토리 클래스들을 참조하면, 팩토리 클래스 입장에선 뭘 어떻게 생성하는지 알 필요 없이 그냥 생성만 해주면 됨 -> 다형성
- 유지 보수 편리
<추상 팩토리 패턴>
: 클라이언트에 연관된 객체들의 패밀리를 반환함
팩토리 메서드 패턴과의 차이점)
- 팩토리 메서드 패턴은 팩토리가 되는 클래스가 하나의 객체를 생성하고 리턴하는게 전부
- 추상 팩토리 패턴은 관련 있는 여러 종류의 객체를 특정 그룹으로 묶어 한번에 생성
장점)
- 관리 용이성: 클래스 이름 대신 팩토리 메소드를 사용해 객체를 생성하므로 추후 실제 생성되는 객체가 바뀌거나 추가되어도 문제가 없음
- 보안성: 클래스의 대부분의 내용은 숨기고 싶을 때, 인터페이스나 abstract를 통해서만 접근하게 할 수 있음
- 리소스 재활용성: 반드시 객체를 새로 생성할 필요는 없고 상황에 따라 새로 생성될 수도, 기존의 것을 리턴할 수도 있음
- 상속 구조: 세밀한 팩토리 관리 가능
<원형 패턴>
: 오브젝트를 새로 생성할 시 기존 오브젝트의 복사본으로 생성하여 내용만 조금 수정
- Prototype을 상속받아 clone() 메소드를 구현하는 ConcretePrototype으로 구성됨
- 원형을 하나 가지고 있고, 원형의 Prototype을 상속 받아 clone() 메소드를 구현한 상태라면 Client에서 원할 때 원형으로 클론을 만들어 사용 가능
사용하는 이유)
- 프로토타입 패턴은 비슷한 오브젝트를 지속적으로 생성해야 할 때 유용하게 사용할 수 있음
- 동적 클래스 확장
- 해당 객체를 얕은 복사로 단순 복사본 객체를 생성하고 리턴함
<경량 패턴>
: 한 개의 고유 상태를 다른 객체들에서 공유하게 만들어 메모리 사용량을 줄임
- 내용이 같은 객체가 이미 있으면 새로 객체를 또 만들지 않고 그 내용 같은 기존 객체를 공유함
- 경량 패턴에서의 객체 데이터 종류
구현)
- 인스턴스를 요청 받았을 때 이전에 같은걸 만들어 놓은게 있는지 확인해보고 있다면 그걸 리턴해야 공유 기능 유지됨
<Builder Pattern>
: 객체를 생성할 때, 그 객체를 구성하는 부분 부분을 단계별로 먼저 생성하고 이를 조합함으로써 객체 전체를 생성함
- 복잡한 유형의 오브젝트를 작성할 때 도움됨
- 생성할 객체의 종류를 손쉽게 추가, 확장이 가능한 설계
- 플레이어 캐릭터 별개의 옷, 무기 등등을 조합하고 장착하는 등등 여러가지 경우에 사용될 수 있음
빌더 패턴 vs 추상 팩토리 패턴
Builder
- 복잡한 객체의 단계별 생성에 중점을 두고 있는 패턴
- 마지막 단계에서 생성한 제품을 리턴함
Abstract Factory
- 제품의 유사군들이 존재하는 경우 유연한 설계에 중점을 두는 패턴
- (단계마다) 만드는 즉시 제품을 리턴함
<상태 패턴>
: 상태를 별도의 클래스로 캡슐화한 다음 현재 상태를 나타내는 객체에게 행동을 위임함
- 따라서 내부 상태가 바뀜에 따라 행동이 달라짐
- 동적으로 행동을 교체할 수 있음
- 전략 패턴과 구조는 거의 동일하나 쓰임의 용도가 다름
핵심 정리)
- 상태 패턴을 사용하면 내부 상태를 바탕으로 여러가지 서로 다른 행동을 사용할 수 있음
- 상태 패턴을 사용하면 FSM을 쓸 때와 달리 각 상태를 클래스를 이용하여 표현하게 됨
- 상태를 사용하는 Context 객체에서는 현재 상태에게 행동을 위임함
- 각 상태를 클래스로 캡슐화함으로써 나중에 변경시켜야 하는 내용을 국지화시킬 수 있음
- 상태 패턴과 전략 패턴의 용도 차이점
- 상태 전환은 State 클래스에 의해 제어할 수도 있고 Context 클래스에 의해 제어할 수도 있음
- State 클래스를 여러 Context 객체의 인스턴스에서 공유하도록 디자인할 수도 있음
<옵저버 패턴>
: 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들한테 연락이 가서 자동으로 내용이 갱신되는 방식, 1:N 의존성을 정의
Subject 객체의 변수 값 변경이 일어나면 Observer 객체들에게 이를 알림
각각의 Observer 객체들의 updat() 함수에서 이를 감지하고 이에 따른 동작들을 수행
- Subject가 Observer에 대해서 아는 것은 Observer가 특정 인터페이스를 구현한다는 것뿐
- Observer는 언제든지 새로 추가할 수 있음
- 새로운 형식의 Observer를 추가하려 해도 Subject를 전혀 변경할 필요가 없음
- Subject나 Observer가 바뀌더라도 서로에게 전혀 영향을 주지 않음, 그래서 Subject와 Observer는 서로 독립적으로 재사용할 수 있음
Subject에서 Observer들을 리스트로 관리를 하고, 이 리스트를 순회하며 옵저버들의 함수를 실행시키는 식으로 작동함
-> 유니티, C#에서의 델리게이트와 같음(델리게이트가 곧 이 옵저버 패턴인 것)
<어댑터 패턴>
: 이미 제공되어 있는 것과 필요한 것의 차이를 없애주는 디자인 패턴
- 한 클래스의 인터페이스를 클라이언트에서 사용하고자 하는 다른 인터페이스로 변환함
- 어댑터를 이용하면 인터페이스 호환성 문제 때문에 같이 쓸 수 없는 클래스들을 연결해서 쓸 수 있음
- Adapter 패턴은 Wrapper 패턴으로 불리기도 함
종류)
- 클래스에 의한 Adapter 패턴 (상속을 사용한 Adapter)
- 인스턴스에 의한 Adapter 패턴 (위임을 사용한 Adapter)
Adapter를 사용하는 경우)
- 이미 존재하고 있는, 버그 적은 클래스를 부품으로서 재사용
- Adapter 패턴은 기존의 클래스를 개조해서 필요한 클래스를 만듦
- 이미 만들어진 클래스를 새로운 인터페이스에 맞게 개조시킬 때는 당연히 Adapter 패턴을 사용해야 함
<명령 패턴>
: 함수 호출을 자체를 실체화, 즉 객체로 감싼 것
- 요청 자체를 캡슐화 하는 것
- 함수 호출을 객체로 만들었으므로 디커플링으로 코드가 유연함
- 사용 예) 입력 키 변경, 실행 취소 / 재실행
'Old > Unity' 카테고리의 다른 글
RPG Project 오류 일지 - Respawn (0) | 2023.08.15 |
---|---|
Scriptable Object (0) | 2023.07.24 |
체감형 AR 디자인 - 최적화 (0) | 2023.05.17 |
Object Pool (0) | 2023.05.06 |
C# / 싱글톤 디자인 패턴 (0) | 2023.05.06 |