在模型和模型之间共享数据应用程序的视图

时间:2012-11-16 20:15:13

标签: actionscript-3 architecture

我目前正在尝试找到一个“明确的”解决方案(意思是:找到一个看起来很有效,符合OOP规则的解决方案)来解决我曾经历过一段时间的反复出现的问题:不同的共享数据问题我的代码的一部分。

请注意,我在此处使用任何MVC框架。我只是将我的数据类称为模型,并将显示类称为View(因为它的名称与MVC模式无关,人们在创建MVC模式之前创建了视图和模型方式“)。

这是我的问题:     每当我创建一个使用一些相当扩展的数据的应用程序(例如游戏)时,我会尝试将逻辑(移动,碰撞等)分开并显示在两个类中。但是,我偶然发现了这个问题:如何将我的逻辑类中存储的数据与视图类中的相应显示对象“绑定”,而不会在不同类之间复制数据,引用或其他内容?

让我们举一个基本的例子:

  • 我有一个MyLogicClass,持有一个“EntityData”对象的Vector(每个对象都有位置,大小,各种状态,所有东西都可以处理我项目的逻辑)

  • 我有一个MyViewClass,为MyLogicClass中的每个EntityData创建和显示Sprite,并在游戏循环中更新后移动它们。

我想到的第一件事就是将每个数据元素存储在其对应的视图中,从而允许我遍历我的Vector以更新项逻辑,然后相应地更新视图。但这迫使我在MyViewClass中保存一个MyLogicClass引用,以确保我可以定位实体数据,迫使我将两个类(我不想做的事情)结合起来。

另一方面,每个实体都有一个ID的解决方案,在我的数据模型(MyLogicClass的具有ID参数的EntityData对象)和我的View类(Sprites持有对其原始实体数据ID的引用)中。但是当我想要定位一个特定的实体,迫使我在我的数据模型中循环它时,然后再循环它以在我的视图中找到相关的Sprite。这个解决方案允许我在我的数据和视图之间松散耦合,但每帧两次循环数百个元素(可能发生!)真的听起来不是我的性能优化。

我可能会将整个问题视为应该得到的更重要的问题,但我已经不止一次地磕磕绊绊,而且我希望能有一些其他观点,而不是我的观点。

你们对这样的问题有什么建议/解决方案吗?

对于这种情况,是否还有其他一些我可能不知道的数据格式/层次结构?

2 个答案:

答案 0 :(得分:1)

我所做的是使用事件和事件监听器将它们“链接”在一起。我有“模型部件”抛出“显示部件”捕获和渲染/更新的特定事件。

我发现这确实让我通过编写可以监听某些事件的测试代码来构建我的一些测试,并以错误方式检查它。我的代码仍然是自己分开和可测试的:我可以通过触发并确保正确值的事件被抛出来测试我的“模型”。同样,我可以编写一些测试代码来抛出可以被“显示”捕获的预设事件,看它是否有任何问题。

然后一旦它全部工作,我只是重用那些相同的事件监听器并链接到'彼此'。

稍后我的“控制器”(用户输入)将操纵“模型”部分,这将导致事件被抛出到“显示”,从而被渲染/更新。

我不知道在遵循mvc模式方面这是否“正确”,也不知道我对这些事情有任何正式的了解。我也会对别人的知识渊博感兴趣。

答案 1 :(得分:0)

我想也许你已经过度思考了这个问题。我有时这样做。

您的视图类必须显示某种类型的模型链接,事件是一种很好的方法。这里有些东西让你有个主意。

 // Model class
 package
 {
    class MyModel extends EventDispatcher
    {
        // you can make them public but that would 
        // be against some oop practices. so private it is
        private var m_position:Vector2D; 

        MyModel(){}

        // one way of doing getters/getters
        // example: theModel.SetPosition(something);
        public function GetPosition():Vector2D { return m_position; }
        public function SetPosition(value:Vector2D):void 
        { 
            m_position = value; 
            ModelChanged();
        }

        // the other way
        // sample: theModel.position = something;
        public function get position():Vector2D {return m_position; }
        public function set position(value:Vector2D):void 
        { 
            m_position = value; 
            ModelChanged();
        }

        private function ModelChanged():void
        {
            dispatchEvent(new Event(Event.CHANGE));
        }
    }
}


// now for our view.
package
{
    class MyView extends Sprite // or whatever
    {
        private var model:MyModel;

        MyView(model:MyModel)
        {
            this.model = model;

            model.addEventListener(Event.CHANGE, handleModelChanged);

            // fire off an event to set the initial position.
            handleModelChanged(NULL);
        }

        private function handleModelChanged(evt:Event):void
        {
            x = model.position.x;
            y = model.position.y;
            // etc etc etc.
        }
    }
}

无论如何你不需要设置器,如果你在模型文件中有逻辑也很明显,如果模型之外没有任何东西需要改变它没有理由设置器。但你确实需要吸气剂。

这将模型与视图分离,您可以以任何方式编写任何视图,而您必须提供的只是模型更改时的处理程序。只需使用getter公开您的视图所需的任何数据。

您现在只需循环遍历模型,如果更改它将触发事件,并且正在监听的视图将更新。

希望我没有错过任何内容,这解释了你的想法。

编辑:我忘了添加,如果您使用类似更新功能的东西,则不必在整个地方都有“ModelChanged()”。只需更新,并在完成事件后完成。

相关问题