javaでのVisitorパターン

Visitorパターンは、Compositeパターンを派生させたパターンであり、入れ物・中身の構造に対して複数の処理を記述する必要がある時に適用します。
Entryクラスとは別にVisitorクラスを作成し、Visitorクラスの方に処理を記述することで、構造と処理を分けることができます。

【サンプルコード】

・Element.java

・Entry.java

・Book.java

・GameSoft.java

・Bag.java

・Visitor.java

・ConcreteNormalVisitor.java

・ConcreteNariVisitor.java

・EntryMain.java

【実行結果】


いかがでしたでしょうか。

今回紹介したデザインパターンは、Compositeパターンの派生のようなパターンです。
ファイルシステムを扱う時等に役に立つのではないかと思うので、Compositeパターンのついでに頭に入れておくと良いと思います。

Chain Of ResponsibilityパターンやMediatorパターン等、立ち振るまいに関するデザインパターンがまだまだあるので、これからも紹介していきたいと思います!

javaでのDecoratorパターン

Decoratorパターンは、その名の通りオブジェクトに次々とデコレート(飾りつけ)をし、機能を追加していくパターンです。
Compositeパターンと同じように再帰的なクラス構成とすることで、冗長性を排除します。

今回は、じゃんけんの手を作成するサンプルコードを作ってみました。
「グー」「チョキ」「パー」といった単純な手も作れますし、これらの手を作成するオブジェクトを何度も呼び出すことで「必殺グーチョキパー」のようなズルい手も作れる、というサンプルコードです。

【サンプルコード】

・Hands.java

・CreateEmptyHands.java

・DecorateHands.java

・DecorateRock.java

・DecorateScissors.java

・DecoratePaper.java

・HandsMain.java

【実行結果】


いかがでしたでしょうか?

Compositeパターンと似たような話ですが、Compositeパターンは構造を再帰的に表現するのに対し、今回のDecoratorパターンは機能を再帰的に表現します。
ディレクトリ構造を扱う等ではない場合、Decoratorパターンの方が出番は多いかもしれません。

紹介したいデザインパターンはあと5パターンぐらいあるので、皆さまもう少しお付き合いください。
では、また次回!

javaでのCompositeパターン

Compositeパターンは、入れ物のクラスと中身のクラスを1つの抽象クラスでまとめ、同一視できるようにするパターンです。
このパターンを取り入れることで、クラスを使う側から見て入れ物のクラスなのか中身のクラスなのかを意識する必要がなくなります。

ファイルシステムの例が多いですが、理解を深めるために今回はあえて別の例を出して説明します。
袋と本・ゲームソフトの例を出して説明します。
単に袋の中に本やゲームソフトを入れるだけでなく、袋が破れないように袋を二重にする(袋の中に袋を入れる)こともありますし、袋の中に本用の袋とゲームソフト用の袋を入れて分類することもあります。
このような場合、Compositeパターンを用いることで、袋でも本・ゲームソフトでも同じように処理することができるようになります。

【サンプルコード】

・Entry.java

・Book.java

・GameSoft.java

・Bag.java

・EntryMain.java

【実行結果】


いかがでしたでしょうか。

今回紹介したデザインパターンは、ファイルシステムを扱う時等に役に立つのではないかと思います。
このような再帰的なパターンを自力で思いつくのは難しいと思うので、デザインパターンから学んでおくのが良いと思います。

これからも、役に立つデザインパターンを紹介していこうと思います!

javaでのBridgeパターン

Bridgeパターンは、機能のクラス階層と実装(処理の中身)のクラス階層を橋渡しするパターンです。
機能のクラス階層と実装のクラス階層を分けることで、実装毎に機能を書かなくて良くなりますし、その逆に機能毎に実装を書かなくて良くなります。
結果として、重複した記述を減らすことができ、保守性を向上させることができます。

今回は、RPGのダメージ計算を模したサンプルコードを作成してみました。
機能のクラス階層ではダメージの与え方を定義し、実装のクラス階層では具体的なダメージ計算式を定義しています。
Bridgeパターンの適用により、ダメージの与え方毎にダメージ計算式を書かなくて良くなっている点、逆にダメージ計算式毎にダメージの与え方を書かなくて良くなっている点に注目です。

【サンプルコード】

・DamageCalc.java

・MultipleDamageCalc.java

・DamageCalcImpl.java

・NormalDamageCalcImpl.java

・IgnoreDefenceDamageCalcImpl.java

・DamageCalcMain.java

【実行結果】


いかがでしたでしょうか。

先日記事にさせていただいたBuilderパターンと似たような話ですが、こちらのパターンは、機能や処理の中身が少しずつ違う場合に冗長性を排除できるパターンです。
同じ記述をコピーすると保守性が低下しますので、同じ記述が続いてると思ったらこのパターンの適用を検討した方が良いと思います。

まだ紹介できていないデザインパターンがありますので、これからも記事にしていきたいと思います!

javaでのBuilderパターン

Builderパターンは、処理内容を定義するBuilderクラスと、処理順番を定義するDirectorクラスの2つに分けることで、柔軟に処理を変更できるようにするパターンです。
Builderクラスの定義により処理内容が変わっても都度処理内容を記述する必要が無くなり、Directorクラスの定義により処理順番が変わっても都度処理順番を記述する必要が無くなります。

今回は、RPGのダメージ計算を模したサンプルコードを作成してみました。
ゲームが変わると処理内容が変わるのですが、Builderクラスを定義することで処理内容が変更されても利用者側で処理内容を都度記述する必要が無くなります。
また、ダメージを与える手段によってはダメージが可変になったり固定になったりするのですが、Directorクラスを定義することで利用者側で都度ダメージを可変にしたり固定にしたりするための具体的な記述をする必要が無くなります。

【サンプルコード】

・DamageBuilder.java

・DamageDto.java

・DamageBuilderGameA.java

・DamageBuilderGameB.java

・DamageDirectorVariable.java

・DamageDirectorFixed.java

・DamageCalcMain.java

【実行結果】


いかがでしたでしょうか。

プログラムを作っていると、「処理の順番は同じなのに処理の中身が少しずつ違う…」といったことや「処理の中身は同じなのに処理の順番が少しずつ違う…」といったことがあると思います。私も、そのようなケースでは、共通関数は作りつつも同じ記述を何か所にもコピーせざるを得なくなり、かなり冗長なコードを作ってしまっていました。
Builderパターンは、そのようなケースで効果を発揮します。同じ記述を何か所にもコピーすると保守する時に(テストも含めて)大変なので、中身や順番が少しずつ違うなと思ったら適用することをお勧めします。

次回も、開発の役に立つ情報を発信していきたいと思います!