又称为工厂模式,也叫虚拟构造器(Virtual Constructor)模式,或者多态工厂(Polymorphic Factory)模式
工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。
创建抽象产品类 ;
创建具体产品类,继承抽象产品类;
创建抽象工厂类
创建工厂类,继承抽象工厂类,定义具体产品类的创建方法;
通过调用具体工厂类的方法,从而创建不同具体产品类的实例
当一个类不知道它所需要的对象的类时。使用者无需知道具体产品类的类名,只需要知道所对应的工厂即可;
当一个类希望通过其子类来指定创建对象时。由子类来创建具体产品
优点
缺点
自定义工厂模式实践
创建产品抽象类和产品具体类
// 产品抽象类
UCLASS(Abstract)
class DESIGNPATTERNS_API UProductObject : public UObject
{
GENERATED_BODY()
public:
virtual void ShowInfo() { check(0 && "You must override this"); }
};
// 产品具体类A
UCLASS()
class DESIGNPATTERNS_API UProductA : public UProductObject
{
GENERATED_BODY()
public:
virtual void ShowInfo() override {
UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" This is a ProductA"));
}
};
// 产品具体类B
UCLASS()
class DESIGNPATTERNS_API UProductB : public UProductObject
{
GENERATED_BODY()
public:
virtual void ShowInfo() override {
UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" This is a ProductB"));
}
};
创建工厂抽象类和工厂具体类
// 工厂抽象类
UCLASS(Abstract)
class DESIGNPATTERNS_API UFactoryObject : public UObject
{
GENERATED_BODY()
public:virtual UProductObject* CreateNewProduct() {
check(0 && "You must override this");
return nullptr;
}
};
// 工厂具体类A
UCLASS(Blueprintable,BlueprintType)
class DESIGNPATTERNS_API UFactoryA : public UFactoryObject
{
GENERATED_BODY()
public:virtual UProductObject* CreateNewProduct() override {
return NewObject<UProductA>();
}
};
// 工厂具体类B
UCLASS(Blueprintable, BlueprintType)
class DESIGNPATTERNS_API UFactoryB : public UFactoryObject
{
GENERATED_BODY()
public:virtual UProductObject* CreateNewProduct() override {
return NewObject<UProductB>();
}
};
调用
// 调用测试用的Actor
UCLASS()
class DESIGNPATTERNS_API AFactoryActor : public AActor
{
GENERATED_BODY()
public:
UPROPERTY()
UFactoryA* FactoryA;UPROPERTY()
UFactoryB* FactoryB;
void BeginPlay() override {
// A 工厂生成 A 产品
FactoryA = NewObject<UFactoryA>();
UProductObject* ProductA = FactoryA->CreateNewProduct();
ProductA->ShowInfo();// B 工厂生成 B 产品
FactoryB = NewObject&lt;UFactoryB&gt;();
UProductObject* ProductB = FactoryB-&gt;CreateNewProduct();
ProductB-&gt;ShowInfo();
}
};
调式输出
LogTemp: Warning: UProductA::ShowInfo This is a ProductA
LogTemp: Warning: UProductB::ShowInfo This is a ProductB
继承 UObject 自定义资产类
UCLASS(Blueprintable, BlueprintType)
class DESIGNPATTERNS_API UCustomAsset : public UObject
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere)
FString ProductName;
};
继承 UFactory 的工厂类
UCLASS()
class DESIGNPATTERNS_API UUEDefaultFactory : public UFactory
{
GENERATED_UCLASS_BODY()
public:virtual UObject* FactoryCreateNew(UClass* InClass, UObject* InParent, FName InName, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn) override;
//virtual uint32 GetMenuCategories() const override; //4.25以前
};
UUEDefaultFactory::UUEDefaultFactory(const class FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
bCreateNew = true;
bEditAfterNew = true;
SupportedClass = UCustomAsset::StaticClass();
}
UObject* UUEDefaultFactory::FactoryCreateNew(UClass* InClass, UObject* InParent, FName InName, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn)
{
auto newProduct = NewObject<UCustomAsset>(InParent, InClass, InName, Flags);
return newProduct;
}
//uint32 UUEDefaultFactory::GetMenuCategories() const
//{
//return EAssetTypeCategories::Misc;
//}
自定义模块,并添加到工程中
项目目录
DesignPatterns
└─ Source
├─ DesignPatterns
│ ├─ DesignPatterns.Build.cs
│ ├─ DesignPatterns.cpp
│ ├─ DesignPatterns.h
│ ├─ DesignPatternsGameModeBase.cpp
│ ├─ DesignPatternsGameModeBase.h
│ └─ Patterns_Factory
│ ├─ FactoryObject.cpp
│ ├─ FactoryObject.h
│ ├─ ProductObject.cpp
│ ├─ ProductObject.h
│ ├─ UEDefaultFactory.cpp
│ └─ UEDefaultFactory.h
├─ DesignPatternsEditor
│ ├─ DesignPatternsEditor.Build.cs
│ ├─ DesignPatternsEditor.cpp
│ └─ DesignPatternsEditor.h
├─ DesignPatterns.Target.cs
└─ DesignPatternsEditor.Target.cs
添加 DesignPatternsEditor 模块
在Source目录下,分别添加 DesignPatternsEditor.Build.cs
、DesignPatternsEditor.cpp
、DesignPatternsEditor.h
三个文件
DesignPatternsEditor.Build.cs
using UnrealBuildTool;
public class DesignPatternsEditor : ModuleRules
{
public DesignPatternsEditor(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "UnrealEd", "DesignPatterns"});PrivateDependencyModuleNames.AddRange(new string[] { });
// Uncomment if you are using Slate UI
PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
// Uncomment if you are using online features
// PrivateDependencyModuleNames.Add("OnlineSubsystem");
// To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
}
}
DesignPatternsEditor.h
4.25开始需要自定义 AssetTypeActions(继承自 FAssetTypeActions_Base),才可以在编辑器中找到
#pragma once
#include "CoreMinimal.h"
#include "AssetTypeActions_Base.h"
#include "DesignPatterns/Patterns_Factory/FactoryObject.h"
class FDesignPatternsEditorModule : public IModuleInterface
{
public:
/** IModuleInterface implementation */
virtual void StartupModule() override;
virtual void ShutdownModule() override;
};
class FAssetTypeActions_CustomAsset : public FAssetTypeActions_Base
{
public:
FAssetTypeActions_CustomAsset(){}
FAssetTypeActions_CustomAsset(EAssetTypeCategories::Type InAssetCategory);
virtual FColor GetTypeColor() const override { return FColor(97, 85, 212); }
virtual void OpenAssetEditor(const TArray<UObject*>& InObjects, TSharedPtr<class IToolkitHost> EditWithinLevelEditor = TSharedPtr<IToolkitHost>()) override;
// IAssetTypeActions Implementation
virtual FText GetName() const override { return FText::FromName(TEXT("Custom Asset")); }
virtual UClass* GetSupportedClass() const override { return UCustomAsset::StaticClass(); }
virtual uint32 GetCategories() override { return MyAssetCategory; }
private:
EAssetTypeCategories::Type MyAssetCategory;
};
DesignPatternsEditor.cpp
// Copyright Epic Games, Inc. All Rights Reserved.
#include "DesignPatternsEditor.h"
#include "Modules/ModuleManager.h"
#include "IAssetTools.h"
#include "AssetToolsModule.h"
#define LOCTEXT_NAMESPACE "FDesignPatternsEditorModule"
void FDesignPatternsEditorModule::StartupModule()
{
IAssetTools& AssetTools = FModuleManager::LoadModuleChecked<FAssetToolsModule>("AssetTools").Get();
//定义资产的分类名
EAssetTypeCategories::Type AssetCategory = AssetTools.RegisterAdvancedAssetCategory(FName(TEXT("CustomKey")), FText::FromName(TEXT("CustomCategory")));
TSharedPtr<FAssetTypeActions_CustomAsset> actionType = MakeShareable(new FAssetTypeActions_CustomAsset(AssetCategory));
AssetTools.RegisterAssetTypeActions(actionType.ToSharedRef());
}
void FDesignPatternsEditorModule::ShutdownModule()
{
if (FModuleManager::Get().IsModuleLoaded("AssetTools"))
{
IAssetTools& AssetTools = FModuleManager::Get().GetModuleChecked<FAssetToolsModule>("AssetTools").Get();
AssetTools.UnregisterAssetTypeActions(MakeShareable(new FAssetTypeActions_CustomAsset));
}
}
FAssetTypeActions_CustomAsset::FAssetTypeActions_CustomAsset(EAssetTypeCategories::Type InAssetCategory)
{
MyAssetCategory = InAssetCategory;
}
void FAssetTypeActions_CustomAsset::OpenAssetEditor(const TArray<UObject*>& InObjects, TSharedPtr<class IToolkitHost> EditWithinLevelEditor /*= TSharedPtr<IToolkitHost>()*/)
{
FSimpleAssetEditor::CreateEditor(EToolkitMode::Standalone, EditWithinLevelEditor, InObjects);
}
#undef LOCTEXT_NAMESPACE
IMPLEMENT_MODULE(FDesignPatternsEditorModule, DesignPatternsEditor);
将模块加入到 项目名.uproject
中
{
"EngineAssociation": "4.26",
"Modules": [
...,
{
"Name": "DesignPatternsEditor",
"Type": "Editor",
"LoadingPhase": "Default",
"AdditionalDependencies": [
"Engine",
"CoreUObject",
"Slate",
"SlateCore",
"UnrealEd"
]
}
]
}
将模块加入到 项目名.Target.cs
中
using UnrealBuildTool;
using System.Collections.Generic;
public class DesignPatternsEditorTarget : TargetRules
{
public DesignPatternsEditorTarget( TargetInfo Target) : base(Target)
{
Type = TargetType.Editor;
DefaultBuildSettings = BuildSettingsVersion.V2;
ExtraModuleNames.AddRange( new string[] { "DesignPatterns", "DesignPatternsEditor" } );
}
}
测试结果
手机扫一扫
移动阅读更方便
你可能感兴趣的文章