2012-05-05 74 views
4

鏈讓我們考慮這樣的對象鏈:最好的方式來傳遞的Java基準下的物體

Earth->Continent->Country->City->name 

我們還要考慮Earth.classpublic static void main(String[] args)

當應用程序使用命令行執行選項例如Barcelona,在不引入中間參數的情況下,將其傳遞給City對象的最佳方法是什麼?

對象在程序執行過程中的不同階段創建。

我們應該讓name變量靜態還是使用IoC,比如Spring或Google Guice? 還有其他選擇嗎?

歡迎任何想法。

回答

2
  • 我喜歡IOC最適合這項任務。讓國際奧委會在構建城市時傳遞依賴。
  • 可選:使用靜態服務註冊表,可以查詢該靜態服務註冊表的值。紐約市可以從服務註冊處獲得它的名字。
  • 替代方法:在您的層次結構中實現複合模式,包括可能返回城市的函數(如查找)。然後你只需要查詢和設置earth.find(BarcelonaID).setName(args[0]);

如何在PicoContainer的一個IoC的解決方案看起來像一個例子:

PicoContainer container = new DefaultPicoContainer(); 
container.addComponent(Earth.class); 
container.addComponent(Continent.class); 
container.addComponent(Country.class); 
container.addComponent(City.class, new ConstantParameter(cityName)); 

City barcelona = container.getComponent(City.class); 
+0

謝謝,克里斯托弗。IoC看起來不錯,但最初需要基礎設施才能發揮作用,談到Spring和Guice。我不知道這樣的設置是否合理,只是爲了向正確的地方提供幾個命令行參數:) –

+0

@IvanBalashov基礎設施很少。看例子。 –

2

您可以從自上而下的構建數據結構 - 大陸構造城市或從下往上 - main構建城市並將其傳遞給國家或使用某種組合。 DI有利於後者。

public static void main(String... argv) { 
    // Bottom up. 
    City city = new City(/* args relevant to city */); 
    Country country = new Country(city, /* args relevant to country */); 
    Continent continent = new Continent(country, /* args relevant to continent */); 
    Planet planet = new Planet(continent, /* args relevant to planet */); 
} 

class City { 
    City(/* few parameters */) { /* little work */ } 
} 
class Country { 
    Country(/* few parameters */) { /* little work */ } 
} 
... 
class Planet { 
    Planet(/* few parameters */) { /* little work */ } 
} 

可以比自上而下更清潔:

public static void main(String... argv) { 
    // Top down. 
    Planet earth = new Planet(
    /* all the parameters needed by Earth and its dependencies. */); 
} 
class Planet { 
    Planet(/* many parameters */) { /* lots of work */ } 
} 
... 

的DI民間認爲,自下而上的結構導致更多的維護和測試代碼,但你並不需要一個DI框架來使用它。

+0

謝謝,邁克。幸運的是,對象需要在地球課外建造。否則,這將不會有趣:) –

+0

@IvanBalashov,我主張在外面建造它們。 –

+0

@MikeSamuel我不認爲在他們應該在的地方創建對象是個好主意。一個國家需要知道哪些城市屬於它,如果你把這些知識放在'Country'類之外,那麼你違反了對象封裝 – GETah

1

在我看來,這是您可以想象的Visitor模式的最佳用例。 基本上,應該有一個類Parameters,應該包含所有參數。每個需要一組參數的對象都可以用該類Parameters訪問。然後,該對象可以將參數傳遞給其子代,以瞭解要使用哪些參數以及如何使用。 在你的情況,這是可以做到這樣:

public interface IParameterized{ 
    public void processParameters(Parameters param); 
} 

public class Earth implements IParameterized{ 
    public Earth(){ 
     // Create all countries here and store them in a list or hashmap 
    } 
    public void processParameters(Parameters param){ 
     // find the country you want and pass the parameters to it 
     country.processParameters(param); 
    } 
} 

public class Country implements IParameterized{ 
    public Country(){ 
     // Create all cities that belong to this country 
    } 
    public void processParameters(Parameters param){ 
     // find the city you want and pass the parameters to it 
     city.processParameters(param); 
    } 
} 

public class City implements IParameterized{ 
    public City(){ 
     // Create city... 
    } 
    public void processParameters(Parameters param){ 
     // Do something with the parameter 
    } 
} 

編輯 要連接的點,這可以通過以下方式來使用:

public static void main(String... argv) { 
    Parameters params = new Parameters(); 
    // Populate params from the command line parameters 
    Earth earth = new Earth(); 

    // Earth takes the responsibilty of processing the parameters 
    // It will delegate the processing to the underlying objects in a chain 
    earth.processParameters(params); 
} 

作爲一個側面說明,你也可以看看Chain Of Responsibility的設計模式

+0

謝謝,GETAH。但是我們仍然需要在某處放置IParameterized對象,並將它傳遞給其他對象,這意味着所有引用都應該在一個地方可用。我不知道我們是否可以找到真正解耦的東西:) –

+0

@IvanBalashov參數將在main中創建並傳遞到鏈中,請參閱我的編輯 – GETah

+0

是的,但必須具有「地球」,「城市」和其餘部分在main()中可用的對象,在我的例子中創建的其他對象... –