2012年4月27日金曜日

Steve Jobs' Idea For an Ad-Supported OS

"It looks like Steve drew up an idea for an ad-supported OS. A patent was filed back in 2009 detailing how it was done. From the article: 'Rather than charge the normal upgrade price, which in those days was $99, he was thinking of shipping a second version of Mac OS 9 that would be given away for free — but would be supported instead by advertising. The theory was that this would pull in a ton of people who didn't normally upgrade because of the price, but Apple would still generate income through the advertising. And any time an owner of the free version wanted to get rid of the advertising, he or she could simply pay for the ad-free version. Steve's team had worked out the preliminary numbers the concept seemed financially sound.'"

2012年4月26日木曜日

VMware confirms source code leak, LulzSec-affiliated hacker claims credit

VMware has confirmed a leak of source code from the ESX hypervisor. The code was posted on Pastebin on April 8 by a hacker calling himself "Hardcore Charlie."

VMware confirmed the theft yesterday, and said there is a "possibility that more files may be posted in the future." The good news is that the code dates from 2003 to 2004. While VMware ESX is still heavily used, VMware is shifting customers to a newer hypervisor called ESXi, which has a smaller attack surface and is designed to be more secure.

"The fact that the source code may have been publicly shared does not necessarily mean that there is any increased risk to VMware customers," the company said. "VMware proactively shares its source code and interfaces with other industry participants to enable the broad virtualization ecosystem today. We take customer security seriously and have engaged internal and external resources, including our VMware Security Response Center, to thoroughly investigate. We will continue to provide updates to the VMware community if and when additional information is available."

The Kaspersky Lab ThreatPost blog somewhat over-dramatically called the incident the "IT equivalent of the Deepwater Horizon oil spill disaster."

This VMware source code reportedly was stolen from Chinese military contractor CEIEC, the China National Electronics Import-Export Corporation. VMware code wasn't the only target. Although the VMware connection wasn't verified until yesterday, the hacker Hardcore Charlie told Reuters earlier this month that he hacked into CEIEC seeking information on the US military campaign in Afghanistan, and also that he was a friend of Hector Monsegur, the LulzSec leader who was caught by the FBI and pleaded guilty to criminal hacking charges.

2012年4月25日水曜日

Google Drive公開

Googleが4月25日、オンラインストレージサービス「Google Drive」を公開した。

公開されたGoogle Driveでは、ユーザは5GBまでの無料利用が可能となっている。5GBを超えて利用する場合には有料になっており、料金は25GBで月額2.49ドル、100GBで月額4.99ドル、1TBで月額49.99ドル。有料での利用を選択した際には、Gmailの容量も25GBまで拡張されるという。

サービス開始にあわせて、PCおよびMac、Androidで利用できるアプリも公開された。iOS版のアプリも今後公開の予定で、プラットフォームに縛られないサービス利用が可能だ。また、Googleドキュメントとの統合機能もある。

Google DriveではWebベースのファイルビューアが用意されおり、発表によると30種類以上のファイル形式が閲覧可能とのこと。対応形式にはAdobe PhotoshopやIllustratorも含まれており、HD videoの再生にも対応している。PhotoshopやIllustratorファイルの編集はもちろんできないが、内容が見られるだけでも十分に役立つだろう。

また、ストレージに保存したデータの検索も強化されている。たとえばイメージファイルをアップロードすると、そのイメージに含まれるテキストがOCRで読み取られ、検索の際に利用できるようになる。新聞記事の切り抜き画像をその記事内に含まれる単語で検索するといった使い方が可能だ。

イメージそのものを認識する機能もあり、発表では「グランドキャニオンの写真をアップすると、グランドキャニオン(原文ではgrand canyon)とテキスト検索して探すことが可能」としている。

Yahoo!がNode.jsベースのフレームワーク「Mojito」を公開

 YUI 3とNode.jsをベースにしたMVCフレームワーク「Mojito」がBSDライセンスで公開されました。[GitHubからコードを入手できます]。

 Mojitoの特徴は、クライアントとサーバを同じ言語(JavaScript)で開発できるのは(Node.jsですし)当然ながら、クライアントとサーバのどちらも同じフレームワークを利用できるところにあります。 

 国際化への対応、ユニットテスト機能の統合、モバイルやデスクトップだけではなくTVを含む、デバイスに応じたUIの表示などの機能を持っており、ドキュメントやサンプルも充実しています。気になるフレームワークがまた一つ登場しました。

FirefoxもWebRTCの実装を進行中

 WebRTCとは、Webアプリによるカメラやマイクからのマルチメディアデータ取り込みや、ブラウザ間でのP2P通信を実現するための技術です。 

 かなり先進的な機能ですが、Mozillaによる取り組みも進んでいるとはっきりしたことにより、WebRTCの実装が広まるのは思った以上に早そうだという感触が得られました。他のブラウザでは、Google Chromeでは chrome://flags/で有効にすれば利用でき[OperaもWebRTCを部分的にサポートしたビルドを公開中]、Microsoftもラボでビルドを公開している状態です。

http://hacks.mozilla.org/2012/04/webrtc-efforts-underway-at-mozilla/

Adobe CS6/Creative Cloud

 アドビはCreative Cloudによって「クラウド統合」という新しい分野に大きく踏み出した。Creative Suiteとして提供され、長い期間をかけて洗練されてきたクリエイティブツールの数々は、その中核をなす存在である。Creative Cloudと同時にリリースされるCS6は、その特徴として以下のような項目が挙げられている。

  • ミッションクリティカルなツールすべてがバージョンアップ
  • 簡素化されたワークフローや64bit化製品の拡張、さらなる最適化、GPUの活用などによって、すべてのツールのパフォーマンスが大幅に向上
  • iPadや各種デバイスに対応した制作機能を強化
  • 印刷ならびにデジタルパブリッシング制作双方の効率性を強化
  • HTML5/CSSなど、最新のWeb標準サポートをさらに強化
  • 洗練されたモダンUIによりクリエイティビティを向上
 CS6は、Creative Cloudのメンバーとして利用するほか、従来通りの統合製品としてで購入することもできる。CS6では、「Master Collection」「Design Standard」「Production Premium」「Design & Web Premium」の4種類の統合製品が提供される。
 
 「Creative Cloudによって、洗練されたクリエイティブツールをすべて入手できる。CS6製品とTouch Appsを組み合わせて使うことで、どこでもデザイン・制作が可能になり、あらゆるメディアのデザインと開発が誰でも行える。また、Webやスマートフォン、タブレットへの配信も簡単にできる。コミュニティとつながることもでき、クラウドベースの同期サービスやストレージによって、共同制作やアイデアの共有が可能になる。さらに、追加コストを支払うことなく、最新の技術やバージョン、新製品をすぐに利用できる」

 ここにも挙げられているように、クラウドを利用することによって、PCやモバイル端末上の各種ツールを連携させ、出来上がった制作物をシームレスに配信までつなげることがCreative Cloudの強みといえる。

 これを活用すれば、例えばアイデアを思いついた瞬間にTouch Appsでプロトタイプ化し、それを基にデスクトップ上で加工して精度を高め、クラウドサービスを利用して配信するといったワークフローも実現できるという。

 CS6の登場は、Webコンテンツの制作者にも大きな影響を与えることになる。CS6に与えられたテーマには、HTML5CSSJavaScriptといったWeb標準技術のサポート強化が含まれている。それを象徴しているのが、Flash Professional CS6に追加されたHTML5サポート機能だ。Flash Pro CS6では、FLAファイルの出力だけでなく、HTML5用アセットの書き出し機能が提供される。

 この機能は、「Toolkit for CreateJS」という無償エクステンションとして提供され、別途ダウンロードして追加することで利用できるという。

 これによって、アニメーションイメージベクタ画像音声/音楽インタラクションといったコンテンツをHTML5向けに作成できる。つまり、Flash Proを使うデザイナや開発者は、これからは用途に応じてFlashとHTML5のどちらを対象とするのか自由に選択できるようになるということだ。

 アドビのデベロッパーマーケティングスペシャリストを務める轟啓介氏は、「HTML5の書き出しをサポートしたことで、Flash Pro CS6はFlashオーサリングツールからWeb用のクリエイティブツールに進化した」と語っている。

 なお、HTML5アセットの書き出しには、クリエイティブなHTML5コンテンツを作成するための「CreateJS」というフレームワークを利用しているそうだ。著名なFlashのエンジニアであるGrant Skinner氏がアドビの支援の下で開発しており、Flashの技法をできるだけ変えないで使えるという点が大きな特徴だという。

 またCreateJSにより、従来のDreamweaverだけではなく「Flash ProからPhoneGapを使って、スマートフォン向けアプリを作る」ワークフローも可能だという。

 Flash Proだけではなく、WebサイトやWebアプリケーション用のデザインツールであるDreamweaver CS6およびFireworks CS6でも、HTML5/CSS3のサポート機能が強化されている。

 例えば、Dreamweaver CS6ではマルチスクリーン対応のWebサイト制作をサポートするための機能として可変グリッドレイアウトや、GUIによるCSS3トランジションの設定機能、jQuery MobileテーマやFireworksで作ったテーマをスウォッチから指定する機能などが提供される。

 またFireworks CS6では、jQuery Mobileテーマの作成、作成したオブジェクトからCSSプロパティを自動で作成する機能や、CSSスプライトの自動生成といった機能が提供される。CSSスプライトとは、複数の画像部品を1枚の画像ファイルにまとめてCSSで表示範囲を指定する機能である。轟氏は「この機能でFireworksが手放せなくなった」と強調していた。

 Webコンテンツを制作するデザイナや開発者にとって、HTML5やCSS3、JavaScriptは必ず押さえておくべき必須技術になっている。しかしながら、HTML5自体の仕様はまだフィックスしておらず、ベンダプレフィックスなどの存在によってデザイナ・開発者に負担が掛かっているというのが現状だ。「この状況をツールの力で何とかできないか、というのがツールベンダとしてのアドビのアプローチ」だと轟氏はいう。CS6には、そのような同社の姿勢が強く現れている。

「Google Drive」正式発表 GmailやGoogle Docsとの連係や検索機能で差別化

 米Googleは4月25日(現地時間)、うわさされていたクラウドストレージ「Google Drive(日本では「Googleドライブ」)」を正式に発表した。

 全ユーザーが使えるようになるには数日かかるようだ。Googleドライブのページを開いて、右上の青いボタンが「使用する」になっていれば、利用できる。

 23日にアップデートが発表された米MicrosoftのSkyDriveと同様に各種プラットフォーム向けアプリも用意されている。Microsoftは対応していないAndroid版もあるが、Windows Phone版はなく、iOSアプリは現在準備中だ。

 先行するDropboxとSkyDriveとの差別化ポイントは、同社の検索技術を生かしたドライブ内検索機能と、Gmail、Google Docs、Google+との連係機能といえる。

 5Gバイトまでは無料で利用できる。「容量プラン」は月額制で25Gバイトから。同じアカウントで使っているPicasaと共有できる(Picasaの無料容量は1Gバイト)。また、容量プランを購入すると、Gmailの保存容量も自動的に追加されるという。なお、カウントされるのは同期またはアップロードしたファイルのみで、Google Docsのファイルはカウントされない。

容量プラン
保存容量 月額料金(ドル)
25GB 2.49
100GB 4.99
200GB 9.99
400GB 19.99
1TB 49.99
2TB 99.99
4TB 199.99
8TB 399.99
16TB 799.99
 また、同日からGmailの無料容量が従来の7.5Gバイトから10Gバイトに増量された。

 GoogleドライブはWebブラウザでdrive.google.comにアクセスすることで利用できるが、Mac、Windows、Android向けのアプリも用意されている。アプリをインストールすれば、Googleドライブをフォルダの1つのように扱え、ドラッグ&ドロップでファイルを保存したり、削除したりできる。

 米AppleのiPhoneおよびiPadで使えるiOSアプリは間もなく登場という。

 Android向けGoogle DocsのアプリはGoogleドライブの一部になり、「Googleドキュメント」というアプリはなくなった。

 Googleアカウントでログインすれば、対応プラットフォームのPCや端末からあらゆる種類のファイルをGoogleドライブに保存でき、自動的に同期される。アップロードできる1ファイルのサイズ上限は10Gバイト。

 PCや端末側に対応アプリがインストールされていなくても、動画、Adobe Illustrator、Photoshopなど、30種類以上のファイルをWebブラウザで表示できる。

 Google Docsの文書は、もちろん編集できる。Google Docsと連係しているので、Google Docsで可能な他のユーザーとの共同編集も可能だ。

 以下のように他のサービスと併用できる。

GoogleドライブのファイルをGmailのメールに挿入
Googleドライブに保存された写真や動画を直接Google+で共有
GoogleドライブのChrome拡張機能で、Web上のファイルを直接Googleドライブに保存
ドライブ内検索
OCRやGoogle Gogglesを使った高度な検索機能

 Googleドライブ上部の検索ボックスを使用して、ファイルやフォルダ、Googleドキュメントを検索できる。Google検索同様に検索演算子を利用でき、検索ボックスに付属するメニューで、ファイルの種類や公開設定などでファイルの絞り込みもできる。

 Google DocsのOCR変換機能により、スキャンした画像のテキストも検索対象になる。また、Google Gogglesの技術により、画像も検索できる。Google Gogglesが正しく画像を分析していれば、例えば「グランドキャニオン」で検索すると、グランドキャニオンの写真が検索結果として表示されるという。

 Chromeウェブストアから、Googleドライブで利用できるさまざまなサードパーティー製アプリをダウンロードして利用できる。

 例えば、Googleドライブのフォルダにあるドキュメントをファックス送信したり、Googleドライブでファックスを受信できるようにする「HelloFax」や、Googleドライブ上の動画をそのまま編集できる「WeVideo for Google Drive」などがある。

スマホアプリで本当に週末起業できるのか?

 「こんなアプリがあったらいいのにな…。もしナイなら、自分で作ってみようか。もしかしたらヒットするかも!ヒットしたら起業も夢じゃない!!」——。なんてことを、自分のスマートフォンをいじりながら夢想してみたことはないだろうか。何を隠そう私も何度か経験がある。

 スマホユーザーにそう思わせるのには理由がある。

 第一は、スマホアプリ制作のハードルが年々下がってきていること。iOSやAndroid向けの基本的な開発ツールキットは無料で公開されており、バリバリの3Dゲームを開発できるゲームエンジンですら、個人は無料で利用できる。プログラミングでちょっと腕に覚えがある人なら、簡単に始められる環境が整ってきているのだ。

 第二に、スマホアプリビジネスに関する情報がふんだんにそろってきたことだ。書店に並んでいる開発ノウハウ本、もしくは開発導入サイトなどで情報を仕入れていけば、スマホアプリを開発し、それを世に送り出すところまでの最低限の情報は簡単に入手できる。後は、自分のアイデアとトライする気持ちがそろえば、すぐにでもスマホビジネスを進められるというわけだ。

 ただ、現実はそう甘くない。オランダの調査会社ディスティモ(Distimo)によると、2011年末の段階でiPhoneとiPadアプリを足すと約50万超、Androidアプリで約35万超のアプリがマーケットに存在しているという。特にAndroidアプリは前年比で2.3倍程度も増えており、この増加傾向はしばらく続きそうだ。せっかく新しいアプリを作っても、50万ものアプリ群の中に紛れてしまい、利用者が見つけてくれるのは容易なことではない。

 スマホ黎明期は、素人やプロとして活躍する個人がアイデア勝負で作ったアプリが多く、スマッシュヒットもこうした中から生まれていた。そのうち、そうした成功事例を参考に、企業が組織的に参入する例が増え、アプリの質もグッと高まった。現在のApp StoreやGoogle Play(旧Androidマーケット)で、有名ゲームメーカーやIT企業がダウンロードランキング上位を占めているのを見ると、もはや個人に手が届かないレベルになってしまったように感じる。「スマホでビジネスできている個人はごく一部のはず。アフィリエイトの方がよっぽど儲かる」と断言する業界関係者もいるほどだ。

 だからといって、目の前に広がる新しいフロンティアがあるのに、早々に諦めてしまっていいのだろうか。ビジネスの成功率で見たら、年々厳しくなっていくのは仕方ないが、そのチャンスは大企業でも、個人であっても等しく同じだ。

 スマホビジネスとは少し違うが、Pinterest(ピンタレスト) <http://pinterest.com/> という画像共有型SNSサイトをご存じだろうか。2011年末から、米国で急激に利用者が伸びているサービスで、米調査会社Experian Hitwiseによると、2012年1月には1週間に1700万人が閲覧したという。画面をピンボード(メモや写真を貼り付けるコルクボードのようなモノ)に見立てて、お気に入りの写真をネットで見つけたらそのまま貼り付けることができる。

 女性ユーザーが多いとされ、彼女たちの目的は単にお気に入りの写真を共有するだけではない。自分の好みの洋服やインテリア、化粧品などの"美しい写真"を並べることで、おしゃれな"ECサイト"や"ブティック"を作ってみたいという欲求を満たすことに成功している。国内では、芸者東京エンターテインメントが開発し、ヒットしたソーシャルゲーム「おみせやさん <http://www.geishatokyo.com/mixiapp/playshop/> 」は、同種のニーズを満たしている。ユーザー同士がオープンした"自分のお店"を見せ合い、自分のセンスや興味などについて共感できるのがウリだ。

 2010年にサービス開始したPinterestだが、2011年夏以降に急激にユーザーが増え、今や世界で注目される新サービスにまで成長した。世の中に様々なWebサービスがあふれていても、Pinterestのような新しい芽は常に登場し、成功できている。それはスマホビジネスであっても変わらない。自分のアイデアを信じて、成功に近づけるための正しい努力を続けられれば、そのチャンスは平等に与えられるのだ。

 そこで、ぶつかるのが「正しい努力」は何なのか、ということだ。独力でがむしゃらに突っ走っても、それが正しい方向とは限らない。成功率を少しでも上昇できるようにするためには、知識と経験を持った周囲からの"目"が何よりも大切だ。「なぜそのアプリがウケるのか」「どうやってユーザーを獲得するつもりなのか」「収益をどうやって確保できそうなのか」「事業拡大のための資金調達はどうするのか」——といった厳しい批判と検証を乗り越えなければ、まず成功はありえない。そうした企画を磨く場が、企業ではある程度用意されている。だからこそ、売れるアプリを作り続けられるのだ。

 翻って、個人はどうすればいいのだろうか。答えは一つ。同じ方向を向いて進んでいる"仲間"を作ることだ。スマホビジネスで一旗揚げたいと考えている人同士で、アイデアを批判し合い、磨き合うことで、自分に何が足りないのか、この先どうすれば良いのか、といったことを話し合う。そういう場ができれば、成功の確率は高くなる。

 世の中にはビジネススタートアップ(起業)に関するビジネススクールや相談会、コンテストなどがある。Infinity VenturesやOnlab(デジタルガレージ)、Samurai Incubate、IMJ(ブレークスルーキャンプ2012)といった有名なイベントで、新しい才能を見出したいベンチャーキャピタルやインキュベータが起業への支援をしている。そうした場所で自分の力を試しつつ、仲間を見つけ出すこともできる。また、日本Androidの会のようなスマホ技術者のコミュニティに参加すれば、自分には足りない能力を持った人的ネットワークを広げられる。

 また最近では、学生向けのビジネスコンテストなども非常に盛んだ。投資家や観客の前で、自らのビジネスプランを発表し、そのプレゼンテーションでどれだけの人の心を惹きつけられるかを競う。企業に就職しながらも、副業としてビジネスコンテストで磨いたプランを起業するという若者も増えている。アイデアは自分だけで温めるのではなく、オープンの場で公開して磨くことが、アイデアを完成に近づける最大の特効薬となる。そんな時代がスタートしている。

2012年4月24日火曜日

Trojan Uses Motion Sensors To Steal Smartphone Data

Motion-sensor data from smartphones can be used to effectively guess what keys a user is tapping and steal sensitive data such as PINs and bank details, according to new research (PDF) from Pennsylvania State University (PSU) and IBM.

The researchers developed a proof-of-concept Trojan for Android called TapLogger that uses a "training mode" to build up a database of key-click information before applying the information to refine its guesses as to what keys a user is tapping at any given moment.

Stealth attack

The software masquerades as an icon-matching game, and after the user has played 30 rounds it has access to more than 400 "tap events", researchers said.

"When the user is interacting with the Trojan application, it learns the motion change patterns of tap events," the researchers said in their paper. "Later, when the user is performing sensitive inputs, such as entering passwords on the touchscreen, the Trojan application applies the learnt pattern to infer the occurrence of tap events on the touchscreen as well as the tapped positions on the touchscreen."

The study was carried out by Zhi Xu, a PhD candidate in the Department of Computer Science and Engineering at PSU; Kun Bai, a researcher at IBM's T.J. Watson Research Centre; and Sencun Zhu, an associate professor of Computer Science and Engineering at PSU's College of Engineering.

The research builds on the fact that smartphone applications don't need any particular security clearance to access information from motion sensors. While their Trojan application was built for Android, the researchers said Apple's iPhone also makes motion-sensor data available to unprivileged applications.

The Trojan works because of the correlations between tap events and the motion change of the smartphone, the researchers said.

Subtle changes

During a tap event, the acceleration of the smartphone changes due to the force of the finger on the touchscreen. The taps also cause the handset to make particular movements. For example, when the user taps on the left side of the screen, this may cause the handset to turn slightly to the left.

"By observing the gesture changes during a tap event, the attacker may roughly infer the tapped position on the touchscreen," the researchers wrote.

The results may not be precise, but if the attacker knows contextual information such as the layout of the current view of the touchscreen, "he may be able to infer the user's inputs (e.g. the pressed number button) with the inferred tap position".

The paper, which was presented at the ACM Conference on Security and Privacy in Wireless and Mobile Networks last week, showed two feasible TapLogger-based attacks – guessing the PIN used to unlock the device and guessing a credit card PIN.

A University of California study last year (PDF) demonstrated a similar attack using software called TouchLogger, but TapLogger introduces a training mode and uses more orientation sensor readings, as well as applying the research to two practical attacks.

Android has been the focus of increasing security concern, with a report in February finding that the number ofmalicious apps targeting the platform increased by more than 3000 percent in 2011.

Last month the US' National Security Agency (NSA) said it had built an ultra-secure Android handset allowing fully-encrypted calls connecting through NSA servers. The NSA said it plans to share some of the technology behind the smartphone, codenamed "Fishbowl", for the creation of more secure Android handsets.

 
 

Proof-of-Concept Android Trojan Uses Motion Sensors To Steal Passwords

"TapLogger, a proof-of-concept Trojan for Android developed by resarchers at Pennsylvania State University and IBM, uses infrormation from the phone's motion sensor to deduce what keys the user has tapped (PDF), thus revealing otherwise-hidden information such as passwords and PINs."

2012年4月23日月曜日

GoFの23のデザインパターンを,Javaで活用するための一覧表 (パターンごとの要約コメント付き)

GoFデザインパターンの一覧表と,活用のためのコメント,および入門者が独学するためのリンク集(サンプルコード付き)。

入門者の独学を支援するために,このページのURLを提示して熟読させ,各パターンを短時間で効率よく学んでもらう。


デザインパターンプログラマの常識だ。 Java使いかどうかは問わない。

にも関わらず,入門書を買ったまま,途中で挫折する人が多い。

挫折の原因は,パターンの数が23もあって,多いからだろう。


全パターンをすんなり覚えてもらうためには,各パターンごとに

  • 要するにこういう目的のパターンなんだ。」
  • 「10文字で表現すると,パターンの意味はこうなんだ。」

という要点・本質を,短いコメントで伝えれば助けになるだろう。


こういった学習を通して,Java言語の「設計思想」も併せて感じ取ってゆけるはず。


全パターンの一覧表(要約コメント付き)

全パターンについて,10文字以内での要約コメントを付記した一覧表。

  範囲
クラス オブジェクト


Factory Method:

 動的にサブクラス選択

Abstract Factory: 工場の工場

Builder 初期化手順を細分化

Prototype: コピーを渡す

Singleton: 1インスタンスを保証


・クラス向けAdapter:

 継承ラッパー

・オブジェクト向けAdapter:

 委譲でラッパー

・Bridge: 拡張と実装の階層分離

Composite 再帰ツリー構造

Decorator: 委譲で意図的フック

Facade: 複数クラス利用手順書

Flyweight キャッシュ付の工場

Proxy: こっそりフック




Interpreter: 独自言語の実行

・Template Method:
 子が処理断片を具体化

・Chain of Responsibility:
 助け船ネットワーク

・Command: タスクキューとスタック

Iterator: 並んだ物を順番に処理

Mediator: スター状の相互作用

Memento: 状態のゲッタとセッタ

・Observer: イベントリスナ

・State: 状態オブジェクト

・Strategy: アルゴリズム切り替え

・Visitor: 構造の便利スキャナ

※この表からコメントを除去したバージョンが,本エントリ末尾にある。知識のテストに利用できる。


これらのパターンについて,「要するにどういうパターンか?」というのを,順を追ってわかりやすく解説する。

レベル別に分類して紹介し,23個全部をカバーする。

各パターンのシンプルな分類と説明:

  • (分類1) プログラミングのセンスがあれば,言われなくても自然に使うもの
  • (分類2) パターンの名前自体が有名で,あちこちで使われているもの
  • (分類3) 独力で思いつくのは困難だが,一度ちゃんと学べば,驚くほどプログラミングが開眼するもの
  • (分類4) メリットがわかりづらく,使われづらいもの

付加的な解説:

  • 大事なことは,何か?
  • 独学用のリンク集
  • その他のパターン

各パターンのシンプルな分類と説明

パターンの説明を,慣習に倣って「Abstract Factory」から始める*1のは,無理がある。

もっとわかりやすい順番が色々ある。ここでは,入門しやすい順に掲載した。


エントリの後半に,独学用のリンク集がある。それを見ながら,

各パターンの「本質」はこういう事ね,と納得しながら読み進めるとよい。


(分類1)プログラミングのセンスがあれば,言われなくても自然に使うもの:

パターンとしていちいち取り上げる必要性も薄いほどの物。

逆にそれだけ,オブジェクト指向プログラミング言語の入門者にとっては「初級の段階で必須の知識」という事になる。


  • Template Method: 子が処理断片を具体化
    • Java抽象クラスを作る目的そのものなので,今さら言われても,というパターン。
    • したがって,Java言語ではabstractなクラスは何のために作れるようになってるのか?という点から学べば,何の抵抗もなくこのパターンを受け入れられる。

  • Builder :  初期化手順を細分化
    • あれこれ注文を付けてから,最後にドカンと一発やらかすパターンである。最終的な処理をカスタマイズするために,事前に設定や命令を1個ずつ言い渡す事ができるパターン。とも言える。1個ずつ言い渡せるので,おかげでコンストラクタ内の初期化処理に何もかもを詰め込まないで済む。
    • 各種言語の各種ライブラリは,ユーザに対して選択の自由を与えるために,この形式を頻繁に取っている。いろいろ属性を設定させて,最後に画面表示とか,よくある。
    • とはいえ,このパターンではBuilderが特定のインタフェースを実装する事になっており,Builder自体の交換可能性が増している,という点もポイント。

  • Adapter :  継承でラッパー/委譲でラッパー
    • 単なるラッパークラスである。これだけだとパターンと言うまでもないのだが,「インタフェース(システム側からの見え方)の差し替え」という視点で見てみると,わざわざ言及される理由が少しは納得できるかもしれない。
    • ベンダが提供する既存APIの出来が悪く,これから作るシステムとの相性も悪い(=共通のインタフェースを実装していない)。なのでそのまま使いたくないのだが,APIの改造は禁止されている,とする。その場合,自分が好きなやり方でそれらのAPIを利用できるように,一段かませて「便利クラス」を作る。この便利クラスは,自分たちのシステムで使いやすい形式になっている(=共通のインタフェースを実装している)。
    • なおラッパークラスを作るには,元のクラスを継承してクラス単位でwrapするか,元のクラスのインスタンスをコンポジションで保持してオブジェクト単位でwrapするか,の2パターンがある。なので,Adapterパターンは前掲のマトリックス中の2か所に現れる。
    • ※付加的なテクニックだが・・・,Adapterパターンをうまく使えば,開発チーム内の対人関係が良くなる,という効用もある。低スキル者が滅茶苦茶なコードを書いた際,そのクラスのソースコード自体に横から手を出して他のメンバが書き変えようとすると,最初にコーディングした方のプログラマは「傷ついた」と感じるものだ。それを避けるために,ラッパークラスを一段かませて,ラッパークラス側を充実させて高品質にする。もとのクラスには手を触れないで,原作者の学習課題として保留にしておく。こうすれば,レベルにギャップがあっても低品質なコードの影響を最小限にとどめ,開発工程の品質保持と平和なチームの維持が可能になる。Adapterは,低品質また粗悪なコードからシステムを守るための「防波堤」のような役割をするのだ。

  • Strategy: アルゴリズム切り替え
    • アルゴリズム実装のための専用オブジェクトを複数作っておき,その中から使うものだけを動的に選んで実行する。
    • ある程度複雑なアルゴリズムになると,ふつうのプログラマであれば,その部分を切り出して集約するだろう。また,他のアルゴリズムに置き変わった時に備えて,互換性も持たせておくだろう。なので,あまり新規性を感じないパターンに思えるかもしれない。とはいえ,アルゴリズムの交換可能性を増すために,共通の基底(または共通のインタフェース)を持たせているという点は注目。
    • 「状況に応じてやり方を柔軟に変えたい」という意味では,Stateパターンと類似。なおかつ,Stateのほうが学習上は重要。

  • Decorator : 委譲で意図的フック
    • 操作対象にしたいオブジェクトをコンポジションで保持し,そいつにあれこれ操作を加える(Decorateする)。
    • コンポジションを使っていればいつの間にかそうなっているはず。これぞDecorator,と意識しながら使う程のものでない。Proxyパターンと酷似。
    • コードの見かけ上,DecoratorはDecorateeを引数に取るなどして外側をくるむ。つまり,内側のDecorateeが行なうメイン処理を,外側からDecoratorが何かフックしているのかな,という推察が可能。(しかしやはり,そこで特にDecoratorという名前が持ちあがるわけではない。)
    • そして保持する側と保持される側が同一のインタフェースを持っているので,Decorateされてる物とされてない物を同一視できる。フックのかかった物と,フックされなかった物とを共通項として取り扱えるわけだ。

  • Facade : 複数クラス利用手順書
    • 複数のクラスを呼び出す際,呼び出す順番を思い出さなくてすむように,定石として1メソッド内に集約しておく。そのメソッドは,いわば複数のクラスの利用手順書になる。
    • 再利用しやすいAPIやDSLを作ろうとする場合,自然に生まれる発想。もし自然にこうならないとしたら,プログラミングのセンスが微妙かもしれない。
    • Write less, Do more。

  • Mediator :  スター状の相互作用
    • 網目状の複雑な相互作用ではなく,中央にコントロールを集約した「スター状の結合」を介して,オブジェクト同士が相互作用する。中央にいるのは,管理者オブジェクトのようなもの。
    • あるUIが複雑で,たくさんの部品を持っていて,各部品ごとに制約やイベントがたくさん存在し,それらの条件分岐も大変・・・というような時に,素人はあっちこっちにイベントを埋め込む。そして全体として何をやっているコードなのか分からなくなり,そのうちメンテできなくなり,整合性が損なわれるようになる。こういった滅茶苦茶に分散したコードに付き合わされるのがどれほど大変な事か,経験者はその苦労を語る事ができる。
    • プログラミングのセンスがある人間は,そういう実装はしない。このUIはある程度複雑だな,と感づいたら,そのUI専用のマネージャクラスを立てて,各UI部品はそのマネージャクラスに対して通信するだけにする。そして,マネージャクラスは自分のもとに集約された情報をもとにして,UI全体を調整する役割を果たす。誰にも言われなくても,こういうプログラミング・スタイルを選択しようと自然に思い立つかどうかで,プログラミングのセンスが問われる事になる。
    • そういうわけで,Mediatorパターンは「複雑なUI」を実装する際によく使う。ただし,このパターンは「中央集権的」な発想であり,余りにも複雑すぎるUIになってくると中央で管理しきれなくなって,限界がくる。そういう場合は,後述するChain of Responsibilityパターンで,中央集約ではなく分散構造/バブリングの発想に切り替える。


(分類2)パターンの名前自体が有名で,あちこちで使われているもの:

各種ツール・ライブラリを使った経験があったり,業務経験を少し積んだり,そこそこプログラミングをやっていれば,いずれ目にする名前のパターン。

見た事がないとしたら,経験自体が少ないという事になるかもしれない。


  • Factory Method: 動的にサブクラス選択
    • サブクラスの中から選択する挙動を,動的に変えたい場合に。
    • Javaの各種フレームワーク上でDB操作していれば,いずれ目にする名前。Connection系のFactoryとか。
    • クラス単位でFactoryではないとしても,メソッド単位でFactoryになっているケースも多い。newキーワードを隠ぺいして何かのインスタンスを動的に生成して返していたら,そのメソッドはファクトリ・メソッドと呼ばれうる。
    • クラス設計の戦略がFactoryである場合,もしも何かのはずみで同一箇所にGenericsも導入しようとすると,たいへん悲惨な結果になる。Factoryは性質の異なる子クラスを増やす方針なわけだが,ジェネリクスはその真逆であり,たくさんあるクラスを型パラメータで1つに統一しようとする。なので,この2つの方針がぶつかりあうと,どこかで一斉にコードの矛盾が生じる。その矛盾に気づくのは,Factoryクラスに型パラメータが入り込もうとする瞬間である。「あれ?クラスを分けようとしてたんだっけ,それとも統一しようとしてたんだっけ?」という疑問で手が止まり,しばらく考えた後,Factoryとジェネリクスを両立させようとしていた自分の愚かさに気づくのだ。そんな目に遭わないためには,Factory等を始めとする「ポリモーフィズムをフルに生かして透過的に扱う」という設計パターンと,「型パラメータで抽象化して透過的に扱う」という設計戦略とが,ほぼ対極に位置するため相性が悪い。という点を覚えておいた方がいい。

  • Singleton :  1インスタンスを保証
    • プログラミング言語によっては,これを実現するためのライブラリが言語に組み込み済みなケースも多い。なので知名度は高い。
    • シングルトンには落とし穴が結構あるので,よくわかっている人なら,このパターンの利用を避けるケースが多いと思う。例えばグローバル変数問題は言わずもがな。さらに例を挙げると,Webアプリは複数のリクエストを同時に複数スレッドで受け付けるわけだが,スレッドという枠組みを超えて,複数プロセスでWebサーバのプロセスが走っているというシチュエーションも一般的である(Apache/httpdとか)。その場合,プロセス間ではメモリ空間が異なるためオブジェクトは共有されないので,頑張ってシングルトンを作ったのに本番環境では全く無意味でしたなんていうポカも珍しくない。これは,洒落にならないレベルのダメージを生む設計ミスである。こういう時,周りのメンバが「あっ,こいつSingleton使おうとしてるのかも…?」と感づき,必死で止めに入り,基本設計から再考するように説得する。しかし説得の際に,メモリ空間とかサーバプロセスに関する知識が相手に欠けていると,なぜダメなのか説明に苦労する羽目になる。という具合に,半可通が手を出すと大火傷するパターン。

  • Observer: イベントリスナ
    • Observerという名前ではなく,Listenerという形で,知らないうちに使いこんでいるはず。
    • 「イベントリスナ」という形で,動的なUIを書いた事がある人には馴染みのある概念のはず。監視対象にイベント観察者を埋め込んで,イベントが起こる時に何かさせる。JavaScript使いなんかには即通じる。
    • ただしJava言語にはクロージャがないので,イベントハンドラは○○Listenerクラスみたいな形で記述する必要が生じる。そこが冗長だが,Java言語というプラットフォームを使う以上はしょうがない。妥協点である。

  • Proxy: こっそりフック
    • プロキシ・サーバ(またはリバースプロキシ)という物の存在のために,名前だけは知られているパターン。中継するイメージが共通。
    • メインな処理をするオブジェクトをコンポジションで保持し,メインな処理の前後にフックをかませる。しかも,保持対象と保持者で共通のインタフェースを持っているために,相互の入れ替えがきくという点は,Decoratorパターンと全く同じ。
    • Decoratorは意図的明示的にフックしていたが,Proxyの場合は影で,隠れて,こそこそとフックしている点が異なる。クラスを使う側は,Decoratorパターンの場合は,呼び出し側は意図的にDecorate処理のコードを書く。しかしProxyの場合は,呼び出し側は「保持対象」と「保持者」のどちらを使っているのか意識しない。もしくは,気づけない。
    • 処理にこそこそとフックする,というのの具体例は,例えば「ネットにつながっていると思ってたら,実は違ってて,間に挟まっているプロキシサーバがキャッシュを投げてるだけだった」とか。メイン処理をするオブジェクトと呼び出し元の間に,こっそりと壁を作る(仲介者もしくは盗聴者を置く)事ができるのだ。
    • 別のオブジェクトへの中継地点となって本来の処理を隠ぺいしているメソッドは,プロキシ・メソッドなどと呼ばれる。呼び出し先は別のオブジェクトなので,これは単なるカプセル化とは異なる。

  • Iterator: 並んだ物を順番に処理
    • Java言語にあらかじめ組み込まれていない事が不思議で,これはJava言語の仕様のバグなんじゃないか?と思わせるほど,あって当たり前のプログラミング・テクニック。言語によっては標準APIとして提供される。
    • 「複数のものが順番に並んでいて,取り出せるようになっている」という,集合体(または配列)みたいなオブジェクトがあるとする。ものを順番に取り出して処理するのは,そのオブジェクト自身の責任である。そのオブジェクトを呼び出す外部オブジェクトの責任ではないはずだ。よって,「自分(配列っぽいオブジェクト)が抱えている要素達の面倒を,自分自身が見てあげる」べき。それがIterator。
    • したがって,Javaは純粋なオブジェクト指向の言語ではない。オブジェクト指向ではなく,アセンブラポインタといった低レイヤの考え方を好むC言語ユーザをJavaユーザに呼び込んで,Javaのシェアを拡大するためには,Sunはそうするしかなかったのだ。forループ内でカウンタ変数をインクリメントしながら一つ一つ取り出す,という,C言語ユーザにとってなじみ深い書式を採用するしかなかったのである。拡張forループと言えど,クラス構造の観点で言えば同じこと。つまり,マーケティング上の事情により,Javaはオブジェクト指向の言語になる事ができなかった。この歴史的な経緯は,下記の書籍などでも指摘されており,Javaをちゃんと使っている人なら皆が既によく知っている点だ。

オライリー,「プロダクティブ・プログラマ」,Neal Ford著。

  • セクション14.1.2「Javaの暗黒面」p212〜213。ポインタが多用されるC言語との後方互換性に配慮したおかげで,CやC++からJavaへの移行が楽になった。(Javaはオブジェクト指向でポインタがないにも関らず)
  • セクション10.2「オッカムのかみそり(必要以上の複雑さについて)」p172。JavaおよびC#という言語が作られた目的について。
  • セクション12.4「メタプログラミング」p195。言語に制限が多い事によって,プログラマは力を奪われるのみ。

Javaの上級者なら,Javaの長所だけでなく,欠点についてもよく知っているはずなので,彼らに尋ねてみるといい。


※逆に万が一,こういったJavaの欠点をすらすら言えないとしたら,そのプログラマはJavaを十分使っていない(もしくは,Javaしか知らないのでJavaで閉じた発想法しか持っていない)ということになる。

これはJavaに限らず,何かを習得する際には,全ての事に当てはまる。

    • ちなみにRubyのような純粋なオブジェクト指向の言語であれば,モデル層の記述はイテレータ(each系のメソッド)尽くしのメソッドチェインになったりする。findしてmapしてselectしてmapしてrejectしてuniqしてconcatしてjoin(またはinject)とか,極めて生産的かつ「思った通りに書けば思った通りに動く」を実感する。最近のプログラミング言語では,列挙されたデータの処理を記述する際にはそういうスタイルがだいたい可能になっている。Javaではこれと同じ事ができないので,記述が非常に冗長になる。なぜJavaで実現不可能なのか,を突き詰めると,結局「クロージャ(ラムダまたはブロック)を定義できないから」また「オープンクラスではないから」という言語仕様の難点に尽きる。JDK8から先の動向をウォッチすべし。
    • もし今後,JDKがだめそうなら,JVMプラットフォーム上で動く生産的な動的言語GroovyとかJRuby等)をウォッチすべし。世間でよく言われるように,Javaは「現代のCOBOLであって,COBOLと同様にある時期には非常に有用かつメジャーな商業的ツールではあるものの,何事もタイム・リミット付きなので,「先々をよく見越した上でスキル・ポートフォリオを考えないと,エンジニアとして化石してしまいますよ。」という警告に留意しながら技術動向にキャッチアップしてゆけば安全という事になる。手続き型言語からオブジェクト指向へのパラダイム・シフトが起こった時のように,現時点でも既にビジネス要求の変化が加速しており(要するに時代の変化のスピードがどんどん速くなり),静的言語がその「時代のスピード」の要求にいつまで耐えて持ちこたえられるか,見ものである。それまでの間はJavaを使いましょう。


(分類3)独力で思いつくのは困難だが,一度ちゃんと学べば,驚くほどプログラミングが開眼するもの

このレベルの習得が分かれ目。

自力で思いつく範囲内で設計を続けていると,ここには到達できない。


これらのパターンでは,凡人の発想では思いもよらなかったような対象物/構造をオブジェクト化する。

なので,オブジェクト指向設計の高みを目指す場合,このステップはきわめて有力な踏み台になり得るのだ。


ちょうど「ORマッピング(ObjectとRDB上のリレーションをマッピング)」のように,「Object-○○マッピング」という視点をすると,理解が早い。

「このパターンの場合,○○の部分には何が入るんだろう?何がオブジェクト化されているんだろう?」と。



  • State: 状態オブジェクト
    • システム開発の全工程を通じて,「状態遷移図」は非常に重要な役割を果たす。これは詳細設計フェーズの成果物であり,仕様変更に伴い変更されやすい。単体試験〜結合試験まで,テストケースの洗い出しのためにも極めて重宝する。システム運用フェーズでは,障害発生時にシステムサポート側がしょっちゅう見直す図となる。システム中でこの部分は,考慮漏れバグとか不整合が発生しやすい箇所だからだ。
    • Stateパターンは,個々の状態を表すための専用オブジェクトを作る。なので,状態遷移図ベースのダイレクトなコーディングが可能になる。いわば,Object-状態遷移図マッピングである。そういう経緯もあり,Strategyなんかと比べるとはるかに,システム設計の観点からして望ましいパターン。

  • Command: タスクキューとスタック
    • Stateでは1状態=1オブジェクトだったが,Commandでは1タスク=1オブジェクトとなる。タスク(またはイベント)が,1つのクラス内にカプセル化される。そういうタスクが何種類もあり,共通のインタフェースを実装しているので,複数のタスクを同種のものとしてまとめて取り扱って管理できる。要は,タスクマネージャっぽいものを実現できる(※Windowsの文字どおりの「タスクマネージャ」とはイメージが異なるが)Object-タスク・マッピング。
    • 複数のタスクを保管する際に,終わったタスクをスタック構造で保持すれば,「作業履歴」として参照可能になる。また,スタックの履歴内容に対してpushやpopすれば,直近タスクの「アンドゥ」や「リドゥ」も可能になる。
    • 逆に,処理待ちのタスクはキュー構造で保持する。各タスク(Commandオブジェクト)が,自分自身のタスク完遂のために必要なリソースの見積もり情報を保持していれば,複数のタスクの実行過程において「残り所要時間」とかを算出する事も可能になる。つまりは,プログレスバー
    • そういうわけで,インストーラのプログレスバーとか,アンドゥ・リドゥは,こうやって実装されていたのか!と開眼するきっかけになる。文字通り,操作・命令(「command」)に対する概念が変わるはず。

  • Memento: 状態のゲッタとセッタ
    • オブジェクトの状態のバックアップと復元が可能になり,アンドゥみたいなことができるようになる。バックアップ対象のオブジェクトには,そのオブジェクトの状態をバックアップするための専用のMementoオブジェクトを生成可能にする(状態のgetter)。また,バックアップされた状態オブジェクトを「食わせる」事により,特定の状態に復元させるためのメソッドも用意する(状態のsetter)。こうする事で,オブジェクトのカプセル化を保ったままで,オブジェクトの状態をバックアップ・復元できる。オブジェクト-バックアップ・マッピング。
    • getter/setterという概念や,オブジェクトのatomicな更新といった概念は慣れ親しんでいるだろう。でも,それを活用して特定のオブジェクトの「スナップショット」を取得&適用可能にする,という発想は,自然には生まれづらい。

  • Bridge: 拡張と実装の階層分離
    • このパターンだけ,メリットの説明が少しだけ長くなる。Bridgeは下記のような悩みを解決するパターンである。
      • 「たった1つの新しい機能を追加するたびに,全環境用の,全機能のコードをそれぞれ1から実装し直さなければならない…。」
    • Bridgeパターンを適用すれば,機能追加により生まれる拡張階層と,サポート環境追加により生まれる実装階層を,分離して別個に管理できる。その結果,下記のように状況が変化する。
      • 「たった1つの新しい機能を追加するたびに,全環境用のコードの修正個所は,それぞれ1か所ずつで済む。」
    • Bridgeパターンのメリットを,図を使って説明してみる。
■Bridgeパターン適用前:      ↓  Abstract   ┌─環境タイプ1 (Windows用実装)    ↓  機能ver.1 ←─┼─環境タイプ2 (Mac用実装)   機↓    ↑    └─環境タイプ3 (Linux用実装)   能↓    |   仕↓  Abstract   ┌─環境タイプ1   様↓  機能ver.2 ←─┼─環境タイプ2   の↓    ↑    └─環境タイプ3   進↓    |   歩↓   ・・・    ↓          機能バージョンアップのたびに    ↓          実装の同じ重複が延々と続く      ■Bridgeパターン適用後:      ↓              ↓  機能ver.1 ◇──→ 全verの機能実現用の   タ↓    ↑      API集のインタフェース   テ↓    |          ↑   広↓    |          ・   が↓  機能ver.2      ・・・・・・・   り↓    ↑       ・  ・  ・    ↓    |       環  環  環   ※↓    |       境  境  境   機↓   ・・・      1  2  3   能↓                       ↓            ←─────→    ↓             ヨコ広がり             ※(サポート環境別の)実装    
    • クラス図の全体像が,樹形図のような複雑さを失い,「Π」型ギリシャ文字のパイ)になったのがわかる。この上辺が「橋渡し」を行なっている部分であり,そのためにBridge(橋)という名前がつく。
    • 「機能仕様書の進歩」と,「サポート環境の種類(タイプ)の多さ」という2つの軸を見抜くことがキーになる。Bridgeパターンを使えば,これら2つの軸を「タテ広がり」と「ヨコ広がり」に分解して整理できるのだ。
    • なので結論として,Bridgeパターンの要約フレーズ「拡張と実装の階層を分離する」は,「時間経過に伴って機能が拡張されていくバージョンアップの過程と,実装タイプのバリエーションを豊富に広げる品揃えの充実具合を,別個に分けて,整理して管理できる」というふうにやさしく表現できる。(それを言いたかったので,わざわざAAで図を描いた。)
    • ※とはいえ,このパターンが必要になる理由は,ただ単に「Java言語はコードの共有がしづらいプラットフォームだから」とも言える。Moduleのmixin機構みたいなものが無いということ。「Javaが前提なら,こういうケースにはBridgeで対処可能だ。」と知ること自体は良いことなのだが,でもJavaしか知らないとBridgeの発想に固執してしまうかもしれない。それはそれでまずい。

  • Composite: 再帰ツリー構造
    • ディレクトリ構造や組織の人員構成など,再帰的な構造を実装するために必須のパターン。クラス図上では,子が親になり,親が子になる…という循環的な見かけを持つ。
    • ディレクトリ構造のサンプルコードで言うと,ファイルとフォルダを同一視/抽象化して,両者に共通の性質(インタフェースまたは基底クラス)を持たせるところがポイント。この見方は,自然には生まれづらい。オブジェクト-再帰構造・マッピング。
    • アルゴリズムをちょっと勉強した人なら,再帰呼び出しを使って「階乗の計算」ぐらいは実装できる。つまり処理の実行順という観点での再帰は知っている。しかしそれを知ってても,データ構造をうまく再帰的に実装し,拡張性とシンプルさを両立させる方法となると,自力で思いつくのは難しい。なので,Compositeパターンは意識的に学ぶだけの価値がある情報。

  • Interpretor: 独自言語の実行
    • 構文解析の結果を,オブジェクトにマッピングし,実行させるのである。ORマッピングならぬ,Object-BNFマッピングとでも言うべきパターン。クラス構造が再帰的なのはCompositeと類似。
    • とにかく一回実装してみないと,効用がわからない。自分の手で,何か作ってみること。そうしないと,急にソース中に現れた時に「これはInterpretorだ」と気付く事すらもできず,調査する事も出来ず,手も足も出ない。このパターンでは個々のクラスはシンプルなので,狭い範囲で見ていると,ググって何か手掛かりを得ることは不可能なのである。もしも計算機科学バックグラウンドが浅いためにBNFを見たことが無い場合は,事態はよりいっそう悪化する。
    • このパターンの需要は,一応ある。システムのユーザに対して,何か「独特の記法」を提供するような場合に必要になる。

  • Chain of Responsibillity: 助け船ネットワーク
    • よく言われるのは「リクエストのたらい回し」だが,もうちょっとわかりやすくいうと「助け船のネットワーク」である。自分では処理しきれないタスクだ,と判断したら,自分が知っている助け舟にヘルプを求めて,そいつに任せてしまう。任せた先でも対処しきれなかったら,さらにその助け船が呼ばれる。このように,助け船にヘルプを求める連鎖構造を作るのがこのパターン。全体として見ると,「奥の手を何重にも持っておく」事になるのだが,それだと一つのクラスが対処方法を何重にも張り巡らして待ち構えているように聞こえるので語弊がある。あくまでも,最初の受付にあたる部分から順番にタスクが運ばれてゆき,次の行き先は現在の処理者だけが知っている,という「口付きのネットワーク状の分散構造」がキーになる。
    • 少し専門用語を使って言いなおすと,「要求処理者の線形構造」とも言える。それぞれの処理者達は,自分がダメだった場合の次の行き先(ポインタ,参照)を持っている。だから線形構造と呼べなくもない。しかもそのポインタは,コンポジションとして実現されているので,動的な書き換えが効く。ただし,必ずしも一次元連鎖に限定されず,前述のように網目状のネットワーク構造(循環しない有向グラフ構造)でも構わない。
    • 技術的な言葉を使って説明すれば,GUIシステムにおける「イベントのバブリング」である。例えばブラウザ上のDOM構造で,JavaScriptのイベントは,親ノードへと伝搬してゆく。このエントリなどを参照。おかげで,表面から順番に奥に向かって進んでいく過程で,イベントに対処すべき適切な処理者がそのうち見つかる事になる。
    • このパターンを学べば,バブリングのようなUIシステムはこうやって実現されていたのか!と気づくきっかけになる。そして,処理を行なうオブジェクト同士の協調性を高くするような発想法が生まれる。

  • Visitor: 構造の便利スキャナ
    • 複雑なデータ構造がある場合,データ構造を表すオブジェクトの中には具体的な処理を書かない。かわりに,自分に対して処理を行なってくれるVisitorを受け入れるというロジックだけを整えておく。そして,Visitorはデータ構造を渡り歩き,各データに対して所定の処理を行なう。Visitorはデータ構造をスキャンしながら仕事をこなしているのである。
    • データ構造の側は,具体的な処理を知らなくて済む。Visitorというものが自分のもとを訪れて,何かの処理をしてくれるのだということさえ知っていればよい。また,Visitorの側も,具体的に定義されたデータ構造を知っている必要はない。データ構造の最低限のインタフェースを知っていればよい。そして,データ構造内での探索を行ない,また各データに対する具体的な処理を行なう。このようにして,データ構造と処理が分割される。
    • 要は,visitorはデータ構造に対する「処理付きの便利スキャナ・オブジェクト」となる。オブジェクト指向において役割の分割は肝要な概念なので,データ構造と処理の分離方法として一見の価値はある。ただ,ここまでやらなくても十分「仕事しながらスキャン」できるのでVisitorを実際に使う必要はない,という場合もある。


(分類4)メリットがわかりづらく,使われづらいもの:

デザインパターンの「日蔭組」である。

活用シーンが無いわけではない。なので,窓際族とまでは言わない。


  • Prototype: コピーを渡す
    • 派生オブジェクト達をあらかじめ生成して陳列しておいて,必要な時にコピーを渡す。派生オブジェクトを動的に管理(追加・削除)できる点がメリット。(もし派生オブジェクトがサブクラスの形式で提供されていたらそうはいかない。)
    • 浅いコピーのせいでトラブルが起きたら…?とか,グラフィックエディタを作る機会なんて無いよとか,おまけにPrototypeっていう名前がつくものは他にも色々あるしなど,各種障壁のために,少々手を出しづらく影が薄くなるパターン。

  • Abstract Factory: 工場の工場
    • 工場は,命令に応じて様々なプロダクトを動的に作る。でも,だんだん工場のバリエーションが増えてくる。そこで,工場自体を動的に生成して,さまざまな工場のバリエーションを持たせる。誤解を恐れずに一言で言い表すと,FactoryのFactory。工場の工場。
    • 要はFactory Methodパターンをさらに上から抽象化したものなので,FactoryとAbstractを組み合わせるとこうなるのね,という応用的な位置付けになる。

  • Flyweight: キャッシュ付の工場
    • このパターンは,インスタンス生成の負荷を減らすために,既存のオブジェクトを使いまわす事によってパフォーマンスを向上させる。という点では,SingletonパターンやPrototypeパターンと同じ。ただしインスタンス生成のタイミングとか,各インスタンスの共有の程度が異なっていて,Flyweightパターンの場合は実現すると「Factoryにキャッシュ機能が付いたような物」ができあがる。特定のタイプのインスタンスをくれ,と言われた時点でそのインスタンスを影ながら生成し,あとあと使いまわすという仕組みなので。SingletonとPrototypeの中間ぐらいに位置するパターンと言えるかもしれない。
    • Flyweightの発想自体は,プログラミングを進めていけば,自然な発想としていつの間にか使っているというケースがある。FactoryとSingletonを知っていて,Factoryの裏側でSingleton化対象がいくつもあるような場合は,自然とこういう設計になる。そういう意味では,「(分類1)言われなくても自然に使うもの」に入る,と考える事もできる。
    • だが,このパターン名自体が余りにもマイナーだ。それに,よく考えると,Flyweight自体がもともと提唱している設計をそのまま流用できるシチュエーションは以外と少ない。オブジェクトの生成コストが大きくて,なおかつインスタンスが「そのままで」使い回しが効く必要があるのだ。普通,使いまわされる側は多少なりとも個別にカスタマイズされるので,全く同一のインスタンスでは困る。なので,このパターンはよく考えると影が薄い方に分類されるのかもしれない。
    • あるいは,このパターンは実はアンチパターンなのかもと割り切って考える事もできる。オブジェクト生成のコストを削減するために,Factory役にキャッシュ機構を持たせようという発想自体はごく自然だ。だが,プリミティブ型ではないものをキャッシュしたらそれは値ではなく参照の保持なわけで,もし参照「先」で変更が発生したら全ての参照「元」に影響が及んでしまう。だからキャッシュ機構を作る際には用心しなさいよ。という,よくある警告を伝えるだけのために,このFlyweightパターンは存在する,と考えてもいいかもしれない。


以上で,全23パターンの要約を終える。

全パターンを「俯瞰」できたのでは?


大事なことは,何か?

これらのパターンの中には,重要で有用な物もあれば,そうでないものもある。

成長のために一読が必須なのもあるし,当たり前すぎて学び直す価値があまりない物もある。


だから,23個全部のパターンをキッチリやる必要はないのだ。

1個1個の設計パターンが「絶対」ではないから。


大事なのは・・・

  • (分類1)のレベルの設計は,言われなくても自然に思いつくような,そういうセンスを身につけること。
  • (分類2)のレベルの設計は,いちいち勉強しなくても「どっかで見たぞ」と言えるぐらいの,経験を積むこと。
  • (分類3)のレベルの設計は,意図的に学習するための時間と労力を割くこと。あと,この段階をしっかりと理解できる程度までの技術力を,ちゃんと身につけること。
  • (分類4)のレベルの設計は,他のパターンが分かれば別にいらないなあ,と自分自身で察知できる程度まで,他のパターンをよく理解すること。

という事になる。


そこまで来れば,次のステップを目指せるのだ。

学んだパターンを実践する。必要性を見極めて,適切なタイミングで採用する。

オリジナルのクラス構造を意識しつつも,自分なりにアイデアを盛り込んでカスタマイズして,実際に手を動かして実装してみる。


そうすれば,設計力・実装力が飛躍的に増す。

また,デザインパターン次の段階として「Effective Java」などの必読書を読めるようになる。

(逆に言うと,デザインパターンごときの段階でつまずいていると,各種必読書を読むための力がつかない。)

デザインパターンは,エンジニアに対して,先々のいろんな扉を開いてくれるのだ。



独学用のリンク集

デザインパターンの具体的なサンプルコードや,個々のパターンに関する詳しい解説は,下記のリンク集から取得可能。


ぶあつい入門書を買わなくても,やる気さえあれば,デザインパターンは無料で習得できる。

※とはいえ,古本でも構わないので,手元にリファレンスとして紙媒体があった方が良い。(本エントリを印刷してもいいけど。)

それに,いわゆる「名著」は将来的に読破・制覇した方がよい。


入門者向けのパターン一覧表:

サルでもわかる 逆引きデザインパターン / デザインパターンとは

http://www.nulab.co.jp/designPatterns/designPatterns1/designPatterns1-2.html

  • 名前と概要の一覧表
  • メリットは,再利用性の高い設計,コミュニケーション時の共通言語,オブジェクト指向の理解

Deep Side of JavaJava 言語再入門 第3回 〜 クラス設計とデザインパターン

http://www.nurs.or.jp/~sug/soft/java/java31.htm

  • 名前と概要と適用例の一覧表

矢沢久雄の早わかりGoFデザインパターン

http://itpro.nikkeibp.co.jp/article/COLUMN/20051123/225074/

  • 名前と,名前の直訳と,解説記事へのリンク
  • バブルソートや二分探索といったいわゆる「定番アルゴリズム」のようなもの。知ればプログラミングに目覚める

Java プログラマのためのデザインパターン入門

http://objectclub.jp/technicaldoc/pattern/DPforJavaProgrammers/

  • デザインパターンのカテゴリ」に一覧表。
  • 複数組み合わせて効果を発揮する場合が多い。java.awtクラスの設計例

中級者向けのパターン一覧表:

デザインパターンを読み解く(おすすめ

http://www.happiese.com/system/dpattern.html

  • 分類方法に関する鋭い考察と,まとめ。紹介・解説だけでなくコメント・批判つき
    • 「クラス設計の上位レベルのコンセプトと、コーディングのテクニックをごっちゃにしたようなもの」
    • 大方は普通にクラス設計してくれば出てくるもので,あえてパターンと名づけるほどのものではない。パターンというよりテクニックやイディオム
  • デザインパターン全体を通して強調されているのは、インターフェース(やAbstract)でプログラミングするということ

GOF デザインパターン一覧

http://www14.atpages.jp/hirotech/top/Design_Patterns/

  • 各パターンの動機づけなど,かなり詳しい。C++とJavaのコード有。

全てのパターンを,Javaのサンプルコード付きで独学できるページ:

デザインパターン INDEX

http://www.techscore.com/tech/DesignPattern/index.html/

  • 練習問題と回答とUMLダイアグラムつき

デザインパターン入門(C#,Java サンプルコード)、UMLで紹介

http://www.rarestyle.net/main/patterns/patterns.aspx

  • JavaだけでなくC#のサンプルコードもある。.NET屋さんにも。

デザインパターンの骸骨たち (RE-BONE) with C

http://www002.upp.so-net.ne.jp/ys_oota/mdp/

  • JavaだけでなくC++と,なぜかC言語でのサンプルコードが・・・

矢沢久雄の早わかりGoFデザインパターン

http://itpro.nikkeibp.co.jp/article/COLUMN/20051123/225074/

  • プログラム全体のコードが載っているわけではなく,要所のみを数行でさらっと解説

ときに,「オブジェクト脳のつくり方」("オブ脳")という書籍を本屋で見た事のある人も多いはず。

あの本は,ちょっと吹っ飛んだ入門書なのだが,23あるデザインパターンの中で最も重要なのは下記の5つだ。 としている。

  • Template Method (本エントリでは分類1)
  • Factory Method ( 〃 分類2)
  • Composite ( 〃 分類3)
  • State/Strategy ( 〃 分類3)

※4章の「先人は偉い、超手抜きパターン習得法」を参照。

著者の牛尾 剛氏によれば,「他のパターンはこれら5個の応用に過ぎないので,後から手を付ければいい」のだという。

多数あるパターンから要点のみを抽出して,効率的に学習する上で,参考にできる意見だろう。



「マルチスレッド編」のデザインパターン

デザインパターンには「マルチスレッド版」もある,とされている。

これはGoFとは関係なし。



国内での認知は,下記の書籍の貢献が大きい。

増補改訂版 Java言語で学ぶデザインパターン入門 マルチスレッド編 [大型本]

http://www.amazon.co.jp/exec/obidos/ASIN/4797331623/

  • 700ページもあって5000円する本

その本の旧版の書評

http://manuke.com/review/view.php?f_revid=5469

  • コンピュータ科学にのっとった美しい解説に感心」
    • Immutable:「読み取りだけなら排他制御は必要ない」という数学で言えばゼロにあたる概念
    • マルチスレッド開発における公理系とも言えるモニター(synchronized)やウェイトセット
    • 定理の集合とも言えるパターンランゲージ
  • synchronizedを見つけたら「なにを守っているのか」に着目すると良い、のような実践的な手引きも

Think IT著者陣がおくる デザインパターン必携書籍 厳選6冊

http://thinkit.co.jp/article/941/1

  • スレッドの食わず嫌いを克服する入門書
  • 並行処理のシステム開発は、オブジェクトを壊さず、デッドロックをおこさない性質をもつ必要がある。そのためのパターンの基本

増補改訂版 Java言語で学ぶデザインパターン入門 マルチスレッド編 の感想

http://www.sutosoft.com/room/archives/000513.html

  • クリティカルセクション等の定石を,Java用のパターン名として言いなおしたもの
  • マルチスレッドでの開発が未経験であれば必読書
  • 経験者であれば技術的に新たに得る物は少ないかもしれないが,パターン名を共通のボキャブラリとして獲得できるので,マルチスレッドに関する技術的な解説文章を書く時に重宝する。パターン名を提示するだけで説明が済むから。

上述の書評から見てわかるように,もしマルチスレッドに自信がなければ,中古・新品問わず購入が推奨される。(もちろんGoFが終わってからの段階だが)

WIN32API上とか,他のプラットフォームや他の言語でスレッドを十分に扱った経験があったりしても,とりあえず目次の一覧に目を通し,パターン名を「Java用のボキャブラリ」として覚えておいた方がよい。



Web上で独学するためのリソース:

デザインパターン入門 マルチスレッド編まとめ

http://d.hatena.ne.jp/otuzak/20080527/1211864889

  • 全12パターンの要約メモ
    • Single Threaded Execution
    • Immutable
    • Guarded Suspention
    • Balking
    • Producer-Consumer
    • Read-Write Lock
    • Thread-Per-Message
    • Worker Thread
    • Future
    • Two-Phase Termination
    • Thread-Specific Strage
    • Active Object

ギコ猫とマルチスレッドのパターンたち

http://www.hyuki.com/dp/cat_index.html#thread

  • 12パターンの概要をAAで学ぶことができる

デザインパターン(マルチスレッド)

http://www.tom.sfc.keio.ac.jp/~fjedi/wiki/index.php?%A5%C7%A5%B6%A5%A4%A5%F3%A5%D1%A5%BF%A1%BC%A5%F3%28%A5%DE%A5%EB%A5%C1%A5%B9%A5%EC%A5%C3%A5%C9%29

  • 12パターンのJavaによるサンプルコードと解説集


その他のパターン

GoF以外の他のデザインパターンは,下記のサイトで学習できる。

GoF以外のパターンを紹介します

http://www.hyuki.com/dp/dpinfo.html


こういったのを学ぶ際には,各種の「オブジェクト指向の原則」を頭に入れておくと,全体が俯瞰しやすいと思われる。

オブジェクト指向の原則

http://www.tom.sfc.keio.ac.jp/~fjedi/wiki/index.php?%A5%C7%A5%B6%A5%A4%A5%F3%A5%D1%A5%BF%A1%BC%A5%F3#i6303b5f



補足:面談用の一覧表

冒頭の一覧表から,コメントをすべて除去した物を掲載する。


・Factory Method ・Abstract Factory

・Builder

・Prototype

・Singleton

・Adapter ・Adapter

・Bridge

・Composite

・Decorator

・Facade

・Flyweight

・Proxy

・Interpreter

・Template Method

・Chain of Responsibility

・Command

・Iterator

・Mediator

・Memento

・Observer

・State

・Strategy

・Visitor


例えば採用の面談なんかで,

鼻高々に「Javaの設計できますよ」というエンジニアがいたら,上記の表を印刷し

それはとても良いことですね。じゃ,ここにあるのを全部,それぞれ一言で説明してもらえますか

と言う。


前述の通り,全部をそらで言える必要はない。

重要なものとそうでないものを区別した,それなりに的を射た回答が返ってくれば,OK。

さらに,自分がよく使うパターンの好き・嫌いが言えれば,なお良し。


もし気まずい表情で,よくわかりませんという回答が返ってくれば,

「じゃあ,かわりに何を使ってオブジェクト指向の設計を勉強したの?」

と質問する。

筋道だてて説得力のある納得のいく回答が返ってくれば,問題なし。

口ごもったら,切り捨て。