Kuchitama Tech Note

はてな記法がいつまでたっても覚えられないので、はてなダイアリーからマークダウンが使えるこっちに引っ越してきました。

あ”あ”あ”、画像に埋め込んだ文字がTypoしてる!そんなときはImageMagickだ!!

最近、仕事の傍らScala関西Summitの準備を進めてます。

summit.scala-kansai.org

で、ひとつのテンプレで大量の画像を作成する必要があるタスクがあって、その作業を行っていました。

作ったのは↓のような画像です。*1

f:id:kuchitama:20150718160719j:plain

このアイコンだけを差し替えたような画像を量産していたのですが、 お気づきでしょうか?

イベントのスタッフは stuff ではなく staff なんです。

時既におそく、Typoに気づいたのはすべての画像を書きだした後…

しかも、個々の編集過程が残っているわけではなくて、手元にあるのは大本のテンプレートと作成のための素材、そして大量のTypo画像…

テンプレートを直して一つ一つ画像を直そうかとも思いましたが、さすがにそれはやってられない!

ということで、コマンドラインからImageMagickを使って、まとめて画像を修正することにしました。

手順

まずは、↓のようにテンプレートのTypoを直して、差分が発生する箇所を抜き取って透過した overlayer.png を作成します。(※: 真ん中の矩形部分が切り抜かれています)

f:id:kuchitama:20150718164424p:plain

この画像が用意できたら、ImageMagickconvert コマンドを使って上書きしてやります。

$ convert typo.png fixed.png -composite ./fixed_typo.png

これで、下記のように修正された画像が出力されます!*2

f:id:kuchitama:20150718165249p:plain

このままだと、何度もコマンドを叩かないと行けないので、 xargs を使って対象の画像をまとめて出力するようにします。

xargs-I オプションを使って、任意の位置に引数を設定することができます。

というわけで、実行するコマンドはこちら

$ find -E *.png | xargs -IFILENAME convert FILENAME fixed.png ./fixed_FILENAME

これでまとめて、大量の画像に埋め込まれたTypoを修正することが出来ました。

こんな、地味にStaffが頑張ってるScala関西Summitをよろしくお願いします。

ImageMagick逆引きコマンドリファレンス

ImageMagick逆引きコマンドリファレンス

*1:実際の画像は少し違います。この画像はブログ用に作成しました

*2:イコン画像が切れているのはブログ用に適当に画像を用意したためで、イベントで使う画像はちゃんと合成されてます

Scala WebSocketでwss接続

前に作ったJankenSocketのClientでwss接続を利用するようにしました。

Scala + JettyでWebSocket Clientを実装しました - Kuchitama Tech Note

jetty websocket wss とかでググると、だいたい opensslとかkeytoolとか使って自前証明書を使う方法ばかりでるんですが、ちゃんとした証明書を使ったサーバだと別に証明書作る必要はないみたいです。

というわけで、コミットはこちら

SSLContextFactory を作ってそのまま WebSocketClientコンストラクタに渡せば大丈夫です。

ところで、まともな SSL証明書を使えるherokuは本当に便利です。

Scala界隈でDDDが大いに盛り上がったのでログをまとめましたよ-その2

昨日に引き続き、ScalaJpのgitter.imで上がったDDDの話題の続きです。

scalajp/public - Gitter

なんか、昨日の記事はてブホットエントリしたみたいで、恐縮してます。

昨日あげた2/23の話題ででDDDに関する盛り上がりは収まったかにみえたのですが、翌日、導師かとじゅんさん(@j5ik2o)がみんなの疑問に一つ一つ応えて、我々を更にDDDの世界に導いてくださいました。

実践ドメイン駆動設計 (Object Oriented Selection)

実践ドメイン駆動設計 (Object Oriented Selection)

2月24日


j5ik2o 2015年2月24日

エヴァンスのDDD本だと具体的なrepositoryの置き場所に言及されてないように見える

ドメインモデルのライフサイクルを扱うので、ドメイン層に含まれると思いますけどね。DDDSampleでもそのようになっていたはず。


j5ik2o 2015年2月24日

インフラ層はドメインAPIに依存するのでは

(DDD本に記載されている)トラディショナルなレイヤー化アーキテクチャの場合は、UI層→アプリケーション層→ドメイン層→インフラ層。UI層→インフラ層、アプリケーション層→インフラ層を推奨していますね。実践DDD本には、UI層→アプリケーション層→ドメイン層という依存方向であるが、ドメイン層にはインターフェイス(型としての)を定義し、それをアプリケーション層で実装するというパターンと、DIP(Dependency Inversion Principle)を使った場合の逆転の依存関係で実現したパターンが示されていますね。

http://www.infoq.com/jp/news/2014/11/ddd-onion-architecture

コアがアプリケーションか、ユースケースかな。ちょっとこの図だけでレイヤー表現を解釈することができないな

オニオンアーキテクチャもなんか色々反論でてて何が良いのやら……というわけで実戦DDD本が待ち遠しい今日この頃

オニオンアーキテクチャはあんまり追跡してないんですが、Hexagonal Architectureについては、実践DDD本で言及があった気がします。

Coreってどこ由来の用語なんだろう。エヴァンスのDDD本には出てこなかったような

ドメイン層: "ビジネスの状況を反映する状態はここで制御され使用されるが、それを格納するという技術的な詳細は、インフラストラクチャに移譲される" (エヴァンスのDDD本) オニオンアーキテクチャやヘキサゴナルアーキテクチャとか、DDD本にはでてこないので、一旦DDDの標準的なレイヤー構造を理解した方がいいと思いますよ


j5ik2o 2015年2月24日

実際にインフラ層とドメイン層の橋渡しをするのがリポジトリってやつですね(リポジトリ自体はこれはインフラ層に所属してるって認識でいいんだろうか)

はい。橋渡しはあってますね。リポジトリドメイン層ですね。リポジトリの責務はドメインモデルから永続化責務を分離することなので、ドメインモデルをI/Oするためのオブジェクトということになります。DDD本に記載されている、標準的なレイヤー化アーキテクチャの場合は、下のレイヤーが上のレイヤーを直接依存できないので、仮にリポジトリをインフラ層に配置した場合はこれに反することになります。


j5ik2o 2015年2月24日

かとうさんのペットストアみてたんですが、domain 層と思しき package に JDBC という word が出てきてよくわからなくなったんですよね... https://github.com/j5ik2o/spetstore/blob/master/app/com/github/j5ik2o/spetstore/domain/infrastructure/support/RepositoryOnJDBC.scala あ、これインフラ層なのか

このあたりも試行錯誤ではあるのですが、インフラ層なんですが、すべてのレイヤー(UI, アプリケーション, ドメインなど)から汎用的に利用される技術基盤としてのインフラ層と、各レイヤーだけで必要になる技術基盤とがあるようです。

たとえば、ドメイン層なのになぜJDBCとかJSONというキーワードでてくるのか?話があるのですが、どうしてもドメイン層にしか配置できないものはドメイン層内のインフラ層(言葉が悪いと思っているので、今はs/infrastructure/support/などとしています)に配置しています。


j5ik2o 2015年2月24日

「repositoryを経由することになるので分離は容易」が個人的にとても懐疑的で、ヘタすると謎に層が増えるだけで、全く使いやすくならない、というのが発生しがちな気がしている

自分も最初はこの考え方でしたが、ユビキタス言語パターンを理解するまでは。実装都合でいうと邪魔な層が増えるだけですw が、つまりトレードオフの観点なので、吉田さんの言ってることは全く正しいですが、これはチーム全体の言語を統一してドメインで会話できるようになるために払うコストなんですよね(層を挟むことでドメインモデルがどの永続化技術からも分離できて議論しやすくなるわけなので)。そのコストが払えないチームやプロダクトではそもそもDDDするべきでないと思いますねー。


xuwei-k 2015年2月24日
なるほどー、そういうことならかなり納得できます


j5ik2o 2015年2月24日
はいー


tkawachi 2015年2月24日
@j5ik2o フォローありがとうございます。 実践DDD日本語でたら読まないとなあ


j5ik2o 2015年2月24日

かとうさんも、そのあたり(層をきちんと分けるか否か?)は、パフォーマンスのチューニングのしやすさとか考えると、分けすぎてもあれだし、バランスが必要というかプロジェクト毎に考えるべき的なこと言ってた気がする(かなりうろ覚え)

そうですね。コミュケーションコストを下げるためとはいえ、層は増えますのでなんでもかんでもドメインモデル化しない( つまり重要なものだけに絞るという意)などの工夫が必要なんですよね。 一般的にはドメインモデルは、どの永続化技術にも依存しないので、SkinnyORMなどのORMで表現されるモデルとは分離します。これまでモデル、モデルと呼んでいたものは基本的にインフラ層のモデルになります。なので、Userドメイン(エンティティであり集約) <-> UserRepository(JDBC用) <-> UserTableにmapされることになります。1集約が1テーブルに対応づく場合はよいですが、1集約が複数のテーブルにマップされることもあり(ex 売り上げエンティティ<->売り上げテーブル、売り上げ明細テーブル)、実装はめっちゃ大変です(コード生成でこのあたり作れると楽なんですがねー)


j5ik2o 2015年2月24日

Dao と Repository の使い分けが気になる……。モチベーション的には同じものですよね Dao と Repository。

ここでいうDaoの定義をPofEAAのデータマッパーとすると(一般的にそうだと思うのですが)、Daoはテーブルを扱うためのオブジェクトですね。でも、RepositoryはAggregate(集約)をI/Oするためのものです(集約はドメインモデルのカテゴリとしてはエンティティになります)。そもそもドメインモデルとは、テーブルから分離している存在なので、RepositorとDaoではレイヤーが違ういますね。たとえば、売り上げエンティティは、売り上げテーブルや売り上げ詳細テーブルにマップされる場合があると考えると簡単に理解できます。当然、売り上げエンティティと売り上げテーブルが1:1ならDaoとRepository同じでは?という疑問あると思います。しかし、ドメインモデルはどの永続化技術にも依存せず様々な実装のリポジトリを使って、テーブル以外にファイルやJSON形式で保存されたりします。ネットワークの先のサーバに保存されるかもしれません。テーブルからドメインを見るのではなく、ドメインモデルからみた場合は、テーブルはエンコードの一表現にすぎませんという感じです。

みんなDDD本みてて、最初にレイヤードアーキテクチャが来るからその話が人気なのかな(想像

そうですね。和智さん曰く、2部は一番最後に読むといいらしい


j5ik2o 2015年2月24日

DaoとRepositoryの違い、Daoはデータストレージの抽象化しか志向していないのに対して、Repositoryはドメインモデルとの接続を強く意識しているというのがあるかな(DDDにおいてDaoパターン使ったら自然にRepositoryになりそう)

あと、RepositoryのI/FはRDBMSとかJDBCのコネクションとかトランザクションに依存できないのですー。そとからみたらコレクションのように動作するのがリポジトリなのでDaoとは全然違いますよー

ドメイン層で class MyEntity {...} があって、レポジトリ(インフラ層)で def findMyEntity(id: Id): MyEntity = ??? って書くとしたら、戻り値にドメイン層のクラス出てきてインフラ層がドメイン層に依存してね?って話なんですが

はい。それよくないと思います。ドメインモデルとリポジトリはI/Fも実装もドメイン層に配置することになります。


tototoshi 2015年2月24日
なるほどー

RepositoryのI/FはRDBMSとかJDBCのコネクションとかトランザクションに依存できない ということは理想的にはトランザクションの境界は Repository より下の層にすべきっていう認識で良いですか?


gakuzzzz 2015年2月24日

ここでいうDaoの定義をPofEAAのデータマッパーとすると(一般的にそうだと思うのですが)、Daoはテーブルを扱うためのオブジェクトですね。

あーなるほど。 ここの認識が異なっていた感じですね。 PofEAAのデータマッパーという意味なら理解できます。 Dao というと Data Access Object パターンの認識だったので。 一般的にはどういう認識なんだろう? Seasar界隈ではひがさんがDaoをData Access Object パターン的に説明してたような記憶がうっすらと……


gakuzzzz 2015年2月24日
トランザクションの境界をリポジトリの内側にしちゃうと現実のアプリが回らなくなるか、eventual consistency でやらざるをえなくなるので、 リポジトリドメインモデルが全てSTMモナド的なものを返してアプリケーション層でトランザクションするのかなーと思ってました。


todesking 2015年2月24日
エヴァンスのDDDでは、リポジトリトランザクション管理をしないでクライアント(アプリケーション層?)に任せることを推奨している http://tlync.hateblo.jp/entry/2013/12/12/023135


j5ik2o 2015年2月24日

エヴァンスのDDDでは、リポジトリトランザクション管理をしないでクライアント(アプリケーション層?)に任せることを推奨している http://tlync.hateblo.jp/entry/2013/12/12/023135

ですね。トランザクションの開始と終了については、アプリケーション層の責務となってましたね

Implementing DDDでは、PofEAAパターンで言うData MapperがRepositoryに近くて(どちらもドメインモデルを扱う)、それ以外(Table Module/Table Data Gateway/Active Record)がDao-likeだという解説になってました

ファウラーがいうドメインモデルって集約を意識しているのか、怪しいなと思っています。Data Mapperでは、本来集約内部でにあるオブジェクト群が外に露出していているように見受けられるので。

実践DDD本で手元に届いたらじっくり読んでみます

RepositoryのI/FはRDBMSとかJDBCのコネクションとかトランザクションに依存できない ということは理想的にはトランザクションの境界は Repository より下の層にすべきっていう認識で良いですか?

アプリケーション層ですねー


j5ik2o 2015年2月24日
https://gist.github.com/j5ik2o/973fe2fde3ba8f141bb1

Ctxなんとかできないもんかと。つらい リポジトリのI/Fは永続化技術固有の知識に依存できないのですが、どうにかしてアプリケーション層からドメイン層をまたいでコネクションやらトランザクションをインフラ層にわたさないといけないので


tsukaby 2015年2月24日
すごいレスだ・・・勉強になります。 自分が作ってるDDDっぽいようなMVCっぽいようなScala+PlayアプリもApplication層からdbのsessionを渡して行く感じで「うーん」と思っていたんですが、これはみんな思ってることなのかな。


tkawachi 2015年2月24日

AbstractRepositoryOnJDBC, EmployeeRepositoryOnJDBC は永続化の技術詳細を含むのでインフラ層という認識であってますか? それともドメイン層のなかのインフラ層、と話していたところなのかな..


j5ik2o 2015年2月24日

AbstractRepositoryOnJDBC, EmployeeRepositoryOnJDBC は永続化の技術詳細を含むのでインフラ層という認識であってますか? それともドメイン層のなかのインフラ層、と話していたところなのかな.. 大枠のレイヤーでいうと、AbstractRepositoryOnJDBC, EmployeeRepositoryOnJDBC はドメイン層ですね。インフラ層に移動しちゃうと下位層が上位層に依存することになるので。”ドメイン層の中のインフラ層”的な位置づけになるとは思います。


tkawachi 2015年2月24日
うーん、 ドメイン層 ← インフラ層 方向の依存だったら、インタフェースだけドメイン層におけば、技術詳細をインフラ層に閉じ込めることはできそうなので、そちらのほうが自然に感じるのですが、、、、


j5ik2o 2015年2月24日
"本質的な原則は、レイヤ内のどの要素も、同じレイヤの他の要素か、その「下にある」レイヤの要素にしか依存しない、ということである"なので、上下の定義によるかなと思いますね


以上が、一連のDDD関連の話題になります。

そうですね。和智さん曰く、(DDD本)2部は一番最後に読むといいらしい

そうなので、DDD本も読み返したいです。

エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)

エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)

Scala界隈でDDDが大いに盛り上がったのでログをまとめましたよ-その1

以前、ScalaJpのgitter.imでDDDについて議論が盛んに行われてたけど、いずれログが消えちゃうのがもったいなくて、ここに内容を貼付けます。

scalajp/public - Gitter

要約すると実践DDD本出たらみんなで読もうぜ。ってことで。

実践ドメイン駆動設計 (Object Oriented Selection)

実践ドメイン駆動設計 (Object Oriented Selection)

ホントは、自分のブログとかじゃなくてGistとかがいいんだろうけど、見た目を整えるのが一番楽なので、ここに掲載しておきます。 一応、最初にまとめるにいたった経緯↓


xuwei-k 2015年2月24日
gitter、無料だとログの保存期間2週間って話だったけど、実は現状全部残ってる https://gitter.im/scalajp/public/archives/2014/10/02


Kuchitama 2015年2月24日
え、そうなんですか?


xuwei-k 2015年2月24日
最低2週間を保証するだけで、残せる分は多めに残してくれるのかも?


Kuchitama 2015年2月24日
なるほど。


xuwei-k 2015年2月24日
まぁいつ消えるかわからないし、まとめるならまとめたほうがいいとは思うけど


Kuchitama 2015年2月24日
2週間以内にやりますw

2月23日

すべては @kawachi さんから始まったのであった。


tkawachi 2015年2月23日
実戦 Scala で DDD の話何回か出てきて、DDD本読まないとなあと思ってるところです。DDDのレポジトリってインフラ層ですよね。インフラ層はドメイン層に依存しないですよね。レポジトリは戻り値や引数にドメイン層のクラスを含みますよね。レポジトリはインフラ層ですよね。あれ?インフラ層がドメイン層に依存してる?となったのですが、 Scala + DDD やっている方に誤りを指摘していただきたく。


gakuzzzz 2015年2月23日
インフラ層はドメインAPIに依存するのでは


tkawachi 2015年2月23日
ドメイン層のインタフェースと実装をわけて、インフラ層はドメイン層のインタフェースに依存する形?


gakuzzzz 2015年2月23日
コア<- ドメイン <- インフラ <- アプリケーション <- プレゼンテーション 的な依存関係だったような はい、そんな感じですね。


tkawachi 2015年2月23日
インフラ層はドメイン層の下層なので、ドメイン層はインフラ層に依存していいという認識です。 ドメインAPI <- インフラ <- ドメイン <- アプリ <- UI 的な感じになるのかな?


kiris 2015年2月23日
このあたりの話ですかね

インフラストラクチャ層 - 上位のレイヤを支える一般的な技術的機能を提供する。 - これには、アプリケーションのためのメッセージ送信、ドメインのための永続化、ユーザインタフェースのためのウィジェット描画などがある


gakuzzzz 2015年2月23日
こんなイメージでした。

ドメイン駆動設計とオニオンアーキテクチャ


xuwei-k 2015年2月23日
DDD おじさんの登場が待たれる


gakuzzzz 2015年2月23日
オニオンアーキテクチャもなんか色々反論でてて何が良いのやら……というわけで実戦DDD本が待ち遠しい今日この頃


todesking 2015年2月23日
Coreってどこ由来の用語なんだろう。エヴァンスのDDD本には出てこなかったような ドメイン層: "ビジネスの状況を反映する状態はここで制御され使用されるが、それを格納するという技術的な詳細は、インフラストラクチャに移譲される" (エヴァンスのDDD本)


todesking 2015年2月23日
実際にインフラ層とドメイン層の橋渡しをするのがリポジトリってやつですね(リポジトリ自体はこれはインフラ層に所属してるって認識でいいんだろうか)


kiris 2015年2月23日
リポジトリドメイン言語で記述しない(コレクションとして振る舞う)ので、インフラ層に所属しているという認識でよかったかと


tkawachi 2015年2月23日
かとうさんのペットストアみてたんですが、domain 層と思しき package に JDBC という word が出てきてよくわからなくなったんですよね... https://github.com/j5ik2o/spetstore/blob/master/app/com/github/j5ik2o/spetstore/domain/infrastructure/support/RepositoryOnJDBC.scala あ、これインフラ層なのか


todesking 2015年2月23日
domain.{infra, lifecycle, model}


daiksy 2015年2月23日
実戦DDD本超読みたい


gakuzzzz 2015年2月23日
かとうさんのペットストア、domain と並列した infrastructure と domain配下の infrastructure がありますね。どう使い分けてるんだろう?


tkawachi 2015年2月23日
それ、僕も疑問です… 挙げていただいたオニオンアーキテクチャの説明ではインフラ層が最上位に見えますね。。 DDD本ではインフラ層が最下層なので、混乱してしまう


todesking 2015年2月23日

インフラストラクチャは最外層にあり,データベースやユーザインターフェース,外部サービスなど,さまざまなテクノロジ用のアダプタを含んでいる

DDDとは定義が違うっぽいですね


tkawachi 2015年2月23日
DDDのインフラ

これには、アプリケーションのためのメッセージ送信、ドメインのための永続化、ユーザインタフェースのためのウィジェット描画などがある

と違いがわからないなあ


todesking 2015年2月23日
あっ、本当だ。同じことを言っているんだろうか。 オニオンアーキテクチャの提唱者(?)の図を見るとInfoQと違ってて混乱してきた…… http://jeffreypalermo.com/blog/the-onion-architecture-part-1/


tsukaby 2015年2月23日
お、なんだか興味深い議論が。自分もかわちさんと同じようにDDDのinfraまわり疑問でした。 domainはinfraに依存するからinfra層ってそうそう簡単に取り替えできないような気も・・・しかしDDDよく知らんしなー・・・と思いながらかとうさんの発表聞いてました。


gakuzzzz 2015年2月23日
うお、InfoQと元記事の図だいぶ違いますね……


todesking 2015年2月23日

domainはinfraに依存するからinfra層ってそうそう簡単に取り替えできないような気も

domain全体がinfraにベッタリ依存するわけではなく、repositoryを経由することになるので分離は容易だと思われます (ただし、リポジトリAPI設計はインフラ層の実装の影響を受けるため、RDBをKVSに差し替えるレベルの変更が入った場合は影響を免れないでしょう)


xuwei-k 2015年2月23日
本当に差し替え可能にするなら、こうすべきだろ http://d.hatena.ne.jp/xuwei/20140703/1404356954 って以前書いたら、べつにDDDではそれは必須じゃないといわれた 「repositoryを経由することになるので分離は容易」が個人的にとても懐疑的で、ヘタすると謎に層が増えるだけで、全く使いやすくならない、というのが発生しがちな気がしている まぁ全部ごちゃまぜで密結合よりはマシだろうけど


tsukaby 2015年2月23日
なるほど、ありがとうございます。勉強になります。


todesking 2015年2月23日
実践者の意見だ(´・_・`)


xuwei-k 2015年2月23日
かとうさんも、そのあたり(層をきちんと分けるか否か?)は、パフォーマンスのチューニングのしやすさとか考えると、分けすぎてもあれだし、バランスが必要というかプロジェクト毎に考えるべき的なこと言ってた気がする(かなりうろ覚え)


taisukeoe 2015年2月23日

(ただし、リポジトリAPI設計はインフラ層の実装の影響を受けるため、RDBをKVSに差し替えるレベルの変更が入った場合は影響を免れないでしょう)

あれ、リポジトリAPIはデータソースの種類からの影響は受けるべきではない、という認識でいましたが、ここについて何かソースってありますか?

「内部で何をしていても、外部からはコレクションのように見える」など、46スライド目〜を参照してます。 http://www.slideshare.net/j5ik2o/scala-with-ddd/46


gakuzzzz 2015年2月23日
Dao と Repository の使い分けが気になる……。モチベーション的には同じものですよね Dao と Repository。


taisukeoe 2015年2月23日
各DAOを抽象化して共通インターフェース化したものがRepository、なのかなぁ と思っておりました


todesking 2015年2月23日
エヴァンスDDD6章、リポジトリ - "下層にある技術によって、モデリングの選択肢が制限されることがある" あたりです


tototoshi 2015年2月23日
Repositoryという概念は別にデータソースに依存していないけれど、実際は Repository=Dao になることが多い、って感じじゃないですかね。


gakuzzzz 2015年2月23日
Dao も永続化にDB使うかファイル使うかメモリ使うかなどの実装を隠蔽するための抽象化インターフェイスですよね その辺の認識が異なるのか……?


todesking 2015年2月23日
例えばあるDBでは効率的にクエリできる操作が別のDBではそうではないということが考えられ、それはリポジトリAPI設計に影響を及ぼさざるをえない


tkawachi 2015年2月23日
http://labs.gree.jp/blog/2013/12/9354/ のコラムではDAOをRDBMSインターフェイスと捉えてますね

http://labs.gree.jp/blog/2013/12/9354/

そういう意味でのDAOならrepositoryとは違いそう。DAOをrepository的な意味合いで使う場合もありますよね


taisukeoe 2015年2月23日
ソースありがとうございます。確かに思いっきり「例えば、関係データベースを使うと、深い複合オブジェクトの構造に事実上の制限が設けられるかもしれない」って書いてますね あ、「事実上の〜かもしれない」だから理想的にはAPI設計に影響を与えない方が良いが、パフォーマンス上影響を与えざるを得ない場合がある、という理解でいいのかな


todesking 2015年2月23日
6章、「関係データベースに合わせてオブジェクトを設計する」という項があった。 理想的にはインフラを考慮せずドメインモデルを設計したいんだけど、パフォーマンスやO/Rマッピング時のことを考えると妥協は必要だということでしょうね。


taisukeoe 2015年2月23日
あ、すみません「各DAOを抽象化」ではなくDAO以外のデータソース(外部API呼び出しとか)を含めて抽象化したインターフェース、の意でした だからDAO以外のデータソースがない場合は、DAO=Repositoryになる、ということになる…はず


taisukeoe 2015年2月23日

妥協は必要

「実践ドメイン駆動設計」は、このあたりの理想と現実的制約との戦いの話が多めになるのかなぁ。買わねば。


tototoshi 2015年2月23日
なんかinfraとかRepositoryの話になりがちだけどそっちじゃなくて、いにしえよりService層と言われてるようなところの設計をドメインモデルを中心に考えるという話ではないかなあ。で、それはやはりいにしえより続くドメインモデルvsトランザクションスクリプトみたいな話になる。


xuwei-k 2015年2月23日
いにしえとは・・・(哲学


tkawachi 2015年2月23日
みんなDDD本みてて、最初にレイヤードアーキテクチャが来るからその話が人気なのかな(想像


tototoshi 2015年2月23日
レイヤードアーキテクチャが話題に上がるのはフレームワークとぶつかってRailsとか使ってる限り無理だからでは。


gakuzzzz 2015年2月23日

http://labs.gree.jp/blog/2013/12/9354/ のコラムではDAOをRDBMSインターフェイスと捉えてますね

あーそうこのブログ読んだ時も違和感あったんですよね。このDaoの定義ってどこかに出典あるのでしょうか? http://www.tutorialspoint.com/design_pattern/data_access_object_pattern.htm この辺だとRDBMSは実装側だし、Wikipediaもそれっぽい記述ですが出典が見つからず……。


xuwei-k 2015年2月23日
そんなことよりFree Monad勉強しましょう(唐突


todesking 2015年2月23日
DAOの出典はCore J2EE Patternsかなあ(Wikipediaだとそうなってた) http://www.corej2eepatterns.com/DataAccessObject.htm http://www.corej2eepatterns.com/DataAccessObject.htm


gakuzzzz 2015年2月23日
Free MonadDSL を作ったんですが、こういうDSLの PropertyBased Test を書こうとして止まってしまいました! どうしたらいいでしょうか!? おお、ありがとうございます< Core J2EE Patterns

You want to provide a uniform data access API for a persistent mechanism to various types of data sources, such as RDBMS, LDAP, OODB, XML repositories, flat files, and so on.

ふむ。


gakuzzzz 2015年2月23日
外部API呼び出しとかを含めて抽象化したインターフェースまさしくDaoっぽい


tototoshi 2015年2月23日
なんかもう Dao でいい気がしてきますね


gakuzzzz 2015年2月23日
Daoだお


kkismd 2015年2月23日
あっ


todesking 2015年2月23日
DaoとRepositoryの違い、Daoはデータストレージの抽象化しか志向していないのに対して、Repositoryはドメインモデルとの接続を強く意識しているというのがあるかな(DDDにおいてDaoパターン使ったら自然にRepositoryになりそう)


tkawachi 2015年2月23日
すみません。それで最初の話にもどるのですが ドメイン層で class MyEntity {...} があって、レポジトリ(インフラ層)で def findMyEntity(id: Id): MyEntity = ??? って書くとしたら、戻り値にドメイン層のクラス出てきてインフラ層がドメイン層に依存してね?って話なんですが これはドメイン層のAPI を定義して trait MyEntityAPI { ... }ドメイン層の実装ではAPIを実装 class MyEntity extends MyEntityAPI { ... }レポジトリではファクトリを取る def findMyEntity(id: Id)(factory: ... => MyEntityAPI): MyEntityAPI みたいな形?なんでしょうか?なんか依存は整理できたけど、無駄にごちゃごちゃしたような。


tkawachi 2015年2月23日
何か間違っている気がしてなりません。。。


todesking 2015年2月23日
エヴァンスのDDD本だと具体的なrepositoryの置き場所に言及されてないように見える

ということを考えると、ドメイン層とリポジトリのある層が相互依存することは不可避ではないだろうか

http://stackoverflow.com/questions/18809249

そのものずばりの質問があったけど、どうもしっくりこない……


tkawachi 2015年2月23日
accepted answer みると、ドメイン層はインフラ層に依存すべきではない、と書いてあるなあ。。 class MyEntitytrait RepoAPI { def findMyEntity(id: Id): MyEntity } みたいのがドメイン層で、インフラ層で RepoAPI を実装する感じかあ。


tkawachi 2015年2月23日
onion architecture, hexagonal architecture と DDD本の設計はレイヤー依存関係において異なるみたいですね。 インフラが外か内かという面で。


todesking 2015年2月23日
http://twitter.com/j5ik2o/status/569830145843863552

http://twitter.com/j5ik2o/status/569830775178162176

かとじゅんさんがなぞめいたことを言っておられる


tkawachi 2015年2月23日
導師様ー


j5ik2o 2015年2月23日
ドメイン層はインフラ層に依存していいですよ レイヤー化アーキテクチャーの章読むと良いかと 考えたか色々ありますが、依存は単方向が基本ですね。


j5ik2o 2015年2月23日
いろいろ質問あるようなので、stack overflow などで質問あげると良い気がしますがどうてしょかね?^ ^


2/23はここまででDDDの話題は終了しました。

が、翌日 我々は更にDDDに踏み込む事になります。

残りのまとめも公開しました。(2015/03/06)

Scala界隈でDDDが大いに盛り上がったのでログをまとめましたよ-その2 - Kuchitama Tech Note

Scala + JettyでWebSocket Clientを実装しました

前回、ブログでPlay + ScalaでWebSocketのサーバアプリを作りました。

Scala+PlayでWebSocketプログラミング - Kuchitama Tech Note

で、今回はScala + Jettyで、前回作ったアプリに接続するクライアントアプリを書いてみました。

socket-janken/client at master · Kuchitama/socket-janken · GitHub

動作は、標準入力された内容をじゃんけんサーバに送信して、帰ってきた結果を標準出力に表示するだけです。

探した感じJettyつかってScalaでWebSocket Clientを実装している例が見当たらなかったので、 公式ドキュメントを見ながら実装してみました。

http://www.eclipse.org/jetty/documentation/9.2.6.v20141205/jetty-websocket-client-api.html

Jetty WebSocket Client API

あんまりサンプルもなくって、こんな感じでいいんかな?って、手探りな感じの実装になりました。 もっとスタンダードな実装方法とかあればPRください。

元気があったら、サーバからのメッセージをJsonで返すようにして、じゃんけんの結果をAAで表示とかしたい。

Scala+PlayでWebSocketプログラミング

最近、TypetalkにWebSocketを利用したAPIが追加されてて、WebSocketに興味を持つようになりました。

ストリーミング | Typetalk API | Nulab Developers

で、クライアントサイドのプログラミングだけでなくサーバサイドもちょっとやってみたかったので簡単にサンプルを作ってみました。

WebSocketで接続したら、じゃんけんが出来ます。 使い方などはREADMEに記載しているので、良かったら試してやってください。

Kuchitama/socket-janken · GitHub

今回、サーバサイドの実装には得意のPlayframeworkを使ってScalaで実装しました。 PlayframeworkはAkkaのアクターを使ったWebSocket実装をデフォルトで提供してくれているので、かなり簡単に作れました。 作ったサンプルアプリはHerokuで公開してあります。

Play2.3から、WebSocketの利用方法が2種類に増えたみたいなんですが、サンプルとか記事が見当たらなかったので、多少でもこれからPlayでWebSocketを試してみようかという人の助けになれば幸いです。

あと、初めてHerokuボタンを設置してみました。

Deploy

こっちも試して頂けると幸いです。

AnsibleをProxy環境下で利用する

Ansibleをなんで存在してるのかよくわからない仕事の邪魔にしかならないようなProxy環境下で利用する際のメモ書きです。

入門Ansible

入門Ansible

Proxy環境内の実行マシンからAWSなどのProxy環境外のサーバに対して操作を行う場合を想定しています。 対象のOSはCentOS6で、Vagrantを利用して下記のBoxからイメージを立ち上げ、Ansibleのインストール、実行を行いました。

CentoOS6.4 https://github.com/2creatives/vagrant-centos/releases/download/v6.4.2/centos64-x86_64-20140116.box

目次

  • Proxy環境下でのAnsibleのインストール
  • Proxy環境下でのAnsible実行
  • Proxy環境下のCentOS6でAnsibleを実行

Proxy環境下でのAnsibleのインストール

下ごしらえ

まずはAnsibleのインストールを行います。 とりあえず、一通りhttp, https, ftpに対してProxyを通すように設定しておきます。 インストール自体にはこの設定は不要かもしれませんが、どうせProxy環境から出れない以上は必要なので最初にやってしまいます。

echo "export http_proxy=<PROXY_HOST>:<PROXY_PORT>" >> ~/.bash_profile
echo "export https_proxy=<PROXY_HOST>:<PROXY_PORT>" >> ~/.bash_profile
echo "export ftp_proxy=<PROXY_HOST>:<PROXY_PORT>" >> ~/.bash_profile
source ~/.bash_profile

yumコマンドもProxyを通すように設定します。

sudo sh -c 'echo "proxy=https://<PROXY_HOST>:<PROXY_PORT>/" >> /etc/yum.conf'

インストール

ここまで出来たら、Ansibleのインストール作業に入ります。

まずは、rpmの取得から。 rpmコマンドの実行時にプロキシを通すように指定します。

sudo rpm --httpproxy <PROXY_HOST> --httpport <PROXY_PORT> -ivh http://ftp-srv2.kddilabs.jp/Linux/distributions/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm

rpmが取得出来たら、yumコマンドを使ってAnsibleとそのた必要なものをインストール/アップデートします。

sudo yum install -y ansible sshpass
sudo yum update -y openssh

これでAnsibleはインストール出来たはずです。

Proxy環境下でのAnsible実行

Ansibleのインストールが出来てもそのままでは、Ansibleの実行ができません。 なぜなら、AnsbileがSSHでリモートマシンに接続するときにProxyを通らないから。

というわけで、corkscrewでProxyを通してSSHが実行出来るようにします。 まずは、corkscrewのインストール

cd /tmp
curl -o  corkscrew-2.0.tar.gz http://www.agroman.net/corkscrew/corkscrew-2.0.tar.gz
tar -xzf corkscrew-2.0.tar.gz

cd corkscrew-2.0
./configure
make && sudo make install

corkscrewがインストールできたら、ssh_configに設定を追記します。

sudo cp /etc/ssh/ssh_config /etc/ssh/ssh_config.back # 一応バックアップしておく
sudo sh -c 'echo "ProxyCommand /usr/local/bin/corkscrew <PROXY_HOST> <PROXY_PORT> %h %p" >> /etc/ssh/ssh_config'

これで、SSHもProxy経由で実行出来るようになります。

Proxy環境下のCentOS6でAnsibleを実行

どうもCentOS6は癖があるようで、ここまでの手順を完了していてもAnsibleをきちんと実行する事が出来ません。 (参考 https://groups.google.com/d/msg/ansible-project/ExWKdVE7mwQ/ZtycBhQ4mt4J

というわけで、Ansibleの実行時に -c ssh とオプションに指定してやる必要があります。 毎回、-c オプションをつけるのが面倒な場合は、 ansible.cfgファイルにtransport = smart を追記してやれば良さそうです。 -cオプションできちんと動作する事は確認しました。

ansible -m setup -u <USER> -k -c ssh