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

时间:2011-01-09 19:26:12

标签: actionscript design-patterns coupling

有人可以分享如何设计它的方式:

假设我有一些使用Entries构建的数据模型。

基本上,我有一个抽象类Entry(或接口IEntry - 这对案例来说并不那么重要)并且有几个类的实现 - MovieEntry,{{1} },SoundEntry,无论......

其中每一个都是一些数据的包装(网址,描述,卡路里数等),这些数据在每个相应的类中组合在一起。


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

显然我可以提供另一个接口/抽象类并将其称为MovieEntry (它将继承DrawableEntry,然后构建一堆类{{1} }和Sprite看起来像:

DrawableMovieEntry

但对于小型应用程序来说,这似乎有些过分。

另一种方法是使DrawableSoundEntryclass DrawableMovieEntry extends DrawableEntry { // which also extends 'Sprite' private movieEntry:MovieEntry; public override function draw(backend:*) { // Draw everything using the 'movieEntry' reference // stored. }; ,...扩展精灵并自己提供绘图实现 - 但这显然很糟糕,因为数据与它的可视化例程强烈耦合。 / p>

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

2 个答案:

答案 0 :(得分:1)

您构建数据模型的条目尤其被称为值对象(VO)或数据值对象(DVO)。要先回答你的上一个问题,我从不有一个VO扩展基本VO类以外的东西,所以不要扩展Sprite,你会后悔。

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

我有一个值对象的公共标记接口,它有更多特定的子接口来添加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;
    }
}

如果您决定为Entry层次结构使用基类,请使用该基类而不是接口。您希望您的方法要求值对象类型尽可能接近所需对象。

因为您将条目存储在您的显示类中,所以当您单击显示或希望让它执行其他操作时,很容易传递该条目。

这有帮助吗?

答案 1 :(得分:1)

您的用例似乎是Strategy patternCommand pattern的完美示例 策略是更简单的,这是一个例子:

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

package {
  public interface IDrawStrategy {
    function draw( obj:Object ) : void;
  }
}

实施几个DrawStrategies:

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
    }
  }
}

然后将新成员添加到您的基本Entry类:

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()方法,最好保留一个引用; )。