Open3

Goでデザインパターンをやってみる

かずかず

Decoratorパターン

サンプル実装: https://github.com/kazdevl/design-pattern-tutorial/tree/main/decorator

Decoratorパターンは、特定のインタフェースを持つインスタンスをラップしていくことで、既存の機能を修正することなく、手軽に新しい機能を追加できるようにするデザインパターン。
ログを出力するlogger・通知を飛ばすnotifierなどで活用されるイメージがある。

Write(value any) (err error)というインタフェースを持つloggerの場合、

  1. 標準出力するlogger
  2. 機密情報が含まれている場合に、マスクするlogger
  3. 入力値を圧縮するlogger
    など

Goでいうと、io.Readerとかio.Writer周りで使われてそう。

Decoratorパターンの構成要素

  • コンポーネント: 元となるインスタンスとラップするインスタンスの共通のインタフェースを定義したインターフェース or 抽象クラス。
  • 具象コンポーネント: 大本となる基本的な機能を持った、コンポーネントを実装 or 継承したクラス。
  • デコレーター: 具象デコレーターの基底となる抽象クラス。コンポーネントをフィールドに持つ。
  • 具象デコレーター: デコレーターを継承した、新しい機能を持つクラス。

具象デコレーターが、フィールドにコンポーネントを持つことで、具象デコレーターが具象デコレーターや具象コンポーネントを持つことができるようになる。

所感

  • Goで、このデザインパターンを採用する場合はJavaと違って、抽象クラス・継承が存在しないのでデコレーターに該当する部分は不要。
  • 既存機能を修正する必要がないので、新機能を追加しやすい and 既存を再テストする必要ないので動作確認も楽
  • Adapterパターンと少し似ていているが、Adaptorパターンはインターフェースのずれを埋める(既存機能を使って、異なるインタフェースに合わせる)ためのパターンであり、Decoratorパターンは同じインタフェースで機能追加するためのパターン。
  • 普段の開発で実際に活用できそうなケースとしては、その振る舞いを実現している機能が汎用的な使われかたをする and 機能の拡張性が求められるケース