デザインパターンって何?
前提
プログラムごりごり書いたり設計したりしていると、必ずコーディング方法にある種の規則性があることに気付いている人。または、プロジェクトに適した設計を行いたいと考えている人。カウボーイコーディングでありがちな、チームによるコーディングであっても、成果物の中身に法則性がないプロジェクトメンバーに所属している人向け。
「そこの処理、シングルで作っておいて」と先輩に言われて、何のこと?と内心首をひねったことがある人向け。
※ ↑ 実際に言われた言葉。何のこと?ってなってデザインパターンを知った。。
■デザインパターンとは?
一言で言ってしまうと、コーディングをする際の「テンプレート」のこと。どんな機能でも、ある程度の法則性は必ずある。その中でも、代表的なテンプレートに名前を付けて、デザインパターンという「パターン」分けを行った。上記に出ている「シングル」もデザインパターンの一つ。シングルトン、というのが正確な名称だ。
Webばかりやっていると、めったに聞かないシングルトンという言葉だが、iphoneのゲームアプリを作っていたときは死ぬほど聞かされた言葉だった。プログラムの文中に、getInstanceという単語が出てきたら、「ああ、シングルトンなのね」と気づける人は以下を読む必要はないと思う。
例えば、ボタンの処理があったとする。このOnClick的なものは、当然ユーザーの気分次第で発生するイベントになる。せっかちな人は、当たり前のようにボタン連打するだろう。イベントハンドラーは、その入力をマルチで受け取り、OnClickが並列で流れることになる。
仮にボタンを連打したらシステムエラーを起こすアプリがリリースされたとする。おそらく、リリース後はクレームの嵐。進行不能系のバグだったら、真正面から吹き荒れる逆風を受け止めなければならない。
「ボタンの連打やめてもらえます?」
なんて、いえるはずがない。シングルで作れよ、って年配のエンジニアは思っているはずだからだ。
こんなケースに陥らないためにも、デザインパターンは軽くでいいので、学んでおくに越したことはないと思う。振る舞いに唯一性を持たせるのがgetInstanceという定番のメソッドであり、シングルトンというデザインなのだ。このパターンを知っておけば、事前に「クリック後の処理」は「一つだけ」動く機能として成立させるためのテンプレートを採用すればいいだけ、という結論に早い段階で行きつける。このメリットはとてつもなく大きい。
■どんなパターンがあるの?
全23パターンある。「オブジェクト指向における再利用のためのデザインパターン」という書籍によってカタログ化された。新人のエンジニアが読んでもチンプンカンプンだと思うので、業界の10年戦士にはぜひ概要だけでも知っていてもらいたい。もちろん、理解可能であれば早いに越したことはないが。
おそらく、デザインパターンなんて言葉は知らなくても、自分の書いたコードが、いずれかのパターンに属していることに気付くはずだ。この一連のパターン化をプロジェクト内、チーム内である程度共有できていれば、設計者とコーダーの間にあるギャップを埋めるための一助になるだろうし、「ああしたいのね」「こうしたほうがいいのね」に気付ける幅が広がる。ペアプロ(※1)できるような贅沢な現場にいる人は、コミュニケーションも格段に良くなるはずだ。
※1 ペアプログラミングの略。二人で一つのコードを書いていく開発手法のこと。とても贅沢だが、保守性が高いのでぶっちゃけうらやましすぎる環境。新人とペアプロやっている会社もあった。もちろん、超大手のインフラ系システム。
■代表的なもの
Web系だと、イテレーターかファクトリーあたりだろうか?C#でインターフェイスの設計からごりごり書いているような統制の取れたプロジェクトであれば、テンプレートになるのかもしれないが。
イテレーターは、DBの設計上、明細テーブルがある場合は避けては通れない。明細がないプロジェクトというのがどんなものなのか、ぱっと思いつかないのでイテレータを紹介する。
サンプルコードは以下。
Public Class OrderDetail
'受注明細に必要なフィールドを定義する
Private _orderId As Long
Private _orderDetailId As Long
Sub New(orderId As Long, orderDetailId As Long)
_orderId = orderId
_orderDetailId = orderDetailId
End Sub
'フィールドのアクセサー
Public Function GetOrderId() As Long
Return _orderId
End Function
Public Function GetOrderDetailId() As Long
Return _orderDetailId
End Function
End Class
Public Class OrderDetailList
Protected _orderDetail As List(Of OrderDetail)
Sub New()
End Sub
'それっぽいメソッドを軽く列記
Public Sub Add(orderdetail As OrderDetail)
_orderDetail.Add(orderdetail)
End Sub
Public Function Count() As Long
Return _orderDetail.Count
End Function
Public Function GetOrderDetailAt(index As Long) As OrderDetail
Return _orderDetail(index)
End Function
End Class
まぁ、ごくごくありふれた普通のコードだ。
あとは、下記のようにしておけば受注用の骨子が出来上がる。
'受注のための基底クラス
Public MustInherit Class Order
Protected _orderDetailList As OrderDetailList
Public Overridable Sub CreateOrderDetailList()
End Sub
End Class
'食品用の受注クラス
Public Class FoodOrder
Inherits Order
Public Overloads Sub CreateOrderDetailList()
'処理
End Sub
End Class
たとえば、OrderDetailList.GetOrderDetailAt(0)とした場合、明細の先頭行が取得できる。
※明細はCreate済みとする。
一般的に、明細は1行目から順に取得するはずだ。次は2行目。3行目….と続く。この場合、GetOrderDetailAtのインデックスをインクリメントしていくことも可能だが、派生した子供のクラスでインクリメントしていくのはどうにも手間がかかる。であれば、OrderDetailListにNext()と、次の行を取得するためのメソッドを追加してやれば、食品以外の受注クラスにとっても大助かりとなる。何のことはない、LinkedListのようなものを抽象化してオブジェクトの集まりを作っておくといいよ、という考え方だ。
※VisualStudioを使用しているのであれば、インターフェイスとしてIEnumerable突っ込んどけ、でもいいと思が、Iteratorの考え方には沿ってないんじゃないかな。。?どうだろう?foreach使えるから微妙。
まとめ
サンプルソースのように、ごくごく当たり前のように使用しているコードも、実は何かしらのデザインパターンに類することはよくあることだ。慣れてくると、全く意識しないでもデザインパターンに則ったスケルトンを作ってしまう。IT土方らしく、これを体に(頭ではない)叩き込んでしまえば、おのずと骨子のブレがなくなって、似通ったデザインでコーディングできるようになるはずだ。
面白味はないと思うかもしれないが、ユーザーは面白いソースを求めているわけではない。より堅牢な、保守性の高いシステムを求めているので、できる限り使えるプログラミングを心掛けたい。
せめて、ボタン連打くらいには耐えてもらいたいところだ。
より深く知りたい人は、下記で勉強してみるといいだろう。
デザインパターン
コメントを残す