

這是 AWS CDK v2 開發人員指南。較舊的 CDK v1 已於 2022 年 6 月 1 日進入維護，並於 2023 年 6 月 1 日結束支援。

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# Aspects 和 AWS CDK
<a name="aspects"></a>

Aspects 是將 操作套用至指定範圍內所有建構體的一種方式。該方面可以修改建構，例如透過新增標籤。或者，它可以驗證有關建構的狀態，例如確保所有儲存貯體都已加密。

若要將 面向套用至相同範圍內的建構和所有建構，` [Aspects](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Aspects.html#static-ofscope).of(<SCOPE>).add()`請使用新面向呼叫 ，如下列範例所示。

**Example**  

```
Aspects.of(myConstruct).add(new SomeAspect(...));
```

```
Aspects.of(myConstruct).add(new SomeAspect(...));
```

```
Aspects.of(my_construct).add(SomeAspect(...))
```

```
Aspects.of(myConstruct).add(new SomeAspect(...));
```

```
Aspects.Of(myConstruct).add(new SomeAspect(...));
```

```
awscdk.Aspects_Of(stack).Add(awscdk.NewTag(...))
```

 AWS CDK 使用層面來[標記資源](tagging.md)，但架構也可以用於其他用途。例如，您可以使用它來驗證或變更高階建構模組為您定義的 AWS CloudFormation 資源。

## Aspects 與 Mixins
<a name="aspects-vs-mixins"></a>

Aspects 和 [Mixins](mixins.md) 都修改了建構，但它們的套用時間和方式有所不同：


| 功能 | 面向 | 混合 | 
| --- | --- | --- | 
|   **套用時**   |  在合成期間，所有其他程式碼執行之後。  |  `.with()` 呼叫 時立即執行。  | 
|   **Scope (範圍)**   |  指定範圍內的所有建構，包括稍後新增的建構。  |  只有您明確套用的建構。  | 
|   **Style (樣式)**   |  宣告 – 您設定規則，且 CDK 會套用規則。  |  必要 - 您可以選擇要套用的內容和位置。  | 
|   **最適合**   |  驗證、合規、標記、廣泛的政策。  |  將特定功能新增至個別資源。  | 

當您想要在整個應用程式中強制執行規則，或驗證建構符合特定條件時，請使用 Aspects。當您想要將特定功能新增至特定建構時，請使用 混合。

Aspects 和 Mixins 可以一起使用。例如，您可以使用 Mixins 來設定個別資源和 Aspects，以驗證堆疊中的所有資源是否符合組織的安全需求。

## 層面詳細資訊
<a name="aspects-detail"></a>

Aspects 採用[訪客模式](https://en.wikipedia.org/wiki/Visitor_pattern)。一個方面是實作下列界面的類別。

**Example**  

```
interface IAspect {
   visit(node: IConstruct): void;}
```
JavaScript 沒有介面做為語言功能。因此，一個方面只是類別的執行個體，其具有接受要操作節點`visit`的方法。
Python 沒有介面做為語言功能。因此，一個方面只是類別的執行個體，其具有接受要操作節點`visit`的方法。

```
public interface IAspect {
    public void visit(Construct node);
}
```

```
public interface IAspect
{
    void Visit(IConstruct node);
}
```

```
type IAspect interface {
  Visit(node constructs.IConstruct)
}
```

當您呼叫 時`Aspects.of(<SCOPE>).add(…​)`， 建構會將 面向新增至 面向的內部清單。您可以使用 取得清單`Aspects.of(<SCOPE>)`。

在[準備階段](deploy.md#deploy-how-synth-app)， AWS CDK 會以由上而下順序呼叫建構模組及其每個子系的 物件`visit`方法。

該`visit`方法可免費變更建構中的任何內容。在強類型語言中，先將收到的建構轉換為更具體的類型，再存取建構特定的屬性或方法。

視觀表不會跨`Stage`建構邊界傳播，因為在定義之後`Stages`是獨立且不變的。如果您希望建構體瀏覽 `Stage` 內的建構體，請在建構體本身上套用層面 （或更低）`Stage`。

## 範例
<a name="aspects-example"></a>

下列範例會驗證堆疊中建立的所有儲存貯體是否已啟用版本控制。方面會將錯誤註釋新增至驗證失敗的建構。這會導致`synth`操作失敗，並防止部署產生的雲端組件。

**Example**  

```
class BucketVersioningChecker implements IAspect {
  public visit(node: IConstruct): void {
    // See that we're dealing with a CfnBucket
    if (node instanceof s3.CfnBucket) {

      // Check for versioning property, exclude the case where the property
      // can be a token (IResolvable).
      if (!node.versioningConfiguration
        || (!Tokenization.isResolvable(node.versioningConfiguration)
            && node.versioningConfiguration.status !== 'Enabled')) {
        Annotations.of(node).addError('Bucket versioning is not enabled');
      }
    }
  }
}

// Later, apply to the stack
Aspects.of(stack).add(new BucketVersioningChecker());
```

```
class BucketVersioningChecker {
   visit(node) {
    // See that we're dealing with a CfnBucket
    if ( node instanceof s3.CfnBucket) {

      // Check for versioning property, exclude the case where the property
      // can be a token (IResolvable).
      if (!node.versioningConfiguration
        || !Tokenization.isResolvable(node.versioningConfiguration)
            && node.versioningConfiguration.status !== 'Enabled')) {
        Annotations.of(node).addError('Bucket versioning is not enabled');
      }
    }
  }
}

// Later, apply to the stack
Aspects.of(stack).add(new BucketVersioningChecker());
```

```
@jsii.implements(cdk.IAspect)
class BucketVersioningChecker:

  def visit(self, node):
    # See that we're dealing with a CfnBucket
    if isinstance(node, s3.CfnBucket):

      # Check for versioning property, exclude the case where the property
      # can be a token (IResolvable).
      if (not node.versioning_configuration or
              not Tokenization.is_resolvable(node.versioning_configuration)
                  and node.versioning_configuration.status != "Enabled"):
          Annotations.of(node).add_error('Bucket versioning is not enabled')

# Later, apply to the stack
Aspects.of(stack).add(BucketVersioningChecker())
```

```
public class BucketVersioningChecker implements IAspect
{
    @Override
    public void visit(Construct node)
    {
        // See that we're dealing with a CfnBucket
        if (node instanceof CfnBucket)
        {
            CfnBucket bucket = (CfnBucket)node;
            Object versioningConfiguration = bucket.getVersioningConfiguration();
            if (versioningConfiguration == null ||
                    !Tokenization.isResolvable(versioningConfiguration.toString()) &&
                    !versioningConfiguration.toString().contains("Enabled"))
                Annotations.of(bucket.getNode()).addError("Bucket versioning is not enabled");
        }
    }
}

// Later, apply to the stack
Aspects.of(stack).add(new BucketVersioningChecker());
```

```
class BucketVersioningChecker : Amazon.Jsii.Runtime.Deputy.DeputyBase, IAspect
{
    public void Visit(IConstruct node)
    {
        // See that we're dealing with a CfnBucket
        if (node is CfnBucket)
        {
            var bucket = (CfnBucket)node;
            if (bucket.VersioningConfiguration is null ||
                    !Tokenization.IsResolvable(bucket.VersioningConfiguration) &&
                    !bucket.VersioningConfiguration.ToString().Contains("Enabled"))
                Annotations.Of(bucket.Node).AddError("Bucket versioning is not enabled");
        }
    }
}

// Later, apply to the stack
Aspects.Of(stack).add(new BucketVersioningChecker());
```