---
# System prepended metadata

title: Chapter 26 主元件 The Main Component

---

# Chapter 26 主元件 The Main Component
![](https://i.imgur.com/UkCGDn6.png)

每個系統中，都會至少有一個元件是用來建立、協調、監督其他的元件。我們稱之為 Main。

## The Ultimate Detail
Main 元件就是最終的細節，也是最低層次的策略 (lowest-level policy)。
這是系統的初始入口點。除了作業系統，沒有東西依賴它。
它的任務是建立所有的工廠 (factories)、策略 (strategies)、和其他全域設施 (global facilities)，再將控制權交給系統高層抽象部分。

在 Main 元件中，依賴關係應由依賴注入框架 (Dependency Injection framework) 注入。一但他們被注入到 Main，Main 就能在不使用框架的情況下，如平常時那樣配置這些依賴關係。

可以把 Main 想像成所有髒元件當中最髒的元件。

以下是Hunt the Wumpus當中的 Main 元件。注意他如何載入所有我們不希望程式碼主體知道的字串。

```
static void Main(string[] args)
{
    HuntTheWumpus game;
    int hitpoints = 10;
    List<String> caverns = new List<string>();
    String[] environments = new string[] {    "bright",
    "humid",
    "dry",
    "creepy",
    "ugly",
    "foggy",
    "hot",
    "cold",
    "drafty",
    "dreadful"};


    String[] shapes = new string[] {" round",
    "scruare",
    "oval",
    "irregular",
    " long",
    "craggy",
    "rough",
    "tali",
    "narrow"};

    string[] cavernlypes = new string[] {"cavern",
    "room",
    "chamber",
    "catacomb",
    "crevasse",
    "cell",
    "tunnel",
    "passageway" ,
    "hall",
    "expanse"};

    String[] adornments = new String[] {
        "smelling of sulfur",
        "with engravings on the walls",
        "with a bumpy floor",
        "ม่it red with garbage",
        "spatte ered with guano",
        "with piles of wumpus droppings",
        "with bones scattered around",
        "with a a corpse on the floor",
        "that seems to vibrate",
        "that feels stuffy",
        "that fills you with dread"
    };

}
```

現有一個 main 函式如下。注意它是如何使用 HtwFactory 建立遊戲的。
它透過傳入這個類別的名稱，htw.game.HuntTheWupusFacade，因為那個類別甚至比 Main 更髒，這樣就能防止該類別的更改導致 Main 的重新編譯/部屬。

```

static void Main1(string[] args)
{
    game = HtwFactory.makeGame("htw.game.Hunt ThewumpusFacade",new Main());
    createMap();
    BufferedReader br =
    new BufferedReader(new InputStreamReader(System.in));
    game.makeRestCommand().execute();


    while (true) (
    system.out.printin(game e.getplayerCavern());

    system.out.Printin("Health: " + hitPoints + " arrows: " +
    game.getQuiver());

    HuntTheWumpus.Command c = game.makeRestCommand();

    system.out.printin(">");

    String command = br.readLine();

     if (command.equalsIgnoreCase("e"))
         c = game.makeMoveCommand(EAST);
    else if (command.egualsIgnoreCase("w"))
        c = game.makeMoveCommand(WEST);
    else if (command.ecualsIgnoreCase("n"))
        c = game.makeMoveCommand(NORTH);
    else if (command.ecualsIgnoreCase("s"))
        c = game.makeMoveCommand(SOUTH);
    else if (command.equalsIgnoreCase("r"))
        c = game.makeRestCommand();
    else if (command.equalsIgnoreCase("sw"))
         c = game.makeShootCommand(WEST);
    else if (command.equalsIgnoreCase("se"))
        c = game.makeShootCommand(EAST);
    else if (command.equalsIgnoreCase("sn"))
        c = game.makeShootCommand(NORTH);
    else if (command.equalsIgnoreCase("ss"))
        c = game.makeShootCommand(SOUTH);
    else if (command.equalsIgnoreCase("q"))
    return;
    c.execute();
}  
```
main 建立輸入流並包含遊戲的主迴圈，解譯簡單的輸入命令，並將處理延緩到其他更高層級的元件。

最後，請注意到 main 建立了地圖

```

static void createMap()
{
    int nCaverns = (int)(Math.random() * 30.0 + 10.0);
    while (nCaverns-- > 0)
        caverns.add(makeName());

    for (String cavern : caverns) {
    maybeConnectCavern(cavern, , NORTH);
    maybeConnectCavern(cavern, SOUTH);
    maybeConnectCavern(cavern, EAST);
    maybeConnectCavern(cavern, wEsT);
    }

    String playerCavern = anyCavern();

    game.setplayerCavern(playerCavern);
    game.setwumpusCavern(anyOther(playerCavern));
    game.addBatCavern(anyother(playerCavern));
    game.addBatCavern(anyOther(playerCavern));
    game.addBatCavern(anyother(playerCavern));
    game.addPitCavern(anyother(playerCavern));
    game.addPitCavern(anyother(playerCavern));
    game.addPitCavern(anyOther(playerCavern));
    game.setQuiver(5);


}

```

重點在於 Main 是位於整潔架構 (clean architecture) 最外圈的一個髒的低層級模組。
它將所有內容載入到高層級系統中，接著將控制權轉交給高層系統。

Conclusion
我們可以將 Main 當作是一種 plugin，一種用來設定初始條件 (initial condition) 與設置 (configurations)，並蒐集外部資源 (outside resources)，然後將控制權轉移到程式的高級策略。
由於它是一個 plugin，所以可能有許多的 Main元件(每個應用程式的設置都有一個，ex: Dev、Test、Production…)。

當你將 Main 看做一個躲在架構邊界之後的 plugin 元件時，設置問題 (problem of configuration) 就變得更容易解決了。
