存储对象图形信息的正确方法是什么?

时间:2014-07-09 14:45:09

标签: java oop

我对OOP /设计模式很陌生,我在处理设计问题时涉及将对象的逻辑信息与图形状态分开:

在Java音乐应用程序中,我试图让我有一个 Chord 类,它由 Note 类或 Rest 班级。

在这些课程中我存储"逻辑"信息的midi值,速度等信息

我想在 Staff 对象上绘制这些和弦(它扩展了某种GUI Panel 对象):要做这样的事情,我需要向我添加一些信息类,例如我的对象在工作人员或其符号上的位置。

所以,我制作了图形"等效的"我的类,保存这些图形信息,以及封装我的逻辑和弦,如下图所示:

http://i.imgur.com/b7p00uy.png

但我仍然坚持使用我认为非常奇怪的东西:我的图表在其中心被镜像(这让我觉得我的图形类有些无用)而且我无法创建一个 GraphicChord 来自和弦的对象,因为我无法知道我应该创建 GraphicNote 还是 GraphicRest 对于每个 SimpleElement ,我的和弦包含...

我确定有一些关于设计原则的东西我一定做错了但是我找不到另一种方法来为我的对象添加图形信息...

你能帮帮我吗?

2 个答案:

答案 0 :(得分:0)

  

我无法动态地从Chord创建一个GraphicChord对象,因为我无法知道我是否应该为我的Chord包含的每个SimpleElement创建一个GraphicNote或一个GraphicRest


如果这是拥有Graphic对象的唯一原因,您可以使用instanceof来检查您拥有的SimpleElement类型。

if(myCurrentSimpleObject instanceof Note)
{
   // create Graphic object on the fly
}

如果您想避免使用instanceof,可以通过添加抽象方法来更改SimpleElement类,以确定对象类型。

 abstract boolean isNote();

子类必须实现此方法并返回固定的true或false。 通过返回描述该类的枚举值,可以将其扩展为多个类。
如果您的子课程具有特定于他们的方法,您仍然必须将它们转换为正确的课程。如果您想在执行此操作时避免使用“未经检查的类强制转换”编译器警告,您仍然会遇到instanceof

答案 1 :(得分:0)

您正在使用2组不同的相关对象。你在图中做得很好,有基本的想法,但是,需要一些"清理"。

正如您已经注意到的,一个组由存储数据或模型的对象组成。歌曲对象可以由几个音符组成。

另一组代表数据或模型的视觉或图形表示。您可以显示一个音乐五角星形,它有几个部分,以及同一首歌曲和音符的音符。休息,视觉显示。

您可以使用"装饰器软件设计模式":

http://en.wikipedia.org/wiki/Decorator_pattern

But I'm stuck with something that I think is really strange :
my diagram is mirrored in its center
(which make me think my graphical classes are somewhat useless)
and I can't really create a GraphicChord object from a Chord
on the fly because I can't know if I should make a
GraphicNote or a GraphicRest for each SimpleElement my Chord contains...

在这种问题的情况下,没关系,许多类被复制或镜像",因为一个组代表模型,另一组是同一模型的视觉表示

如果其他人说你错了,不要感到惊讶,因为你有类的副本。在这种特殊情况下,重复信息是正确的。

现在,关于你的问题,请像非编程用户一样思考。非编程用户,不考虑数据或模型类。他/她,考虑接口/ GUI类,并与他们合作。

当用户(或你)创建和弦时,他/她真的会创建一个GraphicalChord,而GraphicalChord将在幕后创建一个内部和弦。用户添加一个Note或Rest,并且实际上添加了一个Graphical Note,或一个Graphical Rest,这些对象将创建一个Data Note或Data Rest,并添加到Chord中。

我建议为非图形类添加前缀或后缀,例如&#34; RealChord&#34;,&#34; DataChord&#34;等等,以避免与GUI类混淆。< / p>

在&#34; SimpleElement&#34;的情况下因为,它已经知道它将有2个子类,你可以添加一个枚举属性来知道它是哪个类。

public enum ElementTypeEnum {
    UNASSIGNED,
    NOTE,
    REST
}

public class SimpleElementClass {
  private ElementTypeEnum _ElementType;

 public void setElementType(ElementTypeEnum n){
    _ElementType = n;
  }
  public ElementTypeEnum getElementType(){
    return _ElementType;
  }

  /* other members */
} // class SimpleElementClass

public class NoteClass extends SimpleElementClass { 
  /* other members */
} // class NoteClass

public class RestClass extends SimpleElementClass { 
  /* other members */
} // class RestClass 

这样,当您添加任何实现子类的对象时,您可以快速推断出它是哪种类型。 Chord课程在某种程度上与&#34; SimpleElementClass&#34; class,而不是子类。

干杯