2013-01-18 60 views
1

我有「建設者」級和聲納給出了以下警告:爪哇 - 缺少靜態方法在非實例化的類

Missing Static Method In Non Instantiatable Class 
pmd : MissingStaticMethodInNonInstantiatableClass 
A class that has private constructors and does not have any static methods or fields cannot be used 

我將如何重構這個類,以滿足上述的檢查? 因爲我確實在使用那個類,所以我正在撓頭。

使用示例:

ViewBuilder vb = new ViewBuilder.Builder() 
    .modelPart(CONTENT_PAGE, contentPageDao.get(id)) 
    .modelPart("navigation_sections", navigationSectionDao.list()) 
    .modelPart("available_tags", tagDao.list()) 
    .modelPart("available_albums", albumDao.list()) 
    .section(CONTENT_PAGE) 
    .page("index") 
    .element("form") 
    .action("/admin/content_page/save/" + id + ".html") 
    .build(); 

類本身:

import java.util.HashMap; 
import java.util.Map; 


public final class ViewBuilder { 

    private static final String ADMIN_LAYOUT = "admin/layout"; 
    private String layout = ADMIN_LAYOUT; 
    private String section = ""; 

    private static Map<String, Object> viewParts = new HashMap<String, Object>(); 

    /** 
    * @return the layout 
    */ public String getLayout() { 
    return layout; 
    } 

    /** 
    * @param layout the layout to set 
    */ public void setLayout(String layout) { 
    this.layout = layout; 
    } 

    /** 
    * @return the section 
    */ public String getSection() { 
    return section; 
    } 

    /** 
    * @param section the section to set 
    */ public void setSection(String section) { 
    this.section = section; 
    } 

    public static class Builder{ 

    // required params 
    private String layout; 
    private String section; 

    // optional params 
    private Map<String, Object > viewParts = new HashMap<String, Object >(); 

    public Builder(){ 

     this.layout = ADMIN_LAYOUT; 
     viewParts.put("layout", ADMIN_LAYOUT); 

    } 
    public Builder(String layout){ 

     if(layout != null){ 
     this.layout = layout; 
     viewParts.put("layout", layout); 
     } else { 
     this.layout = ADMIN_LAYOUT; 
     viewParts.put("layout", ADMIN_LAYOUT); 
     } 

    }// constructor 
    public Builder modelPart(String val, Object o){ 
     this.viewParts.put(val, o); 
     return this; 
    } 

    public Builder action(String val){ 
     this.viewParts.put("action", val); 
     return this; 
    } 
    public Builder element(String val){ 
     this.viewParts.put("element", val); 
     return this; 
    } 
    public Builder section(String val){ 
     this.section = val; 
     this.viewParts.put("section", val); 
     return this; 
    } 
    public Builder page(String val){ 
     this.viewParts.put("page", val); 
     return this; 
    } 
    public Builder layout(String val){ 
     this.layout = val; 
     return this; 
    } 

    public ViewBuilder build(){ 
     return new ViewBuilder(this); 
    } 


    }// Builder 

    private ViewBuilder(Builder builder){ 
     this.section = builder.section; 
     this.layout = builder.layout; 

     viewParts = builder.viewParts; 
    } 

    /** 
    * Get the value of viewParts 
    * 
    * @return the value of viewParts 
    */ 
    public Map<String, Object> getViewParts() { return viewParts; } 

    /** 
    * Set the value of viewParts 
    * 
    * @param viewParts new value of viewParts 
    */ 
    public void setViewParts(Map<String, Object> viewParts) { this.viewParts = viewParts; } 
} 

回答

1

鑑於您的嵌套生成器類是publicstatic,我真的看不出有什麼好處在它被嵌套在所有。我會建議把它打入自己的頂級課程。當然,那不是爲什麼PMD抱怨。您的外部類ViewBuilder沒有公共構造函數,也沒有靜態方法。正如它現在所存在的,它是一個相當無用的'命名空間包裝',它圍繞着你的類。可以給它添加一個構造函數,或者完全擺脫它。

+0

+1。 「公開和靜態的,我真的看到它根本沒有什麼好處」 – kosa

+3

這正是你實現「構建器模式」的方式。如果你認爲它「沒什麼價值」,我建議你對建造者模式的重點進行一些研究。簡而言之,它能夠在保證狀態下可靠地創建對象。私有類用於確保只有在調用build()函數後調用外部類構造函數,並且還提供了一個鉤點以對傳入的變量進行驗證。現在,您可以執行完整性檢查,看看是否有「需要「的值通過或不通過。有關更多信息,請參閱bmg的回覆。 – Russ

2

需要更新SonarQube PMD規則,以考慮靜態嵌套構建器類中的訪問器。

有這個創造了一個PMD問題,但它看起來拋棄: http://sourceforge.net/p/pmd/bugs/955/

我與「重構」不同意擺脫這種聲納違反,建造者模式是衆所周知的,非常有用的創建複雜的對象時。 請參閱「Effective Java」第2章第2項。 http://www.informit.com/articles/article.aspx?p=1216151&seqNum=2

+0

謝天謝地,有人說過建造者模式的價值。問題是*不是*這個人的代碼。這就是聲納不夠「聰明」,不足以理解由內部類「build()」調用的私有構造函數,因此Sonar應該認識到該函數是公開的並且不再抱怨。 +布朗尼要點參考Josh Bloch的書。任何人認爲這個代碼沒有提供任何價值,因爲他們認爲這些代碼是自己選擇Effective Java並給它閱讀的。 – Russ