Flash/ActionScript-应用程序设计问题

Flash/ActionScript-应用程序设计问题,actionscript,design-patterns,coupling,Actionscript,Design Patterns,Coupling,有没有人可以分享一下设计方法: 假设我有一些数据模型,它是使用条目构建的 基本上,我有一个抽象类Entry(或者接口IEntry,这对本例来说并不重要),并且有几个此类的实现-MovieEntry,SoundEntry,FoodEntry,等等 其中每一个都是一些数据(url、描述、卡路里数等)的包装器,这些数据在每个相应的类中分组在一起 现在-如果我希望在屏幕上显示条目的数据(比如电影海报和电影条目的注释)-我应该如何设计 显然,我可以提供另一个接口/抽象类,并将其称为DrawableEnt

有没有人可以分享一下设计方法:

假设我有一些数据模型,它是使用
条目构建的

基本上,我有一个抽象类
Entry
(或者接口
IEntry
,这对本例来说并不重要),并且有几个此类的实现-
MovieEntry
SoundEntry
FoodEntry
,等等

其中每一个都是一些数据(url、描述、卡路里数等)的包装器,这些数据在每个相应的类中分组在一起


现在-如果我希望在屏幕上显示条目的数据(比如电影海报和
电影条目的注释
)-我应该如何设计

显然,我可以提供另一个接口/抽象类,并将其称为
DrawableEntry
(它将继承
Sprite
),然后构建一组类,如
DrawableMovieEntry
DrawableSoundEntry
,它们可能看起来像:

class DrawableMovieEntry extends DrawableEntry { // which also extends 'Sprite'

   private movieEntry:MovieEntry;

   public override function draw(backend:*) {
      // Draw everything using the 'movieEntry' reference
      // stored.
};
但对于一个小应用程序来说,这似乎有点过头了

另一种方法是制作
MovieEntry
SoundEntry
。。。扩展sprite并自己提供图形实现——但这显然是不好的,因为数据与它的可视化例程紧密耦合


那么-这应该怎么做?也许MVC方法可以为这种情况提供一些帮助?

构建数据模型时使用的条目被称为值对象(VO)或数据值对象(DVO)。首先回答你的最后一个问题,我不会让一个VO扩展一个基本VO类以外的东西,所以不要扩展Sprite,以后你会后悔的

转到层次结构。您正在扩展抽象类
Entry
以创建具体的子类,但是由于您还提到了一个可能的接口,我不确定您是否应该使用extend。仅当值对象实际共享公共属性时,才使用公共基类。如果每个条目都有一个
title
属性,那么可以将该属性放入
entry
中并对其进行子类化。如果你的摘要是空的,我建议你使用一个标记(=empty)接口

我有一个用于值对象的通用标记接口,它有更多特定的子接口来添加xml解析或组合等功能。一旦您开始为此使用接口,就很容易进行增强

然后显示。这个问题没有一个正确的答案,因为你的例子仍然很广泛。但我会将VO作为一个整体传递给对象,通过一个方法声明它将存储VO并重新绘制它自己

interface IEntryDisplay {
    redrawWithEntry(entry:IEntry):void;
}
使用IEntry接口将对象作为一个整体传递。在您的实现中,使用带有
is Type
条件的if级联来进行绘图

public function redrawWithEntry(entry:IEntry):void {
    this.entry = entry;

    if (entry is MovieEntry) {
        title.text = MovieEntry(entry).title;
    } else if (entry is SoundEntry) {
        title.text = "(Sound) "+SoundEntry(entry).fileName;
    }
}
如果决定为条目层次结构使用基类,请使用该基类而不是接口。您希望您的方法要求值对象类型尽可能接近所需的对象

因为您将条目存储在display类中,所以当您单击显示或希望它执行其他操作时,很容易在一段时间后传递


这有帮助吗?

您的用例似乎是或的完美示例。
战略是比较简单的一个,下面是一个例子:

创建一个IDrawStrategy界面,如下所示:

package {
  public interface IDrawStrategy {
    function draw( obj:Object ) : void;
  }
}
实施若干战略:

package {
  public class SoundEntryDrawStrategy implements IDrawStrategy {
    public function draw (obj:Object) : void {
       // cast obj to SoundEntry and do all the drawing necessary, 
       // or fail if obj is null or not a SoundEntry
    }
  }
}

package {
  public class MovieEntryDrawStrategy implements IDrawStrategy {
    public function draw (obj:Object) : void {
       // cast obj to MovieEntry and do all the drawing necessary
       // or fail if obj is null or not a MovieEntry
    }
  }
}
等等

然后将新成员添加到基本条目类:

private var _drawStrategy:IDrawStrategy;
并创建一个setter:

public function set drawStrategy ( strat:IDrawStrategy ) : void {
    _drawStrategy = strat;
}
以及绘制方法:

public function draw () : void {
  _drawStrategy.draw( this );
}
现在,您可以为每个条目分配和执行拟合策略:

var mov:MovieEntry = new MovieEntry();
mov.drawStrategy = new MovieEntryDrawStrategy();
mov.draw();

顺便说一句,您在其中绘制信息的精灵可以(但不必)是DrawStrategy类的成员,但是如果您想稍后添加clear()方法,最好保留一个引用;)

这取决于应用程序,如果它是一个简单的迷你网站或“一次性”演示之类的东西,你不应该对此太担心。您可以在视图类中找到最常用的行为,在使用每个单独视图扩展的基本视图类中对其进行编码,希望只有少数类需要重写draw方法。