객체 지향프로그래밍에서의 컴포지션 이란? 객체 지향 프로그래밍에서의 설계는 크게 상속과 컴포지션 의 활용으로 요약할 수 있는데, 상속은 성질이 같은 부모클래스와 자식 클래스와의 관계를 의미하는 Is-A 관계라고 보통 이야기 하고. 컴포지션은 성질이 다른 두 객체에서 어떤 객체가 다른 객체를 소유하는 Has-A 관계라고 요약할 수 있습니다. 컴포지션을 활용하면, 복합적인 기능을 거대한 클래스를, 효과적으로 설계하는데 유용하게 사용할 수 있습니다.
모던 객체 설계 기법 SOLID 를 명심하여 설계해야 합니다.
모던 객체 설계 기법의 설계 핵심은 상속을 단순화하고, 단순한 기능을 가진 다수의 객체를 조합해 복잡한 객체를 구성하는데 있습니다.
카드를 가진 사람
#pragma once
#include "CoreMinimal.h"
#include "UObject/NoExportType.h"
#include "Card.generated.h"
/** 카드의 유형을 나타내는 카드타입 열거형*/
UENUM()
enum class ECardType : uint8
{
STUDENT = 1 UMETA(DisplayName = "ForStudent"), // 학생
TEACHER UMETA(DisplayName = "ForTeacher"), // 선생님
OUTSIDER UMETA(DisplayName = "OutSider"), // 외부인
INVALID
}
/** 사람이 지니고 있어야할 카드 를 표현하는 클래스 */
UCLASS()
class MODULENAME_API UCard : UObject
{
GNERATED_BODY()
public:
UCard();
UPROPERTY()
int32 IdNumber;
UPROPERTY()
ECardType CardType;
public:
FORCEINLINE GetCardIdNumber(){return IdNumber;}
FORCEINLINE void SetCardIdNumber(int32 NewIdNumber){IdNumber = NewIdNumber;}
FORCEINLINE ECardType GetCardType(){return Type;}
FORCEINLINE void SetCardType(ECardType NewCardType){CardType = NewCardType;}
}
#inlude "Card.h"
UCard::UCard()
{
IdNumber = 0;
CardType = ECardType::INVALID;
}
#pragma once
#include "CoreMinimal.h"
#include "UObject/NoExportType.h"
#include "Person.generated.h"
/** 하나의 사람을 표현하는 클래스 */
UCLASS()
class MODULENAME_API UPerson : public UObject
{
GNERATED_BODY()
public:
UPerson();
UPROPERTY()
FString Name;
UPROPERTY()
TObjectPtr<class UCard> Card; // 다른 클래스를 소유합니다.(컴포지션) , 최대한 의존관계를 없애기 위해 '전방선언' 합니다.
/**
오브젝트 포인터 를 선언하는 방식은
UE4 까지는 * 로 사용하였지만,
UE5 부터는 다른 방법으로 하기를 권장하고 있다.
선언부에서는, 원시포인터 * 대신, TObjectPtr<> 을 사용하도록 권장하고,
구현부에서는 그냥 * 를 사용해도 된다.
즉,
class UCard* Card; 로 사용했던것을
UObjectPtr<class UCard> 로 사용하도록 한다.
또한
함수의 인수, 반환형에는 * 를 쓰고
TArray, TMap 에서도 템플릿으로는 * 을 쓴다.
UObject* GetObject();
TArray<UObject*>
*/
}
#include "Person.h"
#include "Card.h"
UPerson::UPerson()
{
Name = TEXT("홍길동");
// 생성자 단계, 즉 CDO 에서 클래스를 생성하려면 CreatureDefaultSubobject API 를 사용해야 합니다.
Card = CreatureDefaultSubobject<UCard>(TEXT("Name_Card"));
}