デザインパターン

Interpreterパターン

概要 対応したい問題を「構文」として表現する。 そして、その構文を理解して、問題の解を出してくれるInterpreterをつくる。 そうすると、 動的に問題を受け取って解決したりできるようになる。 話の流れ こんな上下左右4つの移動先を選びながら、 ゴール…

Commandパターン

概要 1つ1つの処理をオブジェクトとして表現することで、 一連の処理を保存したり、あとで再現できたりして便利。 話の流れ こんな上下左右4つの移動先を選びながら、 ゴールを目指すゲームを作った。 data class Maze(val row: Int, val column: Int, val …

Proxyパターン

概要 あるクラスと同じinterfaceのProxyクラスを用意することで、 元のクラスを修正せず、同じinterfaceのまま、 機能の追加ができて便利 話の流れ 画像をダウンロードできる、こんなクラスを作った。 class ImageDownloader { fun downloadImage(url: Strin…

Flyweightパターン

概要 動的に変わるpropertyを持たないオブジェクトなら、 1度作ったオブジェクトをいろんな所で共有することで、 メモリとか節約できるかも。 話の流れ JavaのIntegerクラスでflyweightパターンが使われています。 Integerクラスとは、primitiveのintをオブ…

Stateパターン

概要 // 処理1は状態によって挙動が変わる if (状態A) { // 処理1A } else if (状態B) { // 処理1B } else if (状態C) { // 処理1C } // 処理2は状態によって挙動が変わる if (状態A) { // 処理2A } else if (状態B) { // 処理2B } else if (状態C) { // 処…

Mementoパターン

概要 あるオブジェクトの状態を保存して、 後で復元できるようにしたい。 そんな時、 オブジェクトの状態を表現するMementoクラスを作り、 Mementoを読み込むことで状態を復元できる機能を提供する。 そうすることで、 状態を保存/復元する側は、 オブジェク…

Observerパターン

概要 あるオブジェクトの状態更新を、 不特定多数のオブジェクトが自動で受け取れるようにしたい。 そんな時、 状態更新を受け取りたいオブジェクト(Observer)を、 状態更新を行うオブジェクト(Subject)に登録しておき、 Subjectは状態更新がおきる度に、 …

Mediatorパターン

概要 複数のオブジェクトが、 お互いの状態を監視して、自身の状態を切り替える。 こんなケースでは、 全オブジェクトの監視、管理を行うMediatorを1つ用意して、 各オブジェクトはMediatorに自身の状態を伝える。 こんな風にすると、各オブジェクトが他のオ…

Facadeパターン

概要 apiを提供する側は、柔軟性確保のため「低レベルなapi」を提供しているが、 apiを使う側は、自分のやりたいことを実現できる「高レベルなapi」を求めている。 そんな時、両者のギャップを埋めるapiを用意することで、 apiの柔軟性は確保したまま、高レ…

Chain of Responsibilityパターン

概要 ある処理を担当できるオブジェクト(Handler)が複数あって、 処理を依頼する側(Client)が、 「どのオブジェクトが処理したのか興味なく、処理の結果さえ受け取れれば良い」 ような時、 Handler同士を移譲で結び付け、 処理を完了できるHandlerまで処理を…

Visitorパターン

概要 あるクラスのデータ構造はそのままに、 機能の追加を頻繁に行いたいなら、 データ構造と機能を切り離して実装することで、 元のクラスを修正することなく、 機能の追加/削除ができて便利かも。 話の流れ 指定のディレクトリ以下のファイル情報を取得し…

Decoratorパターン

概要 「ある機能(ベース機能)」と、「それを拡張する追加機能」の間に、こんな関係がある場合 ベース機能と追加機能のsignature(入出力の型)が同じ 追加機能はベース機能のoutputを加工してoutputを作る ベース機能と追加機能の間に共通のinterfaceを作…

Compositeパターン

概要 ツリー構造のデータを扱う時、 リーフノードと中間ノードを統一的に扱えるinterfaceを用意すると、 ノードの種類を意識せずツリーの操作ができて便利 話の流れ Androidアプリ開発におけるlayoutは、 View要素をTree構造で配置しながら組み立てていく。 …

Strategyパターン

概要 アルゴリズムを柔軟に切り替えたいなら、 アルゴリズムの振る舞いをinterfaceに切り出し、 移譲を使って、アルゴリズムを切り替えられるようにすると良いよ。 話の流れ オセロのゲームを作りたい ユーザがCPUのレベルを「易しい」「普通」「難しい」か…

Bridgeパターン

概要 1つのクラスにいろんな機能が追加されていたら、各機能を 「クラスの基本的な機能」 ex. Sortを行うクラスにおける、Sortメソッド 「場面によって実装を切り替えたい機能」 ex. Sortを行うクラスにおける、Sortアルゴリズム 「特定の場面で使うことを…

FactoryMethodパターン

概要 インスタンス作成手順が複雑で、使う側のコードから作成ロジックを隠したい また、インスタンスは複数種類あり、作成ロジックの大枠は同じだけど、細かい所は違う そんな時、 「作成ロジックの大枠」をFactoryクラスとして用意し、 インスタンスの種類…

Singletonパターン

概要 アプリ内でインスタンスが一つだけ作られるようにするための実装パターン。 話の流れ アプリ内で使うLoggerは、一度セットアップした後は同じインスタンスを使い回せる アプリ開始時に、Loggerをセットアップし、staticなフィールドに保持しておく Logg…

Prototypeパターン

概要 生成処理が複雑なインスタンスがたくさんあって、 かつ、そのインスタンスをいろんな場所で生成したい。 そんな時、 インスタンスをあらかじめ作って保存しておき、 使いたいときは、インスタンスをコピーして新しいインスタンスを作ることで、 複雑な…

Builderパターン

概要 インスタンス生成に必要な設定項目が多く、 コンストラクタで一度に設定するのが大変だったり、 設定項目を徐々に埋めていきたい。 そんな時、 設定項目を一時的に保持するBuilderクラスを用意。 Builderクラスに設定項目を入力していき、 完成したらBu…

AbstractFactoryパターン

概要 インスタンスを作る側(Factory)、作られる側(Item)それぞれの関係を、 interfaceとして定義しておくことで、 異なる種類のインスタンスを統一的なinterfaceで生成できて便利かも。 話の流れ アプリでBlackThemeとWhiteThemeを切り替えられるようにし…

Template Methodパターン

概要 BEFORE AFTER 複数ステップから構成される処理の内、 特定の処理だけ、場面毎にロジックを切り替えたい。 そんな時、 場面毎に異なるロジックはabstract methodにしておく(実装はsub classに任せる。後回し。) abstract methodを使って、複数ステップ…

Adapterパターン

概要 私の使いたい機能を提供してるapiを見つけたが使いづらかった。 そんな時、 「誰かのapiに機能追加しよう」ではなく、 「私のためのadapter(wrapper)クラスを作成しよう」 なんて方針はどうだろう。 話の流れ 私の開発するAndroid appに、「サーバから…

Iteratorパターン

概要 List(複数のものをひとまとめにしたオブジェクト)を走査しながら何か処理をする時、 Listの内部構造を気にせず処理を実行できるといいよね。(当たり前) 話の流れ 図書館の本の管理システムを作りました。 data class Book(val title: String, val publi…