2009-07-19 87 views
3

我有一個句子,它分爲不同的階段。首先,我得到一些屬性(比如,X,Y,Z):分裂或不分裂一個類(在Java中)

public class AnalyzedSentence { 
    private String X; 
    private String Y; 
    private String Z; 

    public AnalyzedSentence(String sentence) { 
     extractX(); 
     extractY(); 
     extractZ(); 
    } 

    // getters, setters 
} 

然後,我用這些屬性來進一步分析句子得到另一個屬性,比如說,「XYZ」,在這之後我創建下面的類:

public class FinalSentence { 

    private AnalyzedSentence data; 

    private String XYZ; 

    public FinalSentence(String XYZ, AnalyzedSentence data) { 
     this.data = data; 
     this.XYZ = XYZ; 
    } 

    // getters, setters 
} 

的工作流程是這樣的:

public class SentenceAnalyzer { 
    /// ... 
    public FinalSentence analyze(String sentence) { 
     AnalyzedSentence as = new AnalyzedSentence(sentence); // every attribute of "as" can be calculated beforehand 
     String XYZ = SpecialClass.extractXYZ(sentence, as); // extract XYZ (needs a special class), based on as 
     return new FinalSentence(XYZ, as); 
    } 
} 

或者,因爲他們提取我可能只是一個類來保存所有信息,填充屬性,這可能RESU在一些空結果。它會是這樣的:

public class Sentence { 

    private String X; 
    private String Y; 
    private String Z;  
    private String XYZ; 

    public Sentence(String sentence) { 
     extractX(); 
     extractY(); 
     extractZ(); 
    } 

    public String getXYZ() { 
     // with this design, this method can be called, even if XYZ was not extracted yet. 
     // remember that XYZ cannot be extracted as X,Y,Z 
    } 

    public void setXYZ(...) {...} 

    // getters, setters 
} 

我的問題是:哪個設計是首選,爲什麼?如果還有更好的方法來完成我在這裏要做的事情,我也想聽聽它。

+0

你能給什麼這些類做一個具體的例子嗎?例如。會給出什麼樣的價值,他們會返回什麼? – chrisbunney 2009-07-19 07:45:29

+0

是的,我有一個管道系統,其中管道的第一個模塊是SentenceAnalyzer,其目標是返回可傳遞給管道其他組件的對象。這個對象是FinalSentence/Sentence。 在第一種情況下,屬性X,Y和Z表示可以從句子中獨立提取的數據,例如POS標籤(名詞,動詞,物品),人名等。然而,XYZ屬性不能獨立提取,並需要一個特殊的課程來完成。它代表了句子的「範疇」,如「體育」。 – 2009-07-19 11:16:51

+0

此外,用於提取XYZ的類需要我傳遞包含提取所需的所有內容的單個對象,因此需要將「AnalyzedSentence」傳遞給它。這個類的接口是:public class Extractor {String extract(E); }因此,我聲明瞭一個Extractor ,這樣我就可以在提取方法中獲得分析的句子數據。這就是爲什麼我認爲這些類應該被拆分的原因之一,因爲提取器不應該接收一個具有額外字段(XYZ)的類,這個字段與它所提取的內容相對應。 – 2009-07-19 11:38:30

回答

2

你需要考慮的是什麼,是,是否在您的問題域,AnalyzedSentence和FinalSentence是唯一的,足以被拆分或合併。

很明顯,他們正在與類似的數據合作,以實現這一目標密切合作。

對我來說,分析,並最終只是說了一句可能是,儘管這是根據我有限的,你正在處理的問題的知識,所以我想看看他們以某種方式結合起來。

編輯 基礎上進一步的信息,我想我會設計它是這樣的:

Sentence類封裝的原句,標籤和提取的類別(或不管它是你」重新提取,我假設它是基於你的描述的類別),以及設置,獲取和提取信息的操作。

Sentence類存儲TagList,其中包含所有標記,原始字符串和提取的類別。它還通過創建一個Extractor並在數據需要提取時傳遞TagList來封裝數據的提取(我將它放在構造函數中,但它可以放在一個方法中,它被調用的地方取決於何時需要提取數據)。

因此,通過這種方式,操縱原始語句所需的所有內容都在Sentence類中。當然,你可能知道的東西,我不認爲使得這種方法不適合,但這裏的一些代碼來說明我的意思:

public class Sentence { 

    private TagList tags  
    private String category; 
    private String sentence 

    public Sentence(String newSentence) { 
     sentence = newSentence; 
     Extractor<TagList> e = new Extractor<TagList>() 
     tags = e.extractTags(sentence); 
     category = new Category(tags); 
    } 

    public String getXYZ() { 

    } 

    public void setXYZ(...) {...} 

    private extractTags(String s){ ...} 

    // getters, setters 
} 


public class TagList{ 

    private List<String> tags; 

    .... 
    //rest of class definition 

} 
3

就我個人而言,我更喜歡第一個設計,一個有兩個類。分析和結果之間的區別對我很有吸引力。我喜歡將類視爲責任集合而不是數據集合,並且使用兩個不同的類使責任更明確。

0

我會去的單一類,因爲我會像對待提取XYZ與兩個步驟單個邏輯操作。

在構造函數中可以提取X,Y,Z,然後使用特殊類來獲得XYZ並返回最後一句。

0

爲什麼不只是一個方法返回基於單個字符串參數的分析數據?

String analyze(String input) {...} 

減少混亂,沒有副作用(一切都在棧上完成),更少的機會誤解API和做一些奇怪的事情。

1

我所有的製作相對較小類,我在掙扎與超過8000線的怪物類一起工作!
現在,FinalSentence類似乎有點太小了,就像一個空殼,一個AnalyzedSentence的簡單外觀,它的用處似乎並不明顯。

1

對於您的問題的回答取決於您希望將來如何修改這些課程,因爲程序的要求會擴大或改變。

一個很好的指引搞清楚何時分裂/加入一類,是單一職責原則「應該不會超過一個原因,一類改變。」

另外,開閉原則有助於決定如何組織類的話,你可以將它們與新課程相結合,而不是通過修改現有的類修改現有類的行爲:「軟件實體(類,模塊,功能等)應該打開進行擴展,但關閉進行修改。「

http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod