[英]How do I add optional functionality to a class?
我目前正在尝试学习XNA / C#的细节,但我目前仍然遇到一个问题:我想为一个类添加可选功能,我不知道如何开始。 为清楚起见,这是我目前的代码:
public class Actor
{
//Fields
private Vector3 m_location;
//Properties
public Vector3 Location
{
get { return m_location; }
set { m_location = value; }
}
//Constructors
public Actor(float x, float y, float z)
{
Location = new Vector3(x, y, z);
}
public Actor(Vector3 location)
{
Location = location;
}
}
public class Actor2D : Actor
{
//Fields
private Texture2D m_texture;
//Properties
public Texture2D Texture
{
get { return m_texture; }
set { m_texture = value; }
}
//Constructors
public Actor2D(float x, float y, float z) : base(x, y, z) {}
public Actor2D(Vector3 vector) : base(vector) {}
//Methods
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(Texture, new Vector2(Location.X, Location.Y), Color.White);
}
public void Load(ContentManager content, string asset)
{
Texture = content.Load<Texture2D>(asset);
}
}
这里的逻辑是所有Actors必须有一个位置,但它们不一定必须有一个纹理,因为Actor可以是光源,触发器等等.Dord2D在此类似,除了它被指定为一个Actor使用2D纹理。 我想要做的是能够根据需要为这些类中的任何一个添加功能。 假设我想要动画Actor2D或者如前所述我想为无纹理的Actor添加触发器或光源......有哪些想法可以帮助我实现这些目标?
您可以尝试查看装饰器模式 ,它允许您“粘贴”对象的行为。
如果您真的希望对象“变形”,就像在运行时更改其方法集的对象一样,那么您正在研究mixins 。 ( 这里的教程)
公平警告:这不是为了胆小的人。
现在,因为在编译时你知道所有必须可用的类型,所以使用各种接口:
然后为您需要的每个组合提供实现。 此外,我认为最好将所有这些放在您的业务层中(如果有的话)。
希望这可以帮助,
巴布。
编辑:例子。
public interface IMovable { void Move(); }
public class MoveMixin : IMovable
{
public void Move() { Console.WriteLine("I am moving"); }
}
public class SomeDude { }
public static class TestClass
{
public static Test()
{
var myMixinConfiguration = MixinConfiguration.BuildFromActive()
.ForClass<SomeDude>().AddMixin<MoveMixin>()
.BuildConfiguration();
using(myMixinConfiguration.EnterScope())
{//In this scope, SomeDude implements IMovable, but only if you get an instance through the ObjectFactory
var myMovableDude = ObjectFactory.Create<SomeDude>(ParamList.Empty);
((IMovable)myMovableDude).Move(); //This line compiles and executes just fine, even though the class declaration does not specify anything about Move() !!
}
//The SomeDude class no longer implements IMovable
}
}
而不是使Actor2D
(和它的喜欢)派生自Actor
。 只需将这些派生类更改为自己的类,并为每个具有所有这些属性的“Actor”创建一个类( - Actor
)。 ( Actor2D
属性......)然后在运行时使用您需要的任何内容。
他们不会占用那么多资源,因为他们在不使用时会指向null
。
编辑:
class Actor
{
public Stuff2D stuff2d = new Stuff2D();
public StuffLightPower lightPower = new StuffLightPower();
//...
}
class Stuff2D
{
public int height;
public int weight;
//...
}
class StuffLightPower
{
public int lumen;
public Color color;
//...
}
然后像这样使用它:
Actor actor1 = new Actor();
//First it's going to be a 2D.
actor1.stuff2d.weight = 3;
//...
//Now it's changed to a light source.
actor1.stuff2d = null;
actor1.lightPower.color = Color.White;
//...
//And back again.
actor1.lightPower = null;
actor1.stuff2d = new Stuff2D();
//...
所以,经过一番思考和搜索Google / StackOverflow之后。 我终于找到了答案。 我没有使用传统的OOP方法,而是学会了使用更加面向组件的编程方法。 我在基于Component的游戏引擎设计中发现了一个非常棒的链接。
特别感兴趣的是关于T = Machine描述实体系统的5部分系列,它似乎是一种完全符合我要求的方法。 对于那些感兴趣的人,第一篇文章是: http : //t-machine.org/index.php/2007/09/03/entity-systems-are-the-future-of-mmog-development-part-1/ 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.