デザインパターン
書籍『オブジェクト指向における再利用のためのデザインパターン』において、GoF (Gang of Four) と呼ばれる4人の共著者は、デザインパターンという用語を初めてソフトウェア開発に導入した。GoFは、エーリヒ・ガンマ、リチャード・ヘルム、ラルフ・ジョンソン、ジョン・ブリシディースの4人である。彼らは、その書籍の中で23種類のパターンを取り上げた。
以下に注意
とても古い:書籍の出版は1994年
C++とSmaltalkの例があるように、そういう時代のもの
プログラミング始めたての頃に見ても何言ってるのか分からなくてかなり苛立った覚えがあるmiyamonz.icon
どうにも、これをパターンとして紹介するのは不適切な部分が多いように思う。
実装のパターンというより、状況のパターンと捉えたほうが正しい
コードを書いてるとき、こういう課題があるよね、というパターン
振る舞い
Visitorパターンの日本語wikipediaは例として不適切だmiyamonz.icon
英語版見たらちゃんと適切な例が書かれてた
visitorパターンは、要するに
何らかの構造を持ったデータに対して、
走査する順序のみを実装し、
操作に対する何らかのアクションを外側に出すという行為
なので、すべてのaccept methodの実装がvisitorを叩くだけだったら、意味がない
state, strategy, template methodあたりはだいたい一緒
インターフェースの抽象度が異なるだけ
なので、構造だけ見て、これらを区別するのはできないのでは?
状態に基づいて振る舞いを変えてるか
切り替えてる内容が、戦略っぽいか
一連の作業とか、大まかなアルゴリズムっぽいか
やりたい命令の自由度が上がり、呼び出すのではなく注入したくなると多分Commandパターンぽくなる?
ここらへんは、どういう抽象として切るのか、というところが頑張りどころだが、全般としてこれは良いパターンと思う
フロントエンドでも効果的なところがあるmiyamonz.icon
mementoはわざわざ名前をつけるほどではない
interperterは、名前の通りインタプリタを想像すると良いのだが
visitorに近いが、visitorに対して具体的なメソッドを叩いてよい感じ
code:java
class TerminalExpression_Plus implements Expression {
public void interpret(Stack<Integer> s) { s.push( s.pop() + s.pop() ); }
}
visitorの場合は、自身の構造に基づいて(たとえば、2項ななにかのLeftとRightをvisitする)イメージがあるはず
対して、interpreterは、stackというものをinterpret時に渡して、push,pop等をすることを想定してる
なので、visitorとinterpreterは両方同時にやるようなこともありえるかもしれない
mediatorは本当にそれ以上の意味はない
仲介が適切であるかどうかは、何をどう仲介しているかに依存するので、meditorパターンそれ自体がイケてるかイケてないか、という判断はできない
ただ、イケてなくても、とりあえず仲介したほうが多少マシ、というときはあるかもしれない
というのも、AとBのやり取りが必要なとき、AとBを同時に扱うので、そのやり取りのコードをAにもBにもどっちに書いても不適切と思える時があるから
あと循環参照でコンパイルできない系の問題が起きるときとかにも必要性が上がる
ベストは、そのやりとりとはなんなのかを適切な抽象として記述することで、
それへの足がかりとしてmediator的なコードから始めることはあるかもしれん
iterator
これはvisitorパターンを、リスト構造に対して適応したものと言える
現代的な言語では、わざわざ自分でこれを書くことは無いかもだが、その抽象行為自体は良かったといえる
Chain of responsibility
これに近いことやったこと無いからなんか全然批評できない
まあ確かに便利なことはあるかもしれない…?
なにかの処理をfallbackさせるようなことを書きたいケースがあまりないからか
そういう副作用チックな処理をあんまりデフォルトであったり、フォールバックさせたりするのは、
内部の挙動を変えると、利用側の挙動も大きく変わってしまうので、こういうやり方が好ましくない、というのはあるか
observer
これはごく当たり前になったが、良い抽象であるね
iterator, observerは良い抽象であるが、現代では言語レベルでのサポートでほぼ呼吸のようにこういうことはするようになった
しかし、教育課程で、これを再発見するようなコードを教えると、「設計によってコードを分かりやすくする」ということの体験の場としてちょうどいいかもしれない
構造
adapter
普通のこと。インターフェースをあわせるために間に挟まる
bridge
なんだこれ
クラスと継承に毒された考えがあって、それに対する解毒薬っぽい
そもそもそんな変な継承をしなければ、そうはならん
ただ単に抽象をしよう、ということ
composite
これは再帰的構造を表現する際によくやるやつ
decorator
もっといいやり方ありそうだなあ
visitorパターンの一種とも見えなくはない
wrapしてなんかする
facade
単に呼び出しをまとめただけ
面倒な呼び出しを利用者に見せないようにする層
単方向なmeditatorとも見えなくはない
わざわざfacadeと呼ばないが、よくやってる話
Flyweight
単なるcache
proxy
間に挟まる系で、インターフェースの違いがないような感じ
「プロクシパターン」が優れてるのかどうかではなく、どういうふうにproxy内で工夫ができるのか、というところのほうが重要
生成
singleton
単一にしたいときに使う
本当に単一にしたいなら便利
ただ、そもそもそんな単一にしたいのって正しい設計ですか、という話がよくある
---
そもそも、生成、構造、振る舞いという分類も微妙なところがある
めちゃ悪いということでもないが