1

誰かがこれをどのように設計すべきかを共有できますか:

を使用して構築されたデータモデルがあるとしEntriesます。

基本的に、私は 1 つの抽象クラスEntry(またはインターフェイスIEntry- この場合はそれほど重要ではありません) を持ち、このクラスのいくつかの実装を持っています - MovieEntry, SoundEntry, FoodEntry, 何でも...

これらはそれぞれ、いくつかのデータ (URL、説明、カロリー数など) のラッパーであり、このデータは対応する各クラスにグループ化されます。


ここで、エントリのデータを画面に表示したい場合(たとえば、映画のポスターや の注釈などMovieEntry)、どのように設計すればよいでしょうか?

明らかに、私は別のインターフェース/抽象クラスを提供してそれを呼び出し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.
};

しかし、これは小さなアプリケーションにとってはやり過ぎのようです。

もう 1 つの方法は、MovieEntry, SoundEntry, ... スプライトを拡張し、描画の実装自体を提供することですが、データがその視覚化ルーチンと強く結合されるため、これは明らかに悪いことです。

それで - これはどのように行うべきですか?MVC アプローチには、この場合に提供できるものがあるのではないでしょうか?

4

2 に答える 2

1

あなたのユースケースは、戦略パターンまたはコマンドパターンの完璧な例のようです.
戦略はより単純なものです。以下に例を示します。

次のような 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;

そしてセッターを作成します:

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() メソッドを追加する場合は、参照を保持することをお勧めします;)。

于 2011-01-10T10:38:01.310 に答える
1

データ モデルを構築するエントリは、とりわけ、値オブジェクト (VO) またはデータ値オブジェクト (DVO) と呼ばれます。最後の質問に最初に答えるために、私はVO がベース VO クラス以外のものを拡張することは決してないので、Sprite を拡張しないでください。後で後悔するでしょう。

ヒエラルキーへ。抽象クラスEntryを拡張して具体的なサブクラスを作成していますが、可能なインターフェイスについても言及しているため、拡張を使用する必要があるかどうかはわかりません。値オブジェクトが実際に共通のプロパティを共有している場合にのみ、共通の基本クラスを使用してください。すべてのエントリにtitleプロパティがある場合は、それを入れてEntryサブクラス化します。アブストラクトが空になる場合は、代わりにマーカー (=空) インターフェイスを使用することをお勧めします。

xml 解析や構成などの機能を追加するためのより具体的なサブインターフェイスを持つ、値オブジェクト用の共通マーカー インターフェイスがあります。このためにインターフェースを使い始めると、拡張は簡単です。

次に表示です。あなたの例はまだかなり広いので、これに対する正しい答えは1つではありません。ただし、VO を保存してそれ自体を再描画することを示すメソッドを使用して、VO をオブジェクト全体に渡します。

interface IEntryDisplay {
    redrawWithEntry(entry:IEntry):void;
}

IEntry インターフェイスを使用して、オブジェクト全体を渡します。実装では、条件付きの if カスケードを使用is Typeして描画を行います。

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 階層に基本クラスを使用する場合は、インターフェイスの代わりにそれを使用します。必要なオブジェクトにできるだけ近い値オブジェクト型を要求するメソッドが必要です。

エントリはディスプレイ クラスに保存されるため、しばらくしてからディスプレイをクリックしたときや、別の処理をさせたいときに簡単に渡すことができます。

これは役に立ちますか?

于 2011-01-09T22:23:45.190 に答える