# Group

## 架構

Packhouse所有的結構與方法都必須封裝在Group內，結構大概如下：

![](https://firebasestorage.googleapis.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LwD6MjHg3yMxWgKGDEI%2Fuploads%2FIrF1ZNXZLiicZuOrzoYW%2Ffile.png?alt=media)

## Property

[Mold](/the-instance/group/mold.md)： 參數型別，可視為Interface或Type的功能。

[Tools](/the-instance/group/tool.md)：方法(Function)的最小單元。

[Lines](/the-instance/group/line.md)：柯里化(Curry)的結構宣告。

```typescript
let group = {
    molds: 'object',
    tools: 'object',
    lines: 'object',
    mergers: 'object',
    install: 'function'
}
```

### Install

**Install**是初始化行為，也是Core和Group交換資料的地方，於初次引用時執行，以AWS S3為例：

```typescript
// s3.js
const group = {
    install: (group, options, packhouse) => {
        const AWS = require('aws-sdk')
        group.service = new AWS.S3({
            apiVersion: options.apiVersion
        })
    }
}

module.exports = group
```

#### Add Group

我們可以藉由`addGroup`方法加入Group，並傳遞Options，但我們不推薦這麼做，請參閱正規化方法[Main](/the-instance/main.md)。

```typescript
packhouse.addGroup('s3', () => {
    return {
        data: require('./s3'),
        options: {
            apiVersion: '2006-03-01'        
        }
    }
})
```

### Mergers

針對跨Group的設計的，當GroupA要使用GroupB的方法時不能直接使用對方，必須藉由merger與[Includ](broken://pages/-LwGVvGBa1zjgFvdW8LZ)的引用才行，此目的能協助綁定上下文以便建立[追蹤](/the-instance/event.md)行為。

```typescript
const group = {
    tools: {
        sum: {
            handler(self, v1, v2) {
                self.success(v1 + v2)
            }
        }
    }
}

const group2 = {
    mergers: {
        mySum: 'sum'
    },
    tools: {
        double: {
            install({ include }) {
                include('sum').tool('mySum/sum')
            },
            handler(self, value) {
                self.tool('sum')
                    .noGood(self.error)
                    .action(value, value, self.success)
            }
        }
    }
}

packhouse.addGroup('sum', () => {
    return {
        data: group
    }
})

packhouse.addGroup('double', () => {
    return {
        data: group2
    }
})

packhouse.tool('double/double').action(10, (error, result) => {
    console.log(result) // 20
})
```

## TypeScript

如果你使用TypeScript，可以使用我們提供的Declaration File：

```typescript
import { Group } from 'packhouse/types'

const group: Group = {}
```

## Lazy First

盡可能不要在外部宣告`require`，可以確保引入的效能、文件的生產與單元測試時Mock行為最佳化。

```typescript
// 這是個糟糕的例子 😢
const AWS = require('aws-sdk')
const group = {
    install: (group, options) => {
        group.service = new AWS.S3({
            apiVersion: options.apiVersion
        })
    }
}

module.exports = group
```

```typescript
// 這是個優良案例 🤣
const group = {
    install: (group, options) => {
        const AWS = require('aws-sdk')
        group.service = new AWS.S3({
            apiVersion: options.apiVersion
        })
    }
}

module.exports = group
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://packhouse-doc.metalsheep.com/the-instance/group.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
