読者です 読者をやめる 読者になる 読者になる

PyConJP2016でiOS開発環境Pythonistaについて発表してきた

PyConJP2016でiOS開発環境Pythonistaについて発表してきました。

pycon.jp


日本の大きめのカンファレンスで発表するのは初めてだったのですが、80人強と向き合うとなかなか緊張しますね。
今回のPyConは5つの発表が平行して流れており、どのくらいの方が聞きに来てくれるかと不安だったのですが、Pythonistaに興味を持ってくださった方々が部屋の席が一杯に聴きに来てくださってとても嬉しかったです。
序盤から接続不良で画面が度々映らなかったり、動画が再生されなかったりして終始テンパってましたが、
私の発表を最後までずっと聴いてくださった皆様、本当にありがとうございました。m(_ _)m


今回発表した資料をリンクしておきます。
(スライド資料のメモ欄に色々解説書いてます)
当日は実際にコードを見ながら解説したのでその部分がまるっと抜けていますが、これからちょっとずつ画像と文章で解説を更新していきます。
そこが見たいゾッて思ってる方がいたらゴメンなさい。今月中に更新します。

docs.google.com


あと、実際に私が個人的な問題解決のために作ったiOSアプリを晒しておきます。参考になれば幸いです :)
⚠️コードの綺麗さは求めてはいけません!

アプリその1
忙しさにかまけて買った食材を賞味期限切れにしてしまう+冷蔵庫に食べ物があるのにそれを忘れて似たような食材を買ってしまう問題を解決するためのアプリ。これでだいぶ食材が無駄にならずに済んだ!
github.com

アプリその2
私の用途に特化したレシピサイトのブックマークアプリ。これを起動すると、私がよく使うレシピサイトとスーパーのチラシ情報サイトにボタン一つで飛べるようにしている。ブラウザにbookmarkでいいじゃんって思うかもしれないが、「自分専用」っていうのが結構楽しいのだ。デザインも自分で好きなように作れるし、自炊が楽しくなったよ。
ちなみにブックマーク機能を付けたいので実はまだ開発途中。
github.com


そうそう、発表後にハッシュタグ( #pycon_203 )を眺めていたら「Pythonistaを購入しました!」という方や「もう一度触ってみようと思った」という方を観測しました。日本人のPythonistaユーザが増えたぞ!とテンションが上がりました :))))
(英語のドキュメントしかないからか、まだまだ海外ユーザばかりなのです)

Pyhonistaに興味を持ってくださった方、もしかしたらこれから興味を持ってくれる方、ぜひぜひPythonistaでものづくりを楽しみましょう!!



ちなみに、発表風景の動画がuploadされているみたいなので、聴きに来れなかった方は是非いろいろな発表を見てみてください。
個人的には、

あたりが仕事でも使えそうで面白かったなーという印象でした。

www.youtube.com




そういえば、小話を一つ。

プロポーザルを出そうと思ったきっかけを聴かれたので、それについて。
実のところ最初は出すつもりはなく、「レベルの高い発表ばかりなんだろうなぁ、自分の発表ネタなんて誰も聞きたいと思わないだろうなぁ」ととてもネガティブ思考で過ごしてました。
でもある日、何気なーくPyConJPの公式ページを眺めてたら、今回のPyCon JP2016のテーマである Everyone's different, all are wonderful. が目に入りまして。
そのとき、「みんな違ってみんな良い、か。あぁ、もしかしたら人にウケるものとか考えなくて良いのかもしれない。というかそんなこと気にしなくても良いんだな。自分の好きなことや興味のある題材でやっていこう。きっと自分はその方が面白い物事を誰かに伝えられそうだな。」と思えて、その場のノリで2のプロポーザルを提出しました。
一つは査読で落ちちゃいましたが競馬の予測モデルの話。もう一つが、Pythonistaのお話でした。
おそらく、このきっかけがなかったら応募しなかっただろうな、と今思います。

PyConJP2015にも参加しましたが、昨年と違う点は、発表者になると自分のしてきたことに対し多くのフィードバックが得られますし、他人に情報を伝えるのである程度の水準まで技術を知らなければと必死になれることかな、と振り返って思いました。また、懇親会などで自分の発表ネタをきっかけに話しかけていただいたり、自分の知らない分野の話をたくさん聞けました。

スタッフの皆さま並びに参加者の方々、素晴らしいカンファレンスを本当にありがとうございました!

PyConJPは来年も開催されるようですね。技術が繋ぐ新たな出会いを思い描きつつ、その時を楽しみに待っています。

来年はどんなネタで応募しようかなぁ。。。

友人たちとisucon予習会をやってみた感想

isuconの予習会をした記録を書く。


pixivさんが社内isuconの資料を公開してくれたので、そちらの資料をもとに実際に予習会をやってみました。


友人が予習会の準備とかしてくれて、isucon概要や基本の戦略をwikiにまとめてくれたり、各チームのスコアをリアルタイムで見れる表とか作ってくれました。ありがとうございました m(_ _)m

資料:

僕はisucon初参加だったのですが、なんとなくisuconがどういうものかこのwikiのおかげで把握できました。
参加人数は10人で、1チーム2~3人にまとまるように当日にチームを4つ作ってスコアを競ってみました。
とりあえず何をやったか忘れないためにメモする。

今回学んだことをざっくりメモ

最初にやった方がいいこと
  • editorとかバージョン管理まわりとかの環境を早めに整える
    • チームの人が「/tmp/usernameをローカルと見立てて本番masterをクローン&コミットして、本番反映するときは本番masterがある場所でpullする」という素晴らしいバージョン管理方法を教えてくれて、今回はこの方法を実践してみました。メンバーがそばにいるので本番反映しますと一言声かけて実行してみて、だめならrevertするみたいにやってました。git remote add file:///tmp/username みたいなことをするという発想が自分にとっては新しくて、感動しました。
    • debianvimが入っていなくて、しかもapt-get updateしないとvimが入らないという状況だったので、最初に手に馴染んだエディタを入れるための方法を調べておいたほうがいいですね。ちなみに僕はvimを入れるためにカジュアルにupdateしてしまいましたが、updateすると今まで動いていたものが急に使えなくなるという状況になることがあるみたいなので、その辺りの知見があれば心強いですね..。
  • 頻繁に使うコマンドは何かでまとめて管理しておく (今回チームメンバーの人がMakefileをささっと作ってくれました)
    • 後半になるとコマンドのtypeミスが多くなるから、とチームの人が作ってくれました。これは初期にやってくれててとても助かりました。
  • コマンド補完を使えるようにする
    • 最初はtabで補完効かなくて不便だったので、apt-get install bash-completion して使えるようにしました。手馴れたもの以外のコマンドのオプションとかいちいち覚えていられないので..。
  • nginx, mysql, アプリケーションのログを出すようにする
    • slow_query とか便利でした
  • ログを解析するためのツールを導入して負荷が高いところを見てみる(みんなはkataribe, ALPとか使ってた)
  • index貼ってあるか確認してみる
    • 他のチームはindexを貼ってみて一気に2万とかスコア上がってました。相乗効果はアプリのチューニング次第だと思うんですが、早めに試しておくべきだった。
チームで試してみたこと

ぼくはあんまり改善できなかったけど、全体的にこんな感じだったらしい

  • socket通信にする
  • sqlの発行を抑えるためにメモリにのせれるものはのせる
  • workerの調整
  • css/jsあたりをminifyしてみる
  • imageのキャッシュ
  • 最後のベンチマークとるときはログ出力を止める
isucon参加する前に身に付けたいこと
  • isuconでちゃんと使える言語を身につけておく
    • 今回はrubyを選択したのですが、構文的な部分で時間を無駄に食ったので、そういう無駄をなくすためにもそれなりに使える言語を身につけておいたほうがいいですね。
    • あと選択した言語が得意な人がいると強いですね。自分がわかってることが一番ですけども。
  • どのファイルシステム/OSが来てもそれなりに使えるようになっておく
    • 今回はdebianだったのですが、環境構築まわりで疲弊したので、本番前にテストで環境構築してみたほうが本番の精神衛生が保てるとおもう。
  • webアプリケーションのパフォーマンスを改善するための定石を知っておく・事前に実践してみる・サクッとできるまで日頃から鍛錬しておく
    • 定石を知らないと最低限何をすべきかもわからない
    • 定石を知っていても実際どうやるかが頭に入っていなければググる時間が増え、大してパフォーマンス改善できずに試合終了する
    • ちょっとググるだけで問題解決できても素早くできないと他の作業にリソース振れないので日頃の鍛錬大事
チームでやる場合に気をつけたほうがいいなと思ったこと
  • バージョン管理をどうするか事前に決めておく
    • 多分それぞれの楽な方法を持っていると思うんですけど、当日試合がスタートしてからなんとなくで決めると、その決めた管理方法に慣れてる人とそうでない人で作業に差が出るので、可能なら先に打ち合わせして決めたほうがよいかなと感じた。
    • あと、まっさらな開発環境更の整備をどこまで時間をかけるかも事前に相談して決めておくといいですね。環境構築のためのshをdropboxに配置しておき、当日はそれを実行すれば環境が整うようにしておくと消耗しなくて済みそうです。
  • 参加意識とが同じレベルの人とやった方が良さそうな感じがあった
    • 今回、私は「とりあえずやってみるぞ」という気持ちで予習会に参加したのですが、おそらくチームの人はそうではなかった様子で、途中で足を引っ張ってしまったあたりから今後どうすれば相手の迷惑にならないのだろうと考えていて思うように作業できなかったので、まずは本番では同じ意識レベルの人と組んで、「いろいろダメなところがあったけどisuconに参加してみて楽しかったね」で終われる人と組むといいのかなと思いました。
  • 技術レベルが近い人と組むか、それなりにwebサービスのパフォーマンス改善の知識をつけてから参加したほうがいい感じがした
    • isucon初ということもあったのですが、僕が何をするとパフォーマンス改善するかを考えて試そうかなと思った時には経験者さんがガガーッと色々やっていて、その頃には下手にコード触ると逆に迷惑になるみたいな状況になり、相手のパフォーマンスとか精神的な部分にも負荷をかけてしまっていて、後半は僕はいないほうが良いのではという感じになったので、そうにならないためにも改善の知識を身につけてからやったほうがいいなと感じました。
全体的な感想
  • 第一に、体調万全でやる。体調が良くないとイライラしたり集中が続かないので、スムーズに問題解決ができなくなる...。
  • isucon予習会の前にしっかり事前調査しておけば少しは僕もマシな作業ができたかなと反省。
  • 試したいこといくつかあったけど今回できなかったのが悔しかったので、個人的にやってみる。なるべく足引っ張らないように最初に一人で似たようなことを試しておいたほうが良かったなと反省。後半、参加しないで後ろからみてた方が良かったかな、ってちょっと思った。
  • rubyを全く書けなくなっていて自分でも愕然としたのでredmineいじりの練習がてらruby触ろうと思います...本当にだめだめだった
  • プロファイラとかツール周りの知識を一通り自分の中で蓄えておきたいなと思った。そもそもrubyのプロファイラって何使えばいいの?みたいになって死んだ。
  • チームで苦しんだ点としてsinatraアプリの簡単なデバッグ方法がわからなかったんだけど、試合終了してから簡単にできることが判明して死んだ。ちゃんと添付資料読もう...。
  • 辛い気持ちになって嫌な体験にしないためにも本番は気楽にやりたいし、そういう空気になるようにしたい
  • 作業分担というか、二人でやるならインフラとアプリケーションで分けても良かったかもしれない。コンフリクトが発生しないような切り分けを最初に決めて、あとはひたすら担当の作業をするというほうが効率が良かったのかもしれないと今日やってみて思いました。
  • そんなに時間を気にしてやってなかったのでいつの間にか残り1hとかで焦ったので、タイマーとかで時間管理した方が良いですね..結構焦る。


雑にメモしたけど、まだまだ書いてない知見が結構あった(いっぺんに書くと疲れるし多すぎるので別のメモに書く)。
こういうの初めてで、楽しかったです。とても良い経験になりました。
予習会を主催してくれた人たちや参加者の皆、そしてチームメンバー、ありがとうございました!

Domain Driven Design Quickly Online を読んでいく。 その4

Domain Driven Design Quickly Online を読んでいく。 その1 - 僕とコードとブルーハワイ
Domain Driven Design Quickly Online を読んでいく。 その2 - 僕とコードとブルーハワイ
Domain Driven Design Quickly Online を読んでいく。 その3 - 僕とコードとブルーハワイ
の続き。


読んでいる本
www.infoq.com


今回は「第4章 リファクタリングのためのさらに深い洞察」をまとめる。


継続的なリファクタリング

前回は、より良いモデルの作るための姿勢やパターンをまとめた。
今回は、リファクタリングのお話。


リファクタリングとは、アプリケーション動作を変えずにコードの再設計をして改善する作業。

コードのリファクタリングは大事だが、設計段階でのリファクタリングはもっと重要。
設計はモデルの本質を作る作業なので、ドメインとモデルの関係を整理できれば、コードを読むだけでモデルの全体を把握できたりドメインの存在理由がわかるようになる。それに、設計内容は結局コードにも影響してくるため、設計段階での深い考察が重要となってくる。

鍵となる概念を明らかにする

リファクタリングは小さな改善の積み重ね。

ドメインについての深い知識に基づいて、新しい概念や抽象を付け加え、設計の考察を繰り返してより深いモデルにしていく。この作業が小さな改善となる。
これを積み重ねていくと、あるときブレイクスルーが起こり、モデルの見方が変わる。

潜在する新しい概念を見つけるコツ:

  • モデリングや設計時に使われる言葉に耳を傾ける、つまりユビキタス言語の構築作業をする。構築されたユビキタス言語から概念をあぶり出す。
  • 設計が曖昧な部分を見つけて、足りない概念がないかを探して、設計に反映してみる。
  • ドメイン構築の際に発生したドメインに対する主張の矛盾を解消する。矛盾の原因は、同じものを別の視点から見ていたり単なる説明不足という場合がある。これを解消することて重要な概念の発見につながるかもしれない。
  • 書籍からドメインについて学ぶ


明確になっていると役に立つ概念:

  • 制約
    • 制約とは不変性を表す方法
    • もしある概念に制約入れてそれをコードとして書く場合、概念の表現と制約の評価は別のメソッドにしておく方が良い。制約の評価部分のコードを外出しして、概念側ではそのコードを呼び出すという構成。こうすると、制約が明確に表現できるし、制約が増えてもロジックの組み込みが簡単だよねという話。
  • プロセス
    • 手続きによって表現されるものだが、DDDはオブジェクト指向を元にして考えるので、振る舞いを見つけないといけない。つまり、サービスを使う。プロセスをカプセル化して、ストラテジパターンを使う。
    • プロセスがユビキタス言語に含まれているなら明確に実装する必要がある。
  • 仕様
    • 仕様とはオブジェクトが条件を満たしているかどうか検証する時に使う
    • 例えばbool値で検証できるものが一つなら簡単だが、検証のルールが増えるにつれてオプジェクトが肥大化する。そこで仕様のリファクタリングをする。
    • 大きくなったルールは、一つの専用のオブジェクトにカプセル化してまとめる。とにかく、いろんなオブジェクトにルールが散らばらないようにする。
    • 単純なルールの集まりをオブジェクトにまとめることで、ルールの検証と追加が容易になるし、コードを読むだけで仕様が把握できる。

まとめというか感想

「自動化されたテストは、システムがデグレしてないか・機能が変更されていないか等をチェックするのに役立つ」というような内容あったんだけど、機能が変更されてないけどパフォーマンス的にはデグレってるというのに気づけるようなテストかけてるかな自分、というのが気になった。
要は、システムの要点を洗い出す力があるかどうかという話なんだけど。
仕様が明確ならばテストを書く時にあまり迷わないけど、迷う時は、仕様が曖昧か、ただ単に自分が仕様を正しく理解できていないということになるのだろうなと思う。

Domain Driven Design Quickly Online を読んでいく。 その3

Domain Driven Design Quickly Online を読んでいく。 その1 - 僕とコードとブルーハワイ
Domain Driven Design Quickly Online を読んでいく。 その2 - 僕とコードとブルーハワイ
の続き。


読んでいる本
www.infoq.com


今回は第三章をまとめる。

前章の振り返り

  • 業務ドメインを中心にしてとらえたソフトウェア開発手法の説明をしていた。
  • 顧客とのヒアリングでドメインを洗い出しするときや、ユビキタス言語を作っていく過程とか作成のポイントとか。
  • ユビキタス言語:ソフトウェア開発者とドメイン専門家とのコミュニケーションを楽にするもの・モデルに取り込むべきドメインの中心概念の発見にも役立つ

モデル駆動設計

モデルをコードとして実装してく作業で重要なのは、簡単かつ正確にコードへ落とし込めるモデルの選定。おすすめの設計手法に「分析モデル」と呼ばれるものがある。分析モデルとは、雑にいうと業務ドメインを分析した結果。

分析モデルを作り上げていく上で発生しうる問題:
  • アナリストが予見できなかった問題がモデルに含まれていた場合、開発者はコードへ落とし込むときに独自の決断をして、設計されたモデルとかけ離れた実装を余儀なくされることがあるかもしれない。
  • モデルとコードの乖離が広がる・モデルの情報が欠損する
より良いモデル作成のためのポイント:
  • アナリストとソフトウェア開発者は積極的にそれぞれが持つドメインの知識を共有していく必要がある。開発者もモデリング段階から参加して、ソフトウェアを正確に表現するモデルを作っていこう。
  • 実装とモデルを強く結びつける。
  • コードの変更=モデルの変更を自覚すること。
  • ドメインモデルから設計に使用される用語抜き出し、モデルの要素に責務を割り当てること


結局のところアナリスト、ソフトウェア開発者の持つドメインの知識を共有する場がないと良いモデルを作れないしモデルをうまくコードへ落とし込めないので、ドメインからモデルが作られていく過程をちゃんと共有する仕組みを作りましょう、という話。

レイヤーアーキテクチャ

ビジネスロジックが他のレイヤに混ざるとそのレイヤの変更に引っ張られる形でビジネスロジックが変異してしまったり、全体的な修正を強いられるので大変。
なので、レイヤ分割し、下位のレイヤだけに依存するレイヤの設計が求められる。
つまり、UI,アプリケーション、ドメイン、インフラなどの各レイヤの責務を明確にまとめることで、変更の管理をしやすくしていこうぜ、という話。

  • UI・・・ユーザが情報の入出力ができる部分。
  • アプリケーションレイヤ・・・アプリケーションの活動を調整するレイヤ。ビジネスロジックを含まない。
  • ドメインレイヤ・・・ドメイン情報を含む。心臓。ビジネスオブジェクトを保持する。
  • インフラストラクチャレイヤ・・・他のすべてのレイヤを補助する。ビジネスオブジェクトの永続化を担う。

エンティティ

エンティティとは、雑にいうと一意性。現実の例で言うと、マイナンバーがエンティティにあたる。DB主キーもそう。ドメインモデルにおいて重要なオブジェクト。

エンティティの重要性としては、以下の一文から読み取れる。

重要なのは、システムが一意性の異なるオブジェクトを簡単に区別できることであり、
一意性を保証する属性や振る舞いが同じであれば、そのオブジェクト同士が同
一だと判別できることです。そうでないと、システム全体が台無しになるかも
しれません。

バリューオブジェクト

オブジェクトをエンティティとして作成する場合の注意点として、あるオブジェクトのインスタンスが大量に作成されるとシステムのパフォーマンス低下になるというのが挙げられる。
本書の例だと、Customerオブジェクトは再利用できないため、顧客がいる分だけインスタンスが生成されますよね、とある。

ある属性を含むオブジェクトを識別することよりも、どのような属性を含むかに関心がある場合は、ドメインのひとつの側面を表現するためのオブジェクトであるため、一意性の保証は必要ない。
このようなオブジェクトをバリューオブジェクトとよぶ。
エンティティを見つけ、そのほかをバリューオブジェクトと定義すると設計は単純になる。

バリューオブジェクトは共有可能なら不変でなければならない。他のオブジェクトが必要とする場合は、値だけを渡すか、バリューオブジェクトをコピーしたものを渡すこと。
なぜ不変でなければならないかという話は、以下の説明で納得した(というか当たり前のことでした)。

変更できるオブジェクトを共有するとどうなるのか想像してみましょう。

例えば、航空予約システムではそれぞれのフライトを表すオブジェクトを作成します。ある顧客がある目的地へのフライトを予約したとします。
もうひとりの顧客が同じフライトを予約しようとします。このときシステムはフライトコードを保持するオブジェクトを再利用します。同じフライトを予約しようとしたからです。
そうしているうちに、顧客は考えを変えて、違うフライトを予約します。このときシステムはフライトコードを変更してしまいます。変更ができるオブジェクトだからです。
その結果、最初の顧客のフライトコードまで一緒に変更されてしまいます。

サービス

動詞は適切な名詞と関連し、オブジェクトの振るまいの一部になる。
オブジェクト指向言語ではドメインに属する振る舞いでも何らかのオブジェクトに属さなければならない。振る舞いは必ずなんらかのオブジェクトに属する。
でも、エンティティやバリューオブジェクトに含めるには的確ではないような、振る舞いがいくつかある。
こういったものをサービスと呼ぶ。


サービスの特徴:

1. サービスとして作成される操作はドメインの概念をあらわしているが、エ
ンティティやバリューオブジェクトに含めると違和感がある。
2. サービスとして作成される操作はドメイン内の他のオブジェクトから参照
される。
3. サービスとして作成される操作は状態をもたない。

サービスは独立したインターフェースとしてモデルに追加し、ドメインモデルの言語を使って定義し、処理の名前もユビキタス言語に含まれなければなりません。

サービスは内部に状態を保持せず、単純に機能だけを提供するものというイメージ。
個人的には、サービスは特定のエンティティやバリューオブジェクトのための機能をまとめるもの、という説明が一番しっくりきた。


モジュール

モジュールは雑にいうとドメインの集まり。
モジュールの各部分が同じデータを操作する場合は通信的凝集になり、モジュール全体にまたがってひとつのうまく定義されたタスクを実行する場合は機能的凝集になる。

ポイント:
- モジュール同士は疎結合にする。
- モジュールへはインターフェースにアクセスさせるようにする。
- モジュール名はユビキタス言語からつける、ドメイン内部に対する洞察を反映するため。
- モジュールの役割は固定、中身は柔軟に。すると設計ミスが見つかった時に修正しやすくなる。


ドメインオブジェクトのライフサイクルを管理するための3つのパターン

アグリゲート

オブジェクトの所有権と境界を定義するのに使うパターン。

特徴:

  • 関連するオブジェクトの集まり(エンティティとバリューオブジェクト)で、データの変更について一括して扱うことができる。
  • アグリゲートの外部からアクセスできる唯一のオブジェクトはひとつのルート(エンティティ)だけ。
  • アグリゲート内部のオブジェクトは互いに参照を持つことができるが、外部のオブジェクトはルートの参照しか保持できない。
  • ルートが削除されメモリ上からも取り除かれた場合、アグリゲート内の他のオブジェクトも削除される。

つまり、アグリゲートという壁を作ってやって、アクセスできるオブジェクトをルートだけに制限することで、不用意なオブジェクトの操作を防ぐ(不変性の維持)、という感じ。
ていうか関連オブジェクト群のカプセル化

データベースのトランザクションはデータの完全性を保証する上でとても重要な役割を果たしますが、もっと望ましいのはデータの一貫性についての問題をモデル内で直接解決することです。

ファクトリ

ファクトリとは、オブジェクト作成のための知識(というか必要な操作群)のカプセル化をするパターンのこと。やってることは、factory_boyのイメージと同じかなぁ。

特徴:

  • アグリゲートに含まれるすべてのオブジェクトを作成するファクトリをつくることで、不変性を保つ。
  • バリューオブジェクトはあとから変更できないのでファクトリ適用時にすべての属性を有効な値に初期化する必要がある。適切に生成できない場合は例外を発生させて無効な値が返らないようにすること。

リポジトリ

まず背景となる問題について。
アグリゲートのルートへバリューオブジェクトのアクセスを要求すると、クライアント側でルートの参照を保持しないといけない。オブジェクトはもともと保持しなくてもいいかもしれないオブジェクトへの参照を保持しなければならず、オブジェクト間の結合が強くなる。
バリューオブジェクトならエンティティの関連をたどりDBから直接アクセスできるけど設計に悪影響を及ぼす。

以下のような悪影響がある:

  • ドメイン全体にデータベースへアクセスするコードがまき散らされ、ドメインモデルが汚くなる。
  • 本来はドメインの概念だけを扱えばいいのに、インフラストラクチャに対する細かな処理をしないといけなくなる。
  • DBの変更をした場合、それにひきづられるようにドメインモデル内にばらまかれたデータアクセスのコードを全て修正することになる。(あー、身に覚えが...)
  • DBに直接アクセスしてオブジェクトを取得すると、クライアントは取得したオブジェクトをアグリゲート内に戻せる。つまり、アグリゲートのカプセル化が破綻する。
  • ドメインにあるはずのロジックがクライアント側のコードに浸透すると、ドメインレイヤが薄くなり、ドメインレイヤとドメインモデルの関連性がなくなる。ドメインモデルとはなんだったのか、という感じになる。

上記解決方法:

  • リポジトリパターン(オブジェクトの参照を取得するのに必要なロジックを全てカプセル化するためのパターン)」を使う。
    • オブジェクトをリポジトリに保存 -> クライアントはリポジトリにオブジェクトを要求する。DBのオブジェクトとクライアントとの仲介役みたいなもの。
    • リポジトリがオブジェクトを持っていない場合は、リポジトリがDBからオブジェクトを取得する
    • オブジェクトのdelete/saveなどの問い合わせ処理をカプセル化する。
    • リポジトリに直接アクセスできるのはアグリゲートのルートだけにすること。そして、オブジェクトの操作はリポジトリに委任すること。
  • 取得条件を仕様として定義する。
    • ファクトリは”新規”オブジェクト作成の管理、リポジトリは”既存”オブジェクトの管理という関係がある。つまり、オブジェクトはコンストラクタを使って作成されるか、ファクトリを通じて作成される。
    • ファクトリはドメインの要素しか持っていないが、リポジトリはインフラストラクチャ(例えばDB)と関連がある。

第3章のまとめ

  • 実装とモデルを強く結びつけるためには、アナリストとソフトウェア開発者は積極的にそれぞれが持つドメインの知識を共有していこう。
  • オブジェクト指向を活用しよう。
  • 各レイヤアーキテクチャの役割を明確にしよう
  • エンティティは一意性を表現し、バリューオブジェクトはエンティティから辿れる不変かつ共有可能なオブジェクト
  • どのオブジェクトにも属さないが、意味のある振る舞い(インターフェイス)をサービスと呼ぶ
  • モジュールはドメインの集合
  • ドメインオブジェクトのライフサイクルを管理するための3つのパターンがある
    • アグリゲート: オブジェクトの所有権と境界を定義するのに使う。アグリゲートの外部からはルート(エンティティ)からしかアクセスできないようにし、オブジェクトの不変性の維持を保証する。
    • ファクトリ: オブジェクト作成のための一連の操作をカプセル化するもの
    • リポジトリ: ドメインでやることをクライアントに混ぜないために、クライアントとインフラストラクチャの間に入ってオブジェクトの問い合わせをしてくれたりするやつ

ThinkPad X220i メモリ増設した

Chromeでタブ開きまくったりメモリを結構使うようなコード書きたいなーとなると4Gじゃ足りなかったので8Gに増設した。

メモリ選定

まずはX220iの仕様を確認する。
以下の仕様書によると「DDR3(動作クロック 1333MHz)」とのことなので、これに合ったメモリを探す。

2013年3月以前のThinkPad製品仕様表

ちなみに、最近のマシンだとクロック数が多少合わなくても使えるものがあるらしいと教わった。どういう制御をしているのだろう。

今回は値段、性能、手元に届く速さからAmazonで以下のメモリを買った。

CFD販売 ノートPC用メモリ PC-10600(DDR3-1333) 4GB×2枚 204pin SO-DIMM (無期限保証)(Panramシリーズ) W3N1333PS-4G

5000円未満で買えるんだよね。これで4G増えるなんて、安いなぁ...。


メモリの脱着
ついき

ThinkPadをひっくり返したら、ネジを外してメモリを入れ替えるだけ。
メモリを押さえている銀色ホルダーを外側に広げて外すとメモリが斜めになった状態で上にひょこっとでてきて取れやすくなる。
メモリを差し替えたら、ホルダーに収まるようにしまってあげるだけ。

f:id:equal_001:20160727000733j:plain

起動して、ちゃんとメモリが増えてることを確認した。
7.7Gって書いてあるけど、残りの0.3Gはどこへ行ってしまったんだろう。MacとかWindowsだときっちり8Gと表示されてた気がするんだけれど。OSで少し食ってる部分を差し引かれてるのかな。
f:id:equal_001:20160727001155j:plain

起動直後にメモリの使用状態を見てみた様子。
f:id:equal_001:20160727001235j:plain
710Mくらい使ってる。こっちがOSで食ってる部分なのかなー。psで詳細調べるとかしないとわからなさそう。Linux のメモリー管理について詳しくないので勉強が必要だ。



追記

くろはこ先生から「なぜ8GBを一枚ではなく4GBを二枚買ったのか」という質問が飛んで来たのでここにも書いておくと、デュアルチャネルで動作させてちょっとでも処理速度上がればいいなーと思ったからでした。多分そんなに大差無いと思うけども。

8GB+2GBで10GBでも動くらしいのですが、もう一度仕様書を見返してみたところ以下のことが書いてありました。

主記憶(RAM)容量(標準/最大) ※5 2GB(2GB*1) (PC3-10600 DDR3 SDRAM)/8GB
※5 メモリーを最大まで拡張されるには、5GBメモリーを2枚装着する必要があります。本体、あるいはOSがサポートする最大容量を超えての仕様はできません。

最大容量が8GBなのは確認してたけど※5のところは見てなかったよ...。あぶないところだったぜ。

Lenovo ThinkPad X220i に Ubuntu16.04 LTS Desktop を入れた

最近は個人ではMacbook Proを使用していたのだけど、せっかくそこそこ良いThink Padを放置するのも宝の持ち腐れだと思い、Ubintu16.04 LTS Desktop を入れることにした。

中にはWindows7が入っていたのだけど、正直使わないのでまるっと削除してすべてをUbuntu色に染めた。


以下、使えるようにするまでの手順のメモ。



UbuntuライブメディアをUSBで作成する

用意するもの:PC, フォーマットしてもいいUSB (2Gあれば十分)

Ubuntuのインストール

  • マシンの再起動をして、BIOSからUSBデバイスを選択する。(私のThinkPadの場合、Enter押したらいけた)
  • 選択するとubuntuのインストールが始まって、セットアップ画面になるので、タイムゾーンとかもろもろ設定していく。セットアップ画面しっかりしてて綺麗。ubuntuめっちゃ頑張ってるなーという印象受けた。

日本語の設定

デフォルトだと日本語が使えなかったので設定変更する必要があった。幸いubuntuのセットアップ時にmozcなど日本語入力に必要なドライバが入ってきていたので、そのあたりは苦労しなかった。

  • desktop右上にあるキーボードアイコン -> 設定 -> 入力メソッドの設定 へ飛ぶ
  • 以下画像左下にあるプラスボタンを押したあと、入力メソッドを検索できるフォームにmozcと入力する
  • mozcを入力メソッドにしてメソッド追加したら、最初から入ってた入力メソッド「キーボード - 日本語」よりも上に持っていく
  • PC再起動する。すると英字/日本語の切り替えができて日本語入力可能になっている


f:id:equal_001:20160718192846p:plain

Chromeを使えるようにする

デフォルトだとFirefoxが入っているのだけど、個人的にChromeが使いたかったので入れた。

$ sudo apt install libappindicator1
$ sudo dpkg -i ダウンロード/google-chrome-stable_current_amd64.deb
  • /opt/google/chrome/ にchrome起動ファイルがあるので実行+Launcherに追加しとく

感想

  • 思ったよりメモリ消費しない。今使ってるノートPCのメモリが4Gなんだけど変に遅くなったりしないしサクサク動作してくれる。chromeにタブ5つくらい開いて、youtubeとか見ても2Gいくかいかないか。ニコ動はもうちょい食うけど許容範囲内。
  • Linuxファイルシステムが普通に使えて最高
  • 充電はMacより長持ちしないのがちょっとつらい
  • ThinkPad軽いなぁ...
  • Kindle for Desktopを頑張って入れないといけないのがちょいと面倒(Windows上なら動くらしいが、Linux版のは無いらしい)

Domain Driven Design Quickly Online を読んでいく。 その2

Domain Driven Design Quickly Online を読んでいく。 その1 - 僕とコードとブルーハワイ
の続き。

読んでいる本
www.infoq.com

ユビキタス言語

ユビキタス言語とは、ドメインの専門家とソフトウェアの専門家の両者が正しくドメインを理解/表現するための共通言語のこと、と捉えた。

例えば、ドメインモデルの作成の過程で、ドメインの専門家は自己の専門範囲である業務の専門用語を使い、ソフトウェアの専門はプログラミング脳でドメインを捉えてたり技術的な専門用語などで説明してしまったりする場合、両者の間で共通の認識を得ないまま、ドメインモデルを構築してしまう。
そうなってしまうと、

ドメインについての正しい表現は記録されず適切でない表現の中に埋もれてしまったり、
相手がわかるように簡単な(と思っている)言葉で説明することに消耗したり、
専門分野を理解しなければいけないがためにまた別の今回限りな専門用語を生み出してしまったり

する。
ドメインモデルの構築、そして設計が困難になってしまう。
これを回避するために、ユビキタス言語(共通言語)を使っていこうね、というお話。

では、ユビキタス言語(共通言語)はどのように構築するか。

監視システムの例を読むと、
ユビキタス言語というものはこれだ!と言って名付けるものではなく、ドメインモデルを構築していく過程のお互いの会話から発せられた、ある程度まとまった概念を持つ単語の持つ意味の認識をすり合わせていく、という作業に考えられた。
そして、すり合わせをした結果できた概念(ユビキタス言語で表現できるもの)をドメインモデルに反映してみて、齟齬をなくしていく、というのが理想なのだろう。

ちなみにユビキタス言語を構築することで得られるコードを書くときの恩恵はこの文章に集約されていた。

ドメインモデルの概念をクラスへと実装することで、ドメインモデルとコードを対応づけることができます。そして、それは共通言語とコードを対応づけることでもあります。しっかり対応づけられていると、コードが読みやすくなり、コードからドメインモデルを再作成できるようになるのでとても役に立ちます。

ふむふむ。
今の仕事でユビキタス言語っぽいものがwikiにまとまっていたりしていて、コードにもそれらが反映されているんだなーというのがなんとなくわかって、それって仕様把握に一役買っていて私は結構助かった記憶がある。
ただ、この本にも書いてあったけどユビキタス言語はどんどん変化していくものだからwikiと同期しないといけないよねという話がある。
それを怠ると、なんでこの名称になったんだっけどか、この部分何に使ってんの?もういらないやつだっけ?とかなったりして、チャットのログやチケットから経緯を追ったりしないといけなくて、結構辛くなってしまうんだよなこれが。(†戒め†



では、ユビキタス言語はどう表現すればよいのか。

UMLは、クラスやその属性、クラス間の関係を表現するのが得意です。 しかし、クラスの振る舞いや制約を表現するのは簡単ではありません。そのた め、UMLでは図のなかにメモを入れて文章で補足します。したがって、UML ではモデルについての2つの重要な側面、つまりモデルがあらわす概念の意味 とオブジェクトがするべきことを伝えられません。

UMLは全体像を把握するには良いけど、実際のところどういう働きをするの?って部分を表現するのは不得意だよねーという話。
では、「モデルがあらわす概念の意味とオブジェクト」をどう表現したら良いかというと、
この本では、モデルをあらわすクラスたちの関係やその説明文や画像などを図に起こすといいよ、と書いてある。
雑にいうと、各ドメインについて理解できるように、膨大なクラス群を適切なモデル単位の概念に集約・区切っていこう、という話だと思われる。

すなわち、ソフトウエアアーキテクト、開発者、ドメインの専門家を含む設計チームに必要なのは、作業を統一し、モデルの作成とコーディングを助ける共通言語だということです。

上記の言葉で第2章は締め括られている。
しかし、ユビキタス言語の構築は思っているより難しいところだなぁと感じる。


今日はここまで。