FlyWeight模式:每个对象参数变得与更新相同

时间:2014-02-28 11:55:35

标签: c# design-patterns xna

大家好,我有飞速模式的问题;

我尝试在我的精灵类中实现flyweight模式。有很多smilarty作为属性,每个Sprite对象只有diffirences是Position和frame;

我的代码ı有问题,每当ı设置(位置或框架)的一个精灵,每个其他对象属性也改变,ı不希望ı希望大多数属性相同但框架和位置是不同的每个对象。

以下是代码:

public enum Type
    {
        sprite,
        None,

    };
    public class FactorySprite 
    {
        private LinkList SpriteList = new LinkList();
        private Hashtable  Sprites = new Hashtable();
        public FactorySprite() 
        {
           // SpriteList.AddtoBegining(new Sprite());
            Sprites.Add(Type.sprite, new Sprite());
        }
        public GameSprite getSprite(Type type) 
        {
            //  return (Sprite)SpriteList.Search(O);
            GameSprite gamesprite = null;
            if(Sprites.ContainsKey(type))
            {
                gamesprite =( GameSprite)Sprites[type];

            }
          return gamesprite;
        }

    } 

    public abstract class GameSprite 
    {
        protected Texture2D texture;
       // protected Vector2 position;
        protected Texture loadTexture;
       // protected int frame;
        protected Vector2 Speed;
        protected Rectangle SourceRectangle;
        protected Color color;
        public Type type;
        protected SpriteBatch spriteBatch;

        public abstract void Draw();
        public  abstract void Update();
        public abstract void setframe(int frame_number);
        public abstract void setPosition(int x,int y);

    }

    public  class Sprite : GameSprite
    {
       private  int frame;
       private Vector2 position;
        public Sprite()
        {
            frame =0;
            type = Type.sprite;
            spriteBatch = Game1.GameInstance.spriteBatch;
            texture = Texture.Instance().GetTexture();

            Speed = new Vector2(0, 1);
            color = Color.White;

        }

        public override void Draw()
        {

            spriteBatch.Draw(texture,position,Image.Instance().drawframe(this.frame), color);

        }
        public override void setframe(int frame_number) {this.frame = frame_number; }
        public override void setPosition(int x, int y)  {this.position = new Vector2(x, y); }
        public  Type getType() 
        { 
            return type;
        } 
        public override void Update(){}
    }

这是manin,它创建工厂flayweight和每个创建

的对象
SpriteManager sm = SpriteManager.Instance();

FactorySprite factory = new FactorySprite();
Sprite s1 = (Sprite)factory.getSprite(Type.sprite);
s1.setframe(6);
s1.setPosition(200, 300);
sm.AddSprite(s1);
Sprite s2 = (Sprite)factory.getSprite(Type.sprite);
s2.setframe(5);
s2.setPosition(100, 100);
sm.AddSprite(s2);

问题在这里更清楚s1和s2具有相同的框架和位置(一个是最后一次更新所有其他对象变得相同)

2 个答案:

答案 0 :(得分:4)

关于FlyWeight模式的事情是,每次你要求一个,你得到相同的实例。因此,每次调用GetSprite时,都会返回相同的文件,而不是副本,而是相同的文件。

因此,如果您调用它两次,则现在有两个对同一对象的引用。如果你在一个地方改变它,它会在另一个地方改变,因为这两个是相同的!这实际上是FlyWeight模式的重点。

我建议您不要像使用不同的对象那样使用此模式。

解决这个问题的方法是提取一个Sprite的所有这些部分,这些部分不会变成新的类,然后你可以使用FlyWeight模式。可更改的位将保留在Sprite类中,并添加对新的“ImutableSprite”实例的引用。

答案 1 :(得分:2)

此处不适用Flyweight模式。

Flyweight意味着您在所有需要此特定值的情况下使用相同的对象。显然,如果您在一个地方更改值,则更改将随处出现。

如果你想减少精灵的数量,你可以使用不可变的语义:当你想要一个具有不同集合的Sprite时,对一组特定的Position,Frame使用单个Sprite实例并创建一个副本。