JWorld@TW the best professional Java site in Taiwan
      註冊 | 登入 | 全文檢索 | 排行榜  

» JWorld@TW » Software Design  

按列印兼容模式列印這個話題 列印話題    把這個話題寄給朋友 寄給朋友    訂閱主題
reply to topicthreaded modego to previous topicgo to next topic
本主題所含的標籤
無標籤
作者 有關 Composite 的問題
DJWS

小捷



發文: 20
積分: 0
於 2006-06-02 13:50 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
我現在正嘗試設計一個簡單的 UML class diagram editor。它有幾個簡單的功能,例如在物件之間建立關聯、進行群組化。我利用了 Composite 的設計模式,class diagram 如附圖所示。

這套軟體有個需求是這樣的:使用者可以在基本物件之間建立關聯,但是不能對群組物件建立關聯。至於建立關聯的方法,是用滑鼠按下、拖曳、放開的動作來決定的,所以我設計了以下這段程式碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class Canvas implements java.awt.MouseListener {
  Vector<Component> comps;
 
  Component c1, c2;
 
  public Component getSelected(Point p) {
    for (Iterator i = comps.iterator(); i.hasNext(); ) {
      Component c = i.next();
      if (c.contains(p))
        return c;
    }
    return null;  
  }
 
  public void mousePressed(MouseEvent e) {
    c1 = getSelected(e.getPoint());
 
    if (c1 instance of Composite)
      c1 = null;
  }
 
  public void mouseReleased(MouseEvent e) {
    c2 = getSelected(e.getPoint());
    
    if (c2 instance of Composite)
      c2 = null;
 
    if (c1 && c2) {
      new RelationLine(c1, c2);
      ........
    }
  }
}

我想,使用 instance of 是個不好的作法。和別人討論過後,只好強硬地使用多型 (polymorphism) 來解決問題。程式碼就變成了以下這樣:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
class Canvas implements java.awt.MouseListener {
  Vector<Component> comps;
 
  Component c1, c2;
 
  public Component getSelected(Point p) {
    for (Iterator i = comps.iterator(); i.hasNext(); ) {
      Component c = i.next();
      if (c.contains(p))
        return c;
    }
    return null;  
  }
 
  /**
   *  新增一個 method 以解決問題
   */
  public Component getRelationTarget(Point p) {
    Component c = getSelected(p)
    return c.getRelationTarget();
  }
 
  public void mousePressed(MouseEvent e) {
    c1 = getRelationTarget(e.getPoint());
  }
 
  public void mouseReleased(MouseEvent e) {
    c2 = getRelationTarget(e.getPoint());
    
    if (c1 && c2) {
      new RelationLine(c1, c2);
      ........
    }
  }
}
 
class Composite extends Component {
  public void getRelationTarget() {
    return null;
  }
}
 
class Entity extends Component {
  public void getRelationTarget() {
    return this;
  }
}


寫到這裡,心中就浮現了兩個問題:ㄧ、這段程式看起來實在太拙了,會有更好的寫法嗎?二、如果還有其他類似的需求,在多型的原則下,那麼我就得替每個需求都撰寫ㄧ個對應的 method。而這些 method 看起來是不能重複利用在其他地方的。這樣method豈不是越來越氾濫、越來越雜了嗎?

想請問大家這兩個問題有更好的解決方法嗎? Big Smile

--
DJWS, a newbie in programming Wink


DJWS edited on 2006-06-02 13:52
reply to postreply to post
作者 Re:有關 Composite 的問題 [Re:DJWS]
koji

秒速5センチメートル

站長

發文: 8415
積分: 19
於 2006-06-06 18:00 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
看到現在為止應該是還可以的設計
因為不知道你未來需求是怎樣的需求
譬如如果是點下以後可以拖曳,那麼你這邊就得想一下該怎麼修改那個getRelation

如果你覺得不好可以想想看,如果照你原本寫法
新增了需求,就只能一直把method變大
那麼反而更糟

koji


reply to postreply to post
JCConf Taiwan 2015 開始售票了!!
Facebook上的TWJUG社團,歡迎加入
» JWorld@TW »  Software Design

reply to topicthreaded modego to previous topicgo to next topic
  已讀文章
  新的文章
  被刪除的文章
Jump to the top of page

JWorld@TW 本站商標資訊

Powered by Powerful JuteForum® Version Jute 1.5.8