2009-12-22 74 views
0

我正在研究一個遺留系統,它有一些「OO Buzzwords」皺眉和一些我個人不喜歡的設計問題。Java與OO設計

這是一個漫畫書店的股票和銷售處理程序。

我有一個Article類,它可以是任何物品(魔術卡,玩具),以及代表書籍和雜誌的繼承自文章的Publication類。 A Publication有作者和可選的問題編號,而文章沒有。

有一個文章編輯器,它是一個GUI來創建和修改文章。既然有裝載有錯誤發佈,而不是添加捲數的可能性,該接口與文章的工作是:

Article a = EntityManager.loadArticle(articleId); 
ArticleEditor editor = new ArticleEditor(a); 
a = e.getValue(); 

允許被改變成一個出版物,如有需要。

我的一個祕密是,如果它使用引用,或者至少在我看來,這可以更優雅地處理。我目前的版本使用了靜態版本中最後兩行的模式,但它仍然看起來很醜,因爲它看起來過於依賴狀態。


第二個問題帶有Java的(也是最「企業」語言)缺乏多分派:EntityManager的有save()方法,重載兩個Article S和Publication秒。這會導致如果我說一個巨大的問題,例如:

Article a = EntityManager.loadArticle(articleId); 
ArticleEditor editor = new ArticleEditor(a); 
a = e.getValue(); 
EntityManager.save(a); 

這是目前「解決」由具有ArticleEditor保存更改(這似乎是錯誤的)。

我確定必須有一些方法來調整設計以消除這些問題。 (我不介意整個重寫,如果需要的話)。

我如何調整設計,以消除這些問題?

編輯:出版也有作者,不僅數字。

+5

問題是? – Bozho 2009-12-22 20:05:51

+1

「問題」中沒有單個問號。 – mk12 2009-12-22 20:10:17

+1

看到http://bikeshed.com/ – 2009-12-22 20:22:44

回答

0
  1. 什麼問題?對我來說似乎很好。
  2. 難道你不能在Java中使用反射來模擬多個派遣嗎?
+0

1:看起來很醜陋;我想知道是否有更好的方法。 2:'public boolean save(Article a){if(a instanceof Publication){return save((Publication)a); }/*保存正常的文章* /}'?當然,它可以做到。但是添加Article的另一個子類將意味着修改'save'。 – Tordek 2009-12-22 20:32:37

0

我不是第一個問題。對於第二種情況,有時候確實需要多次調度,但可能不是這種情況,簡單的if(article instanceof Publication) save((Publication)article)就好了。你只有幾個班,不要試圖過度設計。

2

我不知道你想如何從根本上重構這個系統,但我懷疑你爲什麼會擁有一個單獨的出版物類只是因爲它是具有出版物號的文章。特別是當你提到有時需要將文章改爲出版物。如果文章不是出版物,您可以允許文章具有「出版物編號」屬性,該屬性可以爲null。這就消除了文章變成出版物的需要(只需將該屬性設置爲非空值),並使EntityManager的問題也消失了。

當然,有一個單獨的出版類可能還有其他原因,我只是繼續我在這裏看到的。

+0

出版物可以是一本書,它有作者,但不是數字(我設置爲'null')。我應該澄清一點。 – Tordek 2009-12-22 21:46:57

1

我想你的意思是a = editor.getValue();在你的例子中?

問題1不是一個真正的問題,除非你說你的文章和出版物是不可變的類嗎?編輯器是在一個Article實例上創建的,如果它與該對象引用一起工作,它的內容將會改變(在UI中的確認/回滾決定之後可能改變它)。

從您的描述中,我認爲文章充當「模板「用於發佈,並且在您的UI中,創建發佈的操作與編輯文章或發佈是分開的。你可以編寫新出版的創建是如下:

Publication p = EntityManager.newPublication(articleId); 
ArticleEditor editor = new ArticleEditor(p); 

問題2可以通過實現保存方法在文章和出版物超載得到解決:

interface ArticleStore { 
} 

class Article { 
    void save(ArticleStore store); 
} 

class EntityManager implements ArticleStore { 
    void save(Article a) { 
     a.save(this); 
    } 
} 

save方法ArticlePublication可以調用ArticleStore接口中的方法,如果將新子類添加到層次結構中,則不需要在EntityManager中進行更改。

編輯已更新以反映評論。

+0

爲什麼你會想把文章變成出版物? – Peter 2009-12-23 07:09:01

0

如果你真的想爲你的第二個問題設計一個面向對象的設計,你可以查看訪問者模式,雖然這可能是一個重大的殺手這樣一個小問題,使用instanceof將更容易完成這個把戲。

0

當我聽到或看到繼承的麻煩時,我會考慮使用構圖。在你的情況下,替代的設計可以

+-------------+    +---------+ 
| Publication |--- has-a ---| Article | 
+-------------+    +---------+ 

因此,出版類將有一個像Article articleReference場和發佈建模所需的所有領域。保存文章不會干擾出版物,保存出版物將保存出版物和相關文章。

發佈編輯器可以擴展文章編輯器並添加所需的發佈GUI字段。

缺點是加載包含其發佈數據的文章需要多行代碼。

編輯

我建議你重命名「文章」類,因爲它可以被誤認爲是寫文章的刊物的一部分。 我的示例完全按照問題中的描述使用'文章',作爲某種類型的主數據模型,包括出版物。

+0

從描述中,我假設'文章'用於此處的項目,而不是用於雜誌中的一段文字。 – rsp 2009-12-23 09:44:48

+0

很高興能得到downvoter的評論... – 2009-12-23 19:44:58