2012-09-28 10 views
0

我想知道這種設計是正確的,錯誤的還是兩者兼而有之。
我有一個應用程序與幾個組件(對象),他們每個人都有一個配置(標誌,功能等) 在任何時候,我想檢索對象的配置。
要這樣,我這樣做:動態對象vs單一特定動作

class ConfigRetriever { 
    public String getConfigString() { 
     String configString = ""; 
     configString += "component 1 flag : "+component1.getFlag()+"\n"; 
     configString += "component 2 flag : "+component2.getFlag()+"\n"; 
     // ... 
     return(configString); 
    } 
} 

別的地方,當需要配置:

class SomeClass { 
    public void someMethod() { 
     ConfigRetriever configRetriever = new ConfigRetriever(); 
     String configString = configRetriever.getConfigString(); 
      // Do some stuff with configString... 
    } 
} 

我在對象編程很新,它仍然感覺怪怪的,以創建一個對象(ConfigRetriever)只是一個特定的動作(即使對象能夠做其他的事情)。
我也不過約Singleton模式,有些事情是這樣的:

String configString = ConfigRetriever.getInstance().getConfigString(); 

這是一個整潔的線,但因爲對象停留在內存中,直到應用程序結束後,我真的不知道是什麼正確和錯誤。

我的設計可能會更好嗎?怎麼樣 ?爲什麼?

UPDATE
謝謝你的回答。我想我的問題有點混亂,我錯過了我所要求的觀點。
整個配置和組件故事在這裏作爲我正在處理的這種情況的一個例子。這是快速和骯髒的代碼,我應該警告你。真正的問題是:「創建一個對象只是一次(或有時)訪問它的一個方法是好事嗎?」 那麼,閱讀你的答案,並再次思考它,似乎正確的答案是「這取決於你的目標,課程,責任等等......」
我想將信息存儲在我的目標中嗎?不能是靜態方法。
使用永久內存的單身人士是一個問題嗎?大部分時間都是這樣,因爲我認爲你必須有一個很好的理由來維護一個具有全局狀態的對象。所以,大部分時間:沒有單身。

最後,創建一個類用於實例化某個對象是否有問題?不是這樣做的! :-)

+0

我在你的問題中沒有看到任何建議單身人士,除了你建議它。似乎缺少一些東西,component1和component2從哪裏來? –

回答

1

我沒有看到任何需要在這裏有一個單身人士。

爲單個操作創建對象並不奇怪,但如果頻繁調用該方法可能效率不高。我認爲你能做的最好是使用dependency injection

class SomeClass { 
    private final ConfigRetriever retriever; 
    public SomeClass(ConfigRetriever retriever) { 
     this.retriever = retriever; 
    } 
    public void someMethod() { 
     // use this.retriever here 
    } 
} 
0

的幾個問題 -
A.原密碼已返回名爲getConfigString無效的方法 - 這應該是固定的。
B.此外,ConfigRetriever類中提供的組件的位置並不清楚。
C.你有一些選擇,你可以選擇:

1.有無ConfigProvider類層次結構,這將符合您的組件層次結構 - 如果你有一個名爲ComputerComponent類,你將有一個匹配ComptuerConfigProider

您可以考慮在Component類中使用ConfigProider的getConfigProvider方法。

public abstract class Component { 
    public abstract ConfigProvider getConfigProvider()' 
} 

然後一個具體的類可以用作看起來:類似於第一個

public class ComputerComponent extends Component { 
    public ConfigProvider getConfigProvider() { 
     return new ComputerConfigProvider(this); 
    } 
} 




2.溶液,但具有單個ConfigProvider類,與添加配置組件的方法在上面。
例如,假設ConfigurationProvider僅包含鍵和值的映射。
你在這種情況下,代碼可以作爲看:

public class ConfigProvider { 

    private Map<String,String> internalMap = new HashMap<String,String>(); 
    public String getConfigProvider() { 
     //Return a string representation of the internal map 
    } 

    public ConfigProvider addConfigElement(String key,String value) { 
     map.put(key,value); 
     return this; 
    } 
} 

public class ComputerComponent extends Component { 
    private int memory; 
    private String cpu; 
    public ConfigProvider getConfigProvider() { 
     ConfigProvider configProvider = new ConfigProvider(); 
     return configProvider.addConfigElement("memory",Integer.toString(memory)). 
     addConfigElement("cpu",cpu); 
    } } 




3.如果您仍然想使用singletone
- 因爲你的配置取決於組件狀態,具有配置提供商singletone是錯誤的,除非你把getConfigProvider是一個「無狀態」的方法 -

String getConfigString(Component component) 

但在這種情況下,你可以考慮不使用singletone但僅僅擁有一個靜態方法,並且代碼看起來像:

public class ConfigurationProvider { 
    public static String getConfigString(Component component) { 
    StringBuilder sb = new StringBuilder(); 
    //Append the component values to the string builder 
    return sb.toString(); 
    } 
} 
1

沒有人提到static方法呢。一個典型的Java模式是使用一個靜態方法,你可以在沒有該類的實例的情況下進行分類。喜歡的東西:

class ConfigRetriever { 
    public static String getConfigString() { 
     StringBuilder sb = new StringBuilder(); 
     sb.append("component 1 flag : ").append(component1.getFlag()).append('\n'); 
     sb.append("component 2 flag : ").append(component2.getFlag()).append('\n'); 
     // ... 
     return sb.toString(); 
    } 
} 

因此,這可以讓你做這樣的事情:

// call the static method on the class, not on an instance 
String configString = ConfigRetriever.getConfigString(); 

因爲你沒有一個實例,你不能存儲ConfigRetriever的內部狀態。我不確定component1component2對象來自哪裏。

注意我轉換了您getConfigString()方法使用StringBuilder()類,這是比實際使用多個StringBuilder類內部的+=方法更有效。