使用特性实现组件化编程
在游戏开发过程中,经常需要给一个玩家实现一些功能,比如一些登录,好友等,那么怎样可以方便的将这些功能组件挂接到玩家实体上呢?
直接编写在实体中添加功能组件
class CompModule
{
}
class LoginModule: CompModule
{
}
class FriendModule : CompModule
{
}
class Player
{
public Dictionary<string, CompModule> PlayerModules = new Dictionary<string, CompModule>() { { "Login", new LoginModule() }, { "Friend", new FriendModule() } };
CompModule GetModule(string moduleName)
{
if (PlayerModules.ContainsKey(moduleName)) return PlayerModules[moduleName];
return null;
}
}
这种写法是直接在代码中添加,比较直观,但是添加新的功能组件会对原代码改动比较大
使用特性给实体挂载对应的组件
class CompModule
{
public virtual string ModuleName { get; set; }
}
class LoginModule: CompModule
{
public override string ModuleName { get; set; } = "Login";
}
class FriendModule : CompModule
{
public override string ModuleName { get; set; } = "Friend";
}
[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
class ModulesAttr : Attribute
{
public Type[] ModulesTags { get; private set; }
public ModulesAttr(params Type[] tags)
{
ModulesTags = tags;
}
}
[ModulesAttr(typeof(LoginModule), typeof(FriendModule))]
class NewPlayer
{
public Dictionary<string, CompModule> PlayerModules = new Dictionary<string, CompModule>();
NewPlayer()
{
var modulesAttr = Attribute.GetCustomAttribute(GetType(), typeof(ModulesAttr)) as ModulesAttr;
foreach(var mod in modulesAttr.ModulesTags)
{
var compMod = Activator.CreateInstance(mod) as CompModule;
PlayerModules[compMod.ModuleName] = compMod;
}
}
}
通过特性给实体挂载相应的组件,然后在实体构造时,通过反射检测挂载的组件,并将组件进行实例化,后续给玩家实体挂载组件可以直接修改挂载特性就可以,非常方便的进行扩展。