有人可以分享如何设计它的方式:
假设我有一些使用Entries
构建的数据模型。
基本上,我有一个抽象类Entry
(或接口IEntry
- 这对案例来说并不那么重要)并且有几个类的实现 - MovieEntry
,{{1} },SoundEntry
,无论......
其中每一个都是一些数据的包装(网址,描述,卡路里数等),这些数据在每个相应的类中组合在一起。
现在 - 如果我希望显示屏幕上条目的数据(让我们说FoodEntry
的电影海报和注释) - 我该如何设计?
显然我可以提供另一个接口/抽象类并将其称为MovieEntry
(它将继承DrawableEntry
),然后构建一堆类{{1} }和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.
};
,...扩展精灵并自己提供绘图实现 - 但这显然很糟糕,因为数据与它的可视化例程强烈耦合。 / p>
那么 - 应该怎么做?也许MVC方法可以为这种情况提供一些东西?
答案 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 pattern或Command 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()方法,最好保留一个引用; )。