AWS Summit2015に行ってきた
6/2-3で行われたAWS Summit 2015と併設イベントのデベロッパーズカンファレンスに行ってきました。
聴講したセッションは次の通り。
Day1
- Day1 キーノート(基調講演)
- GitHub, AWS などの分散テクノロジーが実現する、デベロッパー主体のアプリケーションデリバリ
- 【パネルディスカッション】デベロッパー視点でみた AWS
- 【パネルディスカッション】デベロッパーが切り拓く、次の時代
- 2035 年、その時デベロッパーはどう生きるか
- 【パネルディスカッション】高まるゲームプレイ動画の価値。注目市場の今後の展望とは!?
Day2
- 【ランチセッション】【デベロッパー向け】実践 GitHub Flow(同時通訳)
- 【デベロッパー向け】日本最大の即レスサービス「アンサー」を支える Amazon DynamoDB
- 【デベロッパー向け】なぜクックパッドは開発しやすいのか
- 【デベロッパー向け】Run Code in The Cloud : AWS Lambda 概要
- 【デベロッパー向け】デベロッパーのためのクラウド DB 入門: Amazon RDS 編
- 【パネルディスカッション】テーマ: IoT が変える世界
以下、印象に残ったことを書いていきます。
Day1
Day1キーノート(基調講演)では、まずはじめにAWSの規模についての数字が紹介されました。世界中でどれだけAWSが使われているか、どのようなスピードで成長しているか、どれだけのサービスがあるか、など。この数字を見せられただけでAWSの凄さに圧倒され、だいぶお腹いっぱいになりましたw
GitHubのCEOスコットさんの話。今後はあらゆる業種の会社が全てソフトウェア会社になるということ。昔はOSSそれぞれに様々なルールがあってOSSに貢献するのは敷居が高かった、それで、Gitを使ったGitHubというフローを作って、ルールを統一することでOSSに貢献しやすくなったということ。GitHub Flowはソフトウェアの世界だけではなく、様々な世界に使える。例としてホワイトハウスがGitHub上にドキュメントを公開していて、上院議会からプルリクがきたなんて話。プルリクを使うことで、変更に対する理由が残るので良い。最も重要な事はOSSに参加して貢献すること、それで得た経験は役に立つ。
デベロッパは今後どう生き残るのかというテーマのディスカッションが2つ。
まず今後10年というテーマでスピーカーはnaoyaさん・Crowdworksの大場さん。結論としては、トップデベロッパですら正解はわからないし不安はある。だから逆に安心してってw 必要なことは、今起きていることに全力で取り組むしか無いということと、デベロッパとして自分の相対的なポジションを知っておくこと。もはや開発者は開発だけやればいいという時代ではなく、ビジネスのゴールに向かっていく責任があるということ。
続いて20年後というテーマで大前 研一氏・大前 創希氏による親子トーク。親子ならではの掛け合いが面白かったw 内容としては、今ある仕事の大部分はインド等の安い人材、もしくは、ロボットがやるようになる。生き残りたいのなら、とにかくロボットが出来ない仕事、つまり「発想・構想・コンセプトを生み出すことをやれ」ということ。ちなみにロボットは発想を生み出す仕事をできないのか?という問に対しては、「ロボットも発想はできるが、そこに独自性はなく価値は生まれない」とのこと。ユニークを生み出せるのは人間だけみたいな話でした。なんか哲学的。
Day2
GitHubのコービーさんがGitHub Flowについて解説。超イケメンな上に片言の日本語で挨拶とか、悶絶した人も多いんじゃないでしょうか。内容としては、プルリクをするときは準備が整ってなくてもとにかく早く表に出す事が大事で、そうすることでいろんな人に意見をもらえることに価値があるということ。それからコードの改変に関して、競合などでブロックしないようにすることが開発のスピードを保つ上でとても大事なのでそういう仕組(github/flipperを使っている。)を使うこと。Production Readness ReviewとPostship Health Checkを用いたPDCAは単純な仕組みだけど効果がある。バグを恐れずにデプロイのスピードを上げることで、結果的にバグの修正も早くなり前進し続けることができる。GitHub Flowを上手く運用するためには、ルールをドキュメント化する、自動化に投資する、テストやデプロイの信頼を構築する、早めにディスカッションする、複雑さが発生したら疑問視する、早くやってみること、などをあげていました。
DynamoDBについては、nanapiの秋田さん。KVS的に使う。特徴としては、キーの他にRangeキーを組み合わせて使える。課金はスループット(Read/Writeの量)なので、うまく節約するためのコツが色々。RDB的な使い方をしてしまうとスループット破産するので注意が必要。AWSの「よくある質問」がとても充実していてすごい。
CookPadの開発方式についてはCookPadの成田さんから、開発・テスト・デプロイの3点で紹介。開発については、開発に用いるデータはダミーデータではなく本番データを用いるべきということ。ステージング環境というのはあまり使われていなくて、本番環境で限られたユーザで試行運転をする。そのためのツールとしてChankoがある。テストはテストケースが膨大なのでRSpecを並列実行するRRRSpecっていうのを開発して2日かかったテストが数分になった。デプロイもサーバ数が膨大なのでmamiyaっていうのを開発して100台のEC2に12秒でデプロイできるようになった。これら3点全てで一貫しているのは、『効率の悪い作業を徹底的に効率化すること』がちゃんと行われているということです。もう一つ重要な事は「割れ窓」を放置しないということ。どちらも言われれば当たり前の事なんですが、その当たり前をちゃんとできるのは凄いと思います。
AWSの西谷さん・岩永さんからlambdaとRDSの紹介。lambdaはAWSの他の機能と簡単に連携できて、サーバレスでジョブを実行できるのでとても便利ですね。RDSもDBの厄介な部分を全部AWSがやってくれるので本当に便利だと思います。意外だったのは、SQLServerやOracleも従量課金で利用できて、ライセンスは従量課金に含む方式と、既存のオンプレミス環境のライセンスをAWSに引き継ぐこともできるということでした。あとはPoint in Time Recoveryっていって、障害調査などである時点のバックアップをすぐに他のインスタンスで復元して見られるっていうのが便利だなと思いました。
個別のセッションについては以上。
ちなみにAWSからのセッションのスライドは全てアップされるそうです。
全体を通じては、まずAWSに対する認識がすごく変わりました。数年前のAWSっておそらくEC2とS3がメインで、いわゆるインフラサービスねって認識でしたが、今のAWSはインフラレイヤーだけでなくアプリケーションレイヤにも様々なサービスがあるので、ほとんどのサービスがAWSの中だけで構築できるインフラ・アプリケーションプラットフォームであるという認識になりました。
それから、デベロッパーズカンファレンスも併設されていたということもあり、AWS以外にも色々なセッションがありましたし、ランチブッフェorランチまで付いて参加費無料なのでデベロッパなら行き得しかないですね。また来年も行きたいと思います。
Macの環境構築メモ(ターミナル/シェル)
『エンジニアたるもの使う道具にはこだわりを持て』ということでMacの開発環境を色々といじってみました。こういうのは書いておかないとすぐ忘れてしまうので備忘のためにメモしておきます。
iTerm2
今までターミナルはMacのデフォルトのを使っていました。カラースキームとかも綺麗で特に不満は無かったのですが、定番のiTerm2を使ってみることにしました。
今のところ使っている機能としてはこのくらいです。
機能 | ショートカット |
---|---|
検索する | Ctrl+f |
ペインを水平分割する | Ctrl+d |
ペインを垂直分割する | Ctrl+Shift+d |
ペインを移動する | Ctrl+Option+方向キー |
ペインを閉じる | Ctrl+w |
タブを移動する | Cltr+Shift+[ またはCltr+Shift+] |
まだまだ機能はたくさんあるので使っていて不便を感じたら調べるといいですね。ちなみに私は前回入力したコマンドを再入力する際に↑
キーを連打するのですが、押す回数が多いのでもっと簡単に履歴を探せる機能がほしいなと思ったんですが、これはターミナルではなく別の機能で実現できました。
iTerm2のカラースキームはここにたくさん(たくさん!)あるので、好きなモノをダウンロードしてインポートできます。
https://github.com/mbadolato/iTerm2-Color-Schemes
oh-my-zsh
oh-my-zshはzshの設定を管理するためのツールです。zshは今までも使っていたのですが、カスタマイズはほとんどしていませんでした。入力補完とかは何もしなくてもついてくるので超便利ですけどね!
https://github.com/robbyrussell/oh-my-zsh
oh-my-zshには「テーマ」と「プラグイン」という2つの便利な機能があります。
テーマ
テーマは見た目の表示をカスタマイズしたテンプレートで、あらかじめたくさん(たくさん!)の種類が備わっていて、設定を変えるだけでそのテーマが使えるようになります。また、テーマはシェルスクリプトで書かれているので、ちょっとしたカスタマイズなら簡単にできます。
https://github.com/robbyrussell/oh-my-zsh/wiki/themes
私は"wedisagree"というテーマを使っているのですが、現在時刻は行ごとに出力しなくてもいいので削除しました。このテーマはカレントディレクトリのgitリポジトリの状態を表示してくれるので、ブランチの切り替え忘れとかを防げて便利ですね。
ZSH_THEME="wedisagree"
プラグイン
プラグインはコマンドのショートカット集のようなものです。
https://github.com/robbyrussell/oh-my-zsh/wiki/Plugins
例えばbundler
というプラグインを入れてbe
と打つと、bundle exec
が実行されます。今まではわざわざaliasを書いて設定していました。プラグインもあらかじめたくさん(たくさん!)備わっていて、設定に書くだけで使えるようになります。なお、各種プラグインの設定は、~/.oh-my-zsh/plugins
の中にある設定ファイルを見ると分かります。
plugins=(git osx brew bundler rails)
autojump
autojumpはディレクトリ移動を高速にするためのツールです。移動したことのあるディレクトリを記録し、次回以降はフルパスを入力しなくても、j [移動したいディレクトリの一部の文字]
と入力するだけで移動できます。
インストールはHomebrew経由で入れてしまうのが簡単です。
brew install autojump
あとは、お使いのシェルのrcファイル(私は.zshrc)に以下を追加します。
[[ -s $(brew --prefix)/etc/profile.d/autojump.sh ]] && . $(brew --prefix)/etc/profile.d/autojump.sh
しかし、私の環境ではこのままでは以下のエラーとなりました。
$ j usage: autojump [-h] [-a DIRECTORY] [-i [WEIGHT]] [-d [WEIGHT]] [--complete] [--purge] [-s] [-v] [DIRECTORY [DIRECTORY ...]] autojump: error: unrecognized arguments: -l
j
のエイリアスが本来ならばjobs
になるはずなんですが、なぜかjobs -l
となるためエラーとなります。おそらくoh-my-zshの影響かと思うのですが、なぜこのようなエイリアスになるのかは分かりませんでした。対処として、先ほど追加したautojumpの設定の下に、alias j="jobs"
を追記することでエイリアスの上書きができました。
他にzという同様のツールがありますが、こちらは[移動したいディレクトリの一部]
が充分でない(候補がたくさんある)時でも、優先順位が一番高いディレクトリへ移動してしまうので、autojumpの方が使い勝手が良さそうです。
percol
https://github.com/mooz/percol
これを使って色々と便利なカスタマイズをしているブログ記事が見つかりましたが、今回はコマンド履歴の検索をしてみました。設定方法は以下のサイトで説明されている通りです。
http://blog.zoncoen.net/blog/2014/01/14/percol-autojump-with-zsh/
例えば、20回前に入力した長いコマンドを再度入力したいとき、今までは↑
を20回押してましたが、これを使うとCommand+r
でインタラクティブモードになった後にコマンドの一部を入力して検索すると絞り込まれていきすぐに見つけることができます。
参考
node.jsの環境構築メモ
Yeomanを使ってみようと思って、Macにインストールされているnode.jsをすごい久しぶりに触ろうとしたらエラーが起きたので、nodebrewを使って再構築したメモ。
node.jsのアンインストール
まずはじめに、Macにインストールされているnode.jsをアップデートし、npmパッケージを入れていこうと思ったら、node.jsをアップデートした後にnpmコマンドが使えなくなってしまいました。node.jsをアップデートする前から使えてたかどうかは不明です。(かなり長い間使っていなかったので。)
$ node -v v0.8.16 $ n stable install : v0.12.2 mkdir : /usr/local/n/versions/0.12.2 fetch : http://nodejs.org/dist/v0.12.2/node-v0.12.2-darwin-x64.tar.gz installed : v0.12.2 $ node -v v0.12.2 $ npm module.js:338 throw err; ^ Error: Cannot find module 'are-we-there-yet' at Function.Module._resolveFilename (module.js:336:15) at Function.Module._load (module.js:278:25) at Module.require (module.js:365:17) at require (module.js:384:17) at Object.<anonymous> (/usr/local/Cellar/node/0.8.16/lib/node_modules/npm/node_modules/npmlog/log.js:2:16) at Module._compile (module.js:460:26) at Object.Module._extensions..js (module.js:478:10) at Module.load (module.js:355:32) at Function.Module._load (module.js:310:12) at Module.require (module.js:365:17)
npmコマンドを叩くと上記のエラーが起きます。モジュールが足りないと言われるがそもそもnpmコマンドが使えないのでモジュールを入れる事ができませんでした。また、npmをアンインストールするにもnpmコマンドを使うので詰んでしまった。。
なので、node.jsから入れなおすことにしました。
ところで今使っているnode.jsはどうやって入れたものか?それがわからないと消し方もわからないのですが、まず一番ありそうなところで、Homebrewを確認してみます。
$ brew list node ...
brew経由でnodeが入っていた事は分かりましたが、フォルダ名が現在使っているバージョンとは違いました。これはアップデートする前のバージョンが表示されるのかもしれませんが、この時のログが流れてしまってもう確認できません。なんにせよもう必要がないのでアンインストールします。
$ brew uninstall node
もう一つの方法として、nodeをインストーラからインストールした場合の削除方法というのもありましたので、念のためこちらもやっておきます。また、あわせてnpmのグローバルでインストールしたパッケージも削除しました。手順は以下のサイトを参照しました。
http://whiskers.nukos.kitchen/2014/09/25/nodebrew.html
これでもまだnodeの実行モジュールが残っていてパスが通るので、手動で実行モジュールを削除しました。(たぶん正しい手順ではないです。)
$ which node /usr/local/bin/node $ sudo rm /usr/local/bin/node
nodebrewのインストール
nodebrewはnode.jsやio.jsのバージョン管理ツールです。Rubyでいうrbenvみたいなものですね。他にもnode.jsのためのバージョン管理ツールが色々とありますが、nodebrewが一番環境をクリーンに保てて良いというのを目にしたのでこれにしました。実際、使うのは~/.nodebrew
だけで、あとはパスを通すだけです。とってもクリーンですね!
インストール方法もこちらのサイトを参考にしたので、自分が改めて書くまででもないですね。
http://whiskers.nukos.kitchen/2014/09/25/nodebrew.html
基本的なコマンドだけメモしておきます。
- nodebrew ls-remote
- nodebrew install-binary [バージョン]
- nodebrew uninstall [バージョン]
- nodebrew list
- nodebrew use [バージョン]
nodebrew install [バージョン]
でもインストールできますが、ソースからコンパイルするため非常に時間がかかります。通常はinstall-binary
を使うといいですね。
参考
ちなみに、今から使うんだったらio.jsじゃない?って思ってちょっと調べてみたら、こんな記事が見つかりました。内容は記事を見ればわかるのでここには書きませんが、自分は特に最新機能が必要でない限りはnode.jsを使いつつ様子見しようと思います。
http://yosuke-furukawa.hatenablog.com/entry/2015/03/05/171527
『関数型プログラミングに目覚めた! IQ145の女子高校生の先輩から受けた特訓5日間』を読んだ
『関数型プログラミングに目覚めた! IQ145の女子高校生の先輩から受けた特訓5日間』を一読したので感想を書いていきます。
関数型プログラミングに目覚めた! IQ145の女子高校生の先輩から受けた特訓5日間
- 作者: 岡部健
- 出版社/メーカー: 秀和システム
- 発売日: 2015/04/24
- メディア: 単行本
- この商品を含むブログ (3件) を見る
この本の感想を3行でまとめると
- 命令型プログラミングから関数型プログラミングへのパラダイムシフトを体験できた
- 関数型プログラミングができるまでの歴史的背景を知ることができた
- 本を読む姿勢を改めて考えさせられた
パラダイムシフト
本書の前半半分は、命令形プログラミングと関数型プログラミングのパラダイムの違いを非常に分かりやすく説明されています。自分が今まで書いていた命令形プログラミングはフローを作成して機能毎に分割して作っていましたが、関数型プログラミングはフローや状態を排除し論理毎に機能を作成し、必要になった時に必要な分だけ計算する(イベント駆動)という方法を取ります。「論理」と「計算」を分けて考えるという説明はわかりやすかったです。
一方の後半半分は、FRP(関数型リアクティブプログラミング)の説明になるのですが、アリストテレス、ピタゴラス、プラトン、デカルト、などの哲学思想(これはこれで読み物としては面白かったですが)とFRPを対比させて説明が進んでいくのですが、正直最後の方はついていけなくなりました。まあこの辺は、FRPだけを説明するのはもっと簡単だけど、筆者としてはその根本的な思想を伝えたかったのだと思います。なお、これらの大部分は著者のブログの記事(量子コンピュータ関連のエントリー)にも書いてありますので、興味があれば読んでみるとよろしいかと。
歴史的背景
会話形式で説明が進んでいく中でいくつものプログラミングに関する歴史が説明されており、読み物として面白かったです。例えばJavaScriptの生い立ちの話とか、命令形プログラミングから関数型プログラミングへのパラダイムシフトやの歴史、そして次のパラダイムシフトは何かなど。
本を読む姿勢
本書を買う前から著者のブログ等で著者の関数型プログラミングの説明に対する否定的な意見があることは知っていましたが、元々の意見が交わされていたサイトは削除されてしまい、今は罵り合いみたいな情報しか残っておらず、遅れて知った身としては何が正しいのか分かりません。ですから、果たして「この本を信頼して読んでよいのか?」という不安がありました。
しかしそもそも、正しい本の読み方としては、本を100%信用して読むのではなく、疑問を持ちながら読むことも必要だということを、『本を読む本 (講談社学術文庫)』という本の中でアドラーが言っていたのを思いだしました。本書を通じて関数型プログラミングに興味が湧いたので(この点に関しては間違いなく読んでよかったと言える)、他の関数型プログラミングに関する本や情報も今後調べて身につけていきたいと思います。
全体を通して
本書は科学哲学史の観点から関数型プログラミングの根本に迫るというアプローチを取っています。このへんは好き嫌いが別れるところかと思いますので本を購入される前に立ち読みをするなり著者のブログに目を通してみることをオススメします。しかし事実として、関数型プログラミングのパラダイムシフトは既に起きており、オブジェクト指向に変わる次のスタンダードになりうるということは大いに共感できたし、実際に世の中の動向もここ数年で「イベント駆動」という方式を取るプロダクトがどんどん生み出されていますので、自分も今のうちに関数型プログラミングを勉強しておかないとなーと思いました。
次にやること
- 関数プログラミング実践入門 ──簡潔で、正しいコードを書くために (WEB+DB PRESS plus)を読む
- Electon(Atom Shell)をさわってみる
- Facebook-Reactをさわってみる
- エディターのカスタマイズ(技術者たるもの使う道具を磨けという一節があり、刺激されたので)
gem yankのポリシーが変わったそうです
たまたま目に止まったのでメモ。
Policy change about gem yank | RubyGems.org
gem yunkは、RubyGemsに公開したgemを公開停止にするコマンドです。
記事の内容を要約すると
いままではgem yankしたら公開停止にするだけでファイルは消さなかった(サイトからはダウンロードできた)んだけど、どうしても消す必要がある物はサポートの人たちがボランティアで削除の対応していて、それに結構な手間がかかっていた。だから今度からは、gem yankしたらRubyGemのストレージからは勝手に消すようにしたけど、非公式のミラーサイトにアップされたものやwebhook経由で公開したものは消せないから気をつけてね。
って感じだと思います。
ちなみにgem yankを取り消す(公開停止を解除する)時は、gem yank --undo
が使えたんだけど、これは使えなくなるのかな?
なんにせよ、gem pushするときはくれぐれも慎重にやりましょう。
Array#eachからRubyのブロックを理解する
Rubyのブロックについて、『パーフェクトRuby』を読んで調べました。内容はQiitaに投稿してあります。
Qiitaに投稿したことで、誤りや曖昧さについて指摘をいただき、より理解を深めることができました。Blogではよほど有名人でない限りこんなにコメントを貰えることはないので、Qiitaならではの良いところですね。一方、上級者から見るとQiitaにゴミを増やすな!という気持ちもあると思うので、なるべく見る人にとって有益になるように心がけないといけないですね。
- 作者: Rubyサポーターズ,すがわらまさのり,寺田玄太郎,三村益隆,近藤宇智朗,橋立友宏,関口亮一
- 出版社/メーカー: 技術評論社
- 発売日: 2013/08/10
- メディア: 大型本
- この商品を含むブログ (20件) を見る
メディア芸術データベースのラッパーGemをリファクタリングしました
これまでの流れ
- メディア芸術データベースのラッパーGemを作ってみました - Persistence
- 俺、Rubyについて全然分かってないじゃん
- 『Rubyによるデザインパターン』を読み終えて - Persistence
- イマココ
クラス設計
Before
Beforeでは、検索した結果をHashオブジェクトで返すだけという単純な機能だったので、クラス自体は多くありませんでした。それにしても、ComicがHttpBaseを継承しているのは不自然極まりないです。委譲でしょ、委譲。
After
Afterでは、検索した結果をその要素のオブジェクト(例えば、Comicを検索した場合はComicオブジェクト)の配列で返すようにしました。これにより、関連する項目(例えば、Comicの著者の詳細情報)を取りたい時に、利用者はidを使って再度検索する必要がなくなり、メソッドチェーンで取り出せるようになりました。
パターン
次に、意識したパターンについて解説します。
Builderパターン
Builderパターンは、次のようなパターンでした。
複雑なコンポーネントの組み立てを簡単に使えるようにするとともに、内部ロジックを隠蔽する。また、コンポーネントの組み立て方に誤りはないか、不足はないかなどのチェックを設けることもできる。
このGemではコンポーネント(クラス)の組み立てはありませんが、検索条件がたくさんありますので、検索条件を設定するためのクラス(SearchOptionBuilder)を作りました。これにより、利用者はどんな検索条件があるかは.methodsを見れば分かりますし、.buildメソッドは検索条件の必須項目をチェックしてから検索クラス(Search)が使うオブジェクトに整形して渡すことができます。
Template Methodパターン
Template Methodパターンは、次のようなパターンでした。
処理全体の流れは同じだが、一部が異なる処理が複数ある場合に用いる。
このGemでは、検索(Search)系の機能と、取得(Find)系の機能があります。FindはSearchで得た各要素のidを用いて詳細情報を取得するための機能です。これらはどちらも「HTTPリクエストをする」「結果を解析する」という同じ流れの処理をしており、これらをまとめた抽象クラスをRetrieveTemplateクラスとしました。Findの方はさらに共通処理が加わるため、FindTemplateを追加しました。XXXとYYYはそれぞれの機能や要素が入りますので複数あります。
Strategyパターン
Strategyパターンは、次のようなパターンでした。
全体の流れは同じである複数の処理があり、一部の処理を変更する必要がある場合。委譲にすることでクラス間の結びつきを疎結合にしたい場合。
このGemでの使い方が厳密にStrategyパターンかと言われるとちょっと自信がないですけど、委譲により解析処理を分けて必要なところで呼び出すようにしています。SearchやFindのクラスに解析処理を入れてしまうと、本来の検索するという目的とは関係のないメソッドがたくさんあって気持ち悪いんですよね。なんでFindクラスにHTML解析のメソッドがあるのって思ってしまいます。
Proxyパターン(仮想プロキシー)
Proxyパターン(仮想プロキシー)は、次のようなパターンでした。
本物のオブジェクトと同じ振る舞いをし、オブジェクトの実体が生成させるのをできるかぎり遅らせるためのプロキシーを仮想プロキシーという。
このGemでは、Searchの検索結果にその要素のオブジェクト(例えば、Comicオブジェクト)が返されますが、検索した時点ではサマリー情報しかありません。全部の情報を取るには、Findを使って詳細ページを取得する必要があります。そこで、Proxyパターンを使って、必要になった時に詳細情報を取得するようにしました。
class Component attr_reader :id def initialize(id, content = {}, retrieved = false) @id = id @content = content @retrieved = retrieved end def [](key) if @content.has_key?(key) @content[key] else unless retrieved? @content.merge!(@retriever.execute.content) @retrieved = true @content.has_key?(key) ? @content[key] : nil end end end def method_missing(name, *args) self[name.to_sym] end def content unless retrieved? @content.merge!(@retriever.execute.content) @retrieved = true end @content end def content_cache @content end private def retrieved? @retrieved end end class Comic < Component def initialize(id, content = {}, retrieved = false) super(id, content, retrieved) @retriever = FindComic.new(@id) end end # 以下同様に続く... #
例えば、SeachComicがComicオブジェクトを作るときには、idとcontent(サマリー情報)を渡します。idとcontentは検索結果を解析して取得しています。また、Comicのinitializeでは@retriverに詳細情報を検索するためのクラスを設定します。
Componentクラスの[]メソッドとmethod_missingメソッドはいずれもcontentへのアクセサです。[]メソッドの場合はcomic[:title]で取り出せますし、method_missingメソッドの場合はcomic.titleで取り出せます。method_missingは存在しないメソッドが指定された時に呼ばれるメソッドで、それをオーバーライドしています。
また、まだ取得していない詳細情報を取得しようとすると、@retrieved(詳細情報を取得したかどうか)がfalseであれば一度だけ@retriverを実行して詳細情報を取得してcontent(サマリー情報)と詳細情報をマージします。このようにして必要になった時に情報を取得するようにすることができました。
まとめ
デザインパターンを意識することで、複雑な構造を持つクラス群をわかりやすくまとめることができました。オブジェクト指向を勉強したら、その次にデザインパターンを勉強すると、より実践的なクラス設計の方法がわかると思いますのでオススメです!
- 作者: Russ Olsen,ラス・オルセン,小林健一,菅野裕,吉野雅人,山岸夢人,小島努
- 出版社/メーカー: ピアソン桐原
- 発売日: 2009/04/01
- メディア: 単行本
- 購入: 13人 クリック: 220回
- この商品を含むブログ (64件) を見る
また、作っていて気づいたことですが、このGemは他のサイトで同じことをやろうとした時でもクラス名とかパーサ部分を変えればほとんどこのまま使えます。クラスを疎結合にしたことで再利用性が高いコードになったんじゃないかと思います。
ソースはGitHubで公開していますので、ご意見をいただけたら喜びます!ブランチは「v1.0.0」です。まだmasterにはマージしていません。
RubyGemsの方はしばらくしたらアップデートします。