<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-23864877</id><updated>2011-11-28T10:15:42.233+09:00</updated><category term='ruby'/><category term='ロボット'/><category term='system'/><category term='調べてみた'/><category term='scala'/><category term='javascript'/><category term='java'/><category term='clojure'/><category term='セミナー/勉強会'/><category term='game'/><category term='book'/><category term='product'/><category term='使ってみた'/><category term='ddd'/><category term='report'/><category term='python'/><category term='PoEAA'/><category term='tips'/><category term='rails'/><category term='dsl'/><category term='雑記'/><category term='design'/><category term='dotnet'/><category term='コンピュータ科学'/><category term='数学'/><category term='家庭内最適化'/><title type='text'>A Life in Shinjuku.</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default?start-index=101&amp;max-results=100'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>182</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-23864877.post-2060111838167429634</id><published>2011-11-08T16:26:00.001+09:00</published><updated>2011-11-08T16:45:30.508+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='clojure'/><title type='text'>WindowsでLeiningen behind a proxy</title><content type='html'>&lt;br /&gt;&lt;div style="overflow-x: hidden; overflow-y: hidden;"&gt;JavaEE勉強会でProgramming Clojureを読んではいるものの、途中不参加だった時期もあり、いまいち身についている感がない。このまま終わってしまうのもアレなので、Webアプリでも作ってもう少し慣れようなどと思い立つ。仕事で時間ができた時に少しずつさわることを想定して、Windows上で環境構築をはじめることにした。&lt;/div&gt;&lt;div style="overflow-x: hidden; overflow-y: hidden;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="overflow-x: hidden; overflow-y: hidden;"&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;まずはNoirフレームワークで&lt;/span&gt;&lt;/div&gt;&lt;div style="overflow-x: hidden; overflow-y: hidden;"&gt;Webで調べてみたところ、Clojure用フレームワークとしてはCompojureが有名っぽい。そういえば、JavaEE勉強会の角田さんによる発表で、Heroku＋CompojureでWebアプリを作っていたような気がする。しかし、社内からはProxyの問題でHerokuが使えないことは確認済み。同じ構成だとHerokuに上げたくなって悔しくなりそう。違うフレームワークを探してみたところ、Noirというものを見つけた。シンプルなWebフレームワークらしいので、まずはNoir向けに環境を作って動かしてみよう。&lt;/div&gt;&lt;div style="overflow-x: hidden; overflow-y: hidden;"&gt;# と思ったら、NoirはCompojure＋Ring上に構築されてるらしいです&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="overflow-x: hidden; overflow-y: hidden;"&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Leiningenインストール&lt;/span&gt;&lt;/div&gt;&lt;div style="overflow-x: hidden; overflow-y: hidden;"&gt;lein-noirというプラグインを使えばNoir関連の依存ライブラリをインストールしてくれるらしいので、Leiningenからインストールする。現在の最新バージョンは1.6.1.1。&lt;a href="https://github.com/technomancy/leiningen#readme"&gt;LeiningenのGithub&lt;/a&gt;からlein.batをダウンロードし、Pathの通った場所に置いてから&lt;/div&gt;&lt;blockquote class="tr_bq"&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;lein self-install&lt;/div&gt;&lt;/blockquote&gt;&lt;div style="overflow-x: hidden; overflow-y: hidden;"&gt;すればOK。ただし、Path上にWget.exeがない場合は leiningen-x.x.x.x-standalone.jar がダウンロードできずに怒られるので注意。この辺りは親切にも、lein self-install のエラーメッセージにダウンロード先を含めて書いてあるので問題ないとは思う。&lt;/div&gt;&lt;div style="overflow-x: hidden; overflow-y: hidden;"&gt;Proxy環境の人なら、環境変数にhttp_proxyを設定すればOK。認証ありでも同じく環境変数を設定すれば問題なし。&lt;/div&gt;&lt;div style="overflow-x: hidden; overflow-y: hidden;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="overflow-x: hidden; overflow-y: hidden;"&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;lein-noirインストール&lt;/span&gt;&lt;/div&gt;&lt;div style="overflow-x: hidden; overflow-y: hidden;"&gt;最新のバージョンは1.2.1。以下のコマンドでOK…のはずだった。&lt;/div&gt;&lt;blockquote class="tr_bq"&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;lein plugin install lein-noir 1.2.1&lt;/div&gt;&lt;/blockquote&gt;&lt;div style="overflow-x: hidden; overflow-y: hidden;"&gt;しかし、あえなくエラー発生。リポジトリ上にlein-noir-1.2.1.jarが見つからないらしい。ブラウザからclojars.org/repo に行って確認したところ、JARはきちんと存在している。&lt;/div&gt;&lt;blockquote&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;D:\&amp;gt;lein plugin install lein-noir 1.2.1&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;Exception in thread "main" org.apache.maven.artifact.resolver.ArtifactNotFoundEx&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;ception: Unable to download the artifact from any repository&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;Try downloading the file manually from the project website.&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;Then, install it using the command:&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; mvn install:install-file -DgroupId=lein-noir -DartifactId=lein-noir -Dversio&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;n=1.2.1 -Dpackaging=jar -Dfile=/path/to/file&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;Alternatively, if you host your own repository you can deploy the file there:&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; mvn deploy:deploy-file -DgroupId=lein-noir -DartifactId=lein-noir -Dversion=&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;1.2.1 -Dpackaging=jar -Dfile=/path/to/file -Durl=[url] -DrepositoryId=[id]&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; lein-noir:lein-noir:jar:1.2.1&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;from the specified remote repositories:&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; clojars (http://clojars.org/repo/),&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; central (http://repo1.maven.org/maven2)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp;(NO_SOURCE_FILE:0)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at clojure.lang.Compiler.eval(Compiler.java:5440)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at clojure.lang.Compiler.eval(Compiler.java:5391)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at clojure.core$eval.invoke(core.clj:2382)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at clojure.main$eval_opt.invoke(main.clj:235)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at clojure.main$initialize.invoke(main.clj:254)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at clojure.main$script_opt.invoke(main.clj:270)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at clojure.main$main.doInvoke(main.clj:354)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at clojure.lang.RestFn.invoke(RestFn.java:551)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at clojure.lang.Var.invoke(Var.java:390)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at clojure.lang.AFn.applyToHelper(AFn.java:193)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at clojure.lang.Var.applyTo(Var.java:482)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at clojure.main.main(main.java:37)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;Caused by: org.apache.maven.artifact.resolver.ArtifactNotFoundException: Unable&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;to download the artifact from any repository&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;Try downloading the file manually from the project website.&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;Then, install it using the command:&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; mvn install:install-file -DgroupId=lein-noir -DartifactId=lein-noir -Dversio&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;n=1.2.1 -Dpackaging=jar -Dfile=/path/to/file&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;Alternatively, if you host your own repository you can deploy the file there:&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; mvn deploy:deploy-file -DgroupId=lein-noir -DartifactId=lein-noir -Dversion=&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;1.2.1 -Dpackaging=jar -Dfile=/path/to/file -Durl=[url] -DrepositoryId=[id]&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; lein-noir:lein-noir:jar:1.2.1&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;from the specified remote repositories:&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; clojars (http://clojars.org/repo/),&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; central (http://repo1.maven.org/maven2)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at org.apache.maven.artifact.resolver.DefaultArtifactResolver.resolve(De&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;faultArtifactResolver.java:212)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at org.apache.maven.artifact.resolver.DefaultArtifactResolver.resolveAlw&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;ays(DefaultArtifactResolver.java:80)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at java.lang.reflect.Method.invoke(Unknown Source)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:90)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at clojure.lang.Reflector.invokeInstanceMethod(Reflector.java:28)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at leiningen.install$standalone_download.invoke(install.clj:39)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at leiningen.install$install.invoke(install.clj:62)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at leiningen.plugin$install.invoke(plugin.clj:32)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at leiningen.plugin$plugin.invoke(plugin.clj:75)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at clojure.lang.Var.invoke(Var.java:373)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at clojure.lang.AFn.applyToHelper(AFn.java:167)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at clojure.lang.Var.applyTo(Var.java:482)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at clojure.core$apply.invoke(core.clj:540)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at leiningen.core$apply_task.invoke(core.clj:229)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at leiningen.core$_main.doInvoke(core.clj:294)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at clojure.lang.RestFn.applyTo(RestFn.java:139)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at clojure.core$apply.invoke(core.clj:542)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at leiningen.core$_main.invoke(core.clj:297)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at user$eval42.invoke(NO_SOURCE_FILE:1)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at clojure.lang.Compiler.eval(Compiler.java:5424)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ... 11 more&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;Caused by: org.apache.maven.wagon.ResourceDoesNotExistException: Unable to downl&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;oad the artifact from any repository&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at org.apache.maven.artifact.manager.DefaultWagonManager.getArtifact(Def&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;aultWagonManager.java:332)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at org.apache.maven.artifact.resolver.DefaultArtifactResolver.resolve(De&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;faultArtifactResolver.java:200)&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ... 33 more&lt;/div&gt;&lt;/blockquote&gt;&lt;div style="overflow-x: hidden; overflow-y: hidden;"&gt;どうやら内部的にはMavenを使っているようなので、 ~/.m2/settings.xmlにproxy設定を追加してみたが状況は変わらず。ちなみに、プロキシがローカルホストなのは、NTLM認証が面倒なのでローカルプロキシを入れているため。&lt;/div&gt;&lt;div style="overflow-x: hidden; overflow-y: hidden;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre&gt;&amp;lt;settings&amp;gt;&lt;br /&gt;  &amp;lt;proxies&amp;gt;&lt;br /&gt;   &amp;lt;proxy&amp;gt;&lt;br /&gt;      &amp;lt;active&amp;gt;true&amp;lt;/active&amp;gt;&lt;br /&gt;      &amp;lt;protocol&amp;gt;http&amp;lt;/protocol&amp;gt;&lt;br /&gt;      &amp;lt;host&amp;gt;localhost&amp;lt;/host&amp;gt;&lt;br /&gt;      &amp;lt;port&amp;gt;9090&amp;lt;/port&amp;gt;&lt;br /&gt;    &amp;lt;/proxy&amp;gt;&lt;br /&gt;  &amp;lt;/proxies&amp;gt;&lt;br /&gt;&amp;lt;/settings&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;div style="overflow-x: hidden; overflow-y: hidden;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="overflow-x: hidden; overflow-y: hidden;"&gt;切り分けのためにMaven3をインストールし、切り分け用のpom.xmlを作って depenencies に lein-noir 1.2.1 を追加。リポジトリにも clojars を追加してから mvn compile を叩くと、正常にダウンロードが完了した。この後再び lein plugin install lein-noir 1.2.1 と叩くと、無事にインストールが完了したらしい。謎。&lt;/div&gt;&lt;blockquote class="tr_bq"&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;lein plugin install lein-noir 1.2.1&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;Copying 1 file to C:\DOCUME~1\....~1\LOCALS~1\Temp\lein-c7edc836-8953-4a2b-b0e&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;0-830eeeaa1ad0\lib&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;Including lein-noir-1.2.1.jar&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;Including clojure-1.2.1.jar&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;Created lein-noir-1.2.1.jar&lt;/div&gt;&lt;/blockquote&gt;&lt;div style="overflow-x: hidden; overflow-y: hidden;"&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Noirプロジェクト作成&lt;/span&gt;&lt;/div&gt;&lt;div style="overflow-x: hidden; overflow-y: hidden;"&gt;LeiningenでNoirプロジェクトを作成。&lt;/div&gt;&lt;blockquote class="tr_bq"&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;lein noir new samplenoir&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;Creating noir project: &amp;nbsp;samplenoir&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;Creating new dirs at: &amp;nbsp;D:\...\projects\clojure\samplenoir&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;Adding files...&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;Project created!&lt;/div&gt;&lt;/blockquote&gt;&lt;div style="overflow-x: hidden; overflow-y: hidden;"&gt;プロジェクトディレクトリに移動してlein runでサーバが起動してデフォルトアプリケーションが利用可能になる。&lt;/div&gt;&lt;blockquote class="tr_bq"&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;lein run&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;Downloading: org/clojure/clojure/1.3.0/clojure-1.3.0.pom from central&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;Downloading: org/sonatype/oss/oss-parent/5/oss-parent-5.pom from central&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;Downloading: noir/noir/1.2.1/noir-1.2.1.pom from central&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;Downloading: noir/noir/1.2.1/noir-1.2.1.pom from clojars&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;- 中略 -&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;Downloading: org/mindrot/jbcrypt/0.3m/jbcrypt-0.3m.jar from clojars&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;Downloading: org/mindrot/jbcrypt/0.3m/jbcrypt-0.3m.jar from central&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;Copying 31 files to D:\watanabeknt\projects\clojure\samplenoir\lib&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;Starting server...&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;2011-11-08 15:00:00.098:INFO::Logging to STDERR via org.mortbay.log.StdErrLog&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;2011-11-08 15:00:00.098:INFO::jetty-6.1.25&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;2011-11-08 15:00:00.238:INFO::Started SocketConnector@0.0.0.0:8080&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;Server started on port [8080].&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;You can view the site at http://localhost:8080&lt;/div&gt;&lt;div style="font-family: Arial, Helvetica, 'Microsoft Yahei', sans-serif; font-size: 0.8em; overflow-x: hidden; overflow-y: hidden;"&gt;#&amp;lt;Server Server@1f02b85&amp;gt;&lt;server server@1f02b85=""&gt;&lt;/server&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div style="overflow-x: hidden; overflow-y: hidden;"&gt;普通に依存ライブラリをダウンロードできているっぽいんですけど、さっきは何がダメだったのだろう？&lt;/div&gt;&lt;div style="overflow-x: hidden; overflow-y: hidden;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="overflow-x: hidden; overflow-y: hidden;"&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Noirアプリケーションにアクセス&lt;/span&gt;&lt;/div&gt;&lt;div style="overflow-x: hidden; overflow-y: hidden;"&gt;コンソールに表示されているとおり、localhost:8080にアクセスすればデフォルトページが表示される。ここには、簡単なサンプルとともに、チュートリアルへのリンクが表示されている。&lt;/div&gt;&lt;div style="overflow-x: hidden; overflow-y: hidden;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="overflow-x: hidden; overflow-y: hidden;"&gt;&lt;span class="Apple-style-span" style="background-color: #474949; color: #d1d9e1; font-family: Monaco, Consolas, 'Courier New'; font-size: 16px; line-height: 24px; white-space: pre;"&gt;(defpage "/my-page" []  (html    [:h1 "This is my first page!"]))&lt;/span&gt;&lt;/div&gt;&lt;div style="overflow-x: hidden; overflow-y: hidden;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="overflow-x: hidden; overflow-y: hidden;"&gt;あれ？なんかあんま好きじゃない感じの記法なんですけど…。なんか昔Javaでこんないけてないライブラリがあったようななかったような。&lt;/div&gt;&lt;div style="overflow-x: hidden; overflow-y: hidden;"&gt;一区切りついて気に入らなかったら、結局Compojureに行ってしまうかもしれない…。&lt;/div&gt;&lt;div style="overflow-x: hidden; overflow-y: hidden;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="overflow-x: hidden; overflow-y: hidden;"&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;次&lt;/span&gt;&lt;/div&gt;&lt;div style="overflow-x: hidden; overflow-y: hidden;"&gt;次は、Noirのチュートリアルと、エディタの整備をやりたい。エディタは、CounterclockwiseかClojureboxどちらかの予定。Emacsとは仲良くなれなかったのでCounterclockwiseが有力。&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-2060111838167429634?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/2060111838167429634/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=2060111838167429634&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/2060111838167429634'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/2060111838167429634'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2011/11/windowsleiningen-behind-proxy.html' title='WindowsでLeiningen behind a proxy'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-8449082746795068031</id><published>2011-04-20T16:35:00.004+09:00</published><updated>2011-04-20T17:16:16.816+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ddd'/><category scheme='http://www.blogger.com/atom/ns#' term='report'/><title type='text'>QCon Tokyo 2011 アーキテクチャパネルディスカッション＋DDD雑多ネタ</title><content type='html'>アーキテクチャパネルディスカッションとラウンジ・ビアパーティでの雑談から、主にDDDに関して興味深かった話をいくつか。聞き取り能力は低いので抜けている部分もあると思いますがご容赦を。&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;b&gt;ビジネス的な有用性はどこにあるのか&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;b&gt;Evans氏発言要旨&lt;/b&gt;&lt;br /&gt;&lt;div&gt;経営層など意思決定を行う人たちに対して、ドメイン駆動設計の有用性をどう訴えかけるのか？という問いに対して、Evans氏は主にコアドメインへの注力によって競争上の優位、市場優位につなげる部分を強調。ここから一段階細かいレベルとして、ビジネスパーソンにとって理解できるソフトウェアへと進んでいくとのこと。ただし、常に労力に見合う価値が得られるわけではないことも忘れずに付加。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;雑感&lt;/b&gt;&lt;/div&gt;&lt;div&gt;この質問はなかなか難しく、聴衆の反応も微妙なものだったように思う。これは、DDDをオブジェクト指向設計方法論として受け取っている人が多く、こうした部分の有用性についての回答を期待していたものの、Evans氏は主にPartⅣの戦略的設計（Strategic Design）の有用性について語ったために、ギャップが生じたためだと思う。&lt;/div&gt;&lt;div&gt;DDDは一読するとオブジェクト指向分析・設計方法論に関する本のようにも見えるが、実際はOOに直接結びついているわけではない。ドメインを中心に設計をする上で都合の良いパラダイムが現状ではオブジェクトパラダイムであるために、実現方法を記した部分（PartⅡ、PartⅢ）がオブジェクト指向設計に沿った形で書かれているにすぎない。DDDにとって根本的に重要なのはOOではなく、その名が示すとおり「ドメイン」へのフォーカスだ。この点を踏まえたなら、コアドメインへの注力はシステム/ソフトウェア全体をドメインの観点から区分するという意味で、まさに大きな意思決定を行うレベルでのドメイン駆動設計そのものだということが理解できると思う。&lt;br /&gt;OO話がなかったのは…残念でした。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;b&gt;ドメインエキスパートをどうやって巻き込むのか&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Evans氏発言要旨&lt;/b&gt;&lt;/div&gt;&lt;div&gt;ドメインエキスパートとの最初のミーティングで、「あなたが最も難しく、面倒だと感じるのはどういった部分なのか？」「安眠を妨げるような問題はないか？」とたずねて、具体的なシナリオをあげてもらう。細かい問題は後で決めれば良い。画面項目の最大長や色などを聞くのはナンセンスで、ただでさえ忙しいドメインエキスパートの貴重な時間を浪費することになる。そんなことをしてはいけない。本当に難しい、重要な問題にフォーカスしてシナリオを描き、シナリオを解決できるモデルをホワイトボードに描き出して共有する。&lt;/div&gt;&lt;div&gt;仮にドメインエキスパートが示す問題がドメインにとってはさほど重要な問題ではなく、彼にとって重要・面倒であるだけであっても大きな問題ではない。彼と信頼関係を構築するのが重要。このセッションがうまくいけば、ドメインエキスパートはセッションを楽しみに待ってくれるようになることもある。これは実際にEvans氏が経験した話。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;雑感&lt;/b&gt;&lt;/div&gt;&lt;div&gt;画面項目の最大長…といったくだりは刺さった。多くのプロジェクトでは、まさにこうしてドメインエキスパートの時間を無駄にしている。ここでも、ドメインにフォーカスし、重要な部分にリソースを投入する、というドメイン駆動の原則が生きている。リソースというのは、開発者のリソースだけではなく、ドメインエキスパートのリソースも同じなのだ。モデリングセッションの進め方は&lt;a href="http://domainlanguage.com/ddd/whirlpool/"&gt;Whirlpool&lt;/a&gt;に沿ったものだが、ここに至って、繰り返し型・反復型開発の重要性も浮き彫りになってくる。ウォーターフォール型の開発プロセスで、横並びに設計を進めるのなら、こうしたアプローチを取るのは難しくなるだろう。しかし、重要な部分を先に進めることを合意できているなら（RUPくらいなら顧客合意も難しくないだろう）、ドメインエキスパートにとって重要な問題にフォーカスすることで注意を引きつけ、それを知的に解決するさまを共有することでモデリングセッションを軌道にのせる姿も現実的なものとして見えてくるのではないだろうか。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;b&gt;一般的・形式的な概念体系をどう扱うか&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;問題要旨&lt;/b&gt;&lt;/div&gt;&lt;div&gt;書籍Domain Specific Languageでは、ドメインエキスパートとのコミュニケーションを促進するためにDSLを構築し、DSLの背後にある概念体型としてセマンティックモデル（Semantic Model）を導入する。このセマンティックモデルの一形態として代替計算モデル（Alternative Computational Model）が挙げられており、よりうまく問題領域にフィットする場合に有効である旨が記述されている。代替計算モデルとして挙げられているステートマシン（State Machine）、依存ネットワーク（Dependency Network）、決定表（Decision Table）などは言わば確立された形式的な概念体系であるのだが、こうした体系とDDDのモデルはどういった関係にあるのか。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Evans氏発言要旨&lt;/b&gt;&lt;/div&gt;&lt;div&gt;確立された概念体系自体は非常に有用であるものの、これは汎用的なものであって、ドメインの重要な概念を直接的に表すものではない。重要なのはむしろ、モデルからこうした概念体系を分離した後に残るものであり、それこそがドメインの概念をより良く表すものとなり得る。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;雑感&lt;/b&gt;&lt;/div&gt;&lt;div&gt;これは、15章「蒸留（Distillation）」に属するパターンの1つである、凝集されたメカニズム（Cohesive Mechanisms）を念頭に置いた回答ではないかと思う。DDDの書籍では、組織内の関係を表すモデルからグラフ構造をCohesive Mechanismsとして取り出す例があげられており、こうすることで組織のモデルからグラフ構造にまつわる概念群（ノード、アークなど）を消し去って、残されたモデルをより本質的なものにしている。また、貨物輸送の例でも配送ルートを決定する際にグラフ構造が使われており、Itineraryを実装した際に混入したであろうグラフにまつわる概念群を引き剥がすことに成功している。これはDDD Sampleでも確認できる。&lt;/div&gt;&lt;div&gt;DSLの代替計算モデル相当をDDDに組み込む場合、最も素直なアプローチはCohesive Mechanismsとして利用することだと考えている。貨物輸送の例であれば、うまくすればエンドユーザーが書いたDSLスクリプトを解釈実行することで、直接配送ルートを表すグラフ構造を構築でき、このモデルを使って最適経路を計算できるだろう。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;ただ、この回答については少し疑問が残っていて、実際は「確立された概念体系」と「ドメインの本質を表す概念群」との境界はそんなにはっきりしたものではないのではないかと思っている。例えば、8章「ブレークスルー」などで登場するシェアパイ（SharePie）は、代数的構造の1つである「群」の概念に沿ったもので、確立された概念体系、もしくはそれに限りなく近いものだが、DDD書籍ではドメインエキスパートがこの概念を操り、ユビキタス言語の一部にもなっている。このように、純粋にメカニズム的な意味を持った概念体系は確かにモデルの本質を表しはしないのであろうが、確立された概念体系自体がドメインの本質を表す場合もあるのではないかと思う。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;# この話、酔っ払った状態でEvans氏に話そうとしたけどstuckしてしまった…無念すぎる。酔っ払ってなくてもダメだったかもしれないことは置いておこう…。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;b&gt;関連：&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://hibituredure.blogspot.com/2010/09/fowler-dsl.html"&gt;Fowler DSLのエッセンス&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 14px; line-height: 18px;"&gt;&lt;a href="http://hibituredure.blogspot.com/2011/04/code-generation-language-workbenchesdsl.html"&gt;Code Generation &amp;amp; Language Workbenches＠DSL読書会&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large; "&gt;&lt;b&gt;英語以外の言語ではどう実践すべきか&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;問題要旨&lt;/b&gt;&lt;/div&gt;&lt;div&gt;英語以外の言語を用いる場合、ほとんどの実装言語が英語に沿ったものであるため、ドメイン概念をそのままソフトウェアとして実装できないことが問題になる。仮にここで、実装言語にあわせて英語を混在させた場合、ユビキタス言語が歪められてしまう。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Evans氏発言要旨&lt;/b&gt;&lt;/div&gt;&lt;div&gt;ソースコードでも日本語を使え。以上。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;雑感&lt;/b&gt;&lt;/div&gt;&lt;div&gt;実際にはこれほど乱暴な話になったわけではない。Evans氏も英語以外の言語での実践経験はなく、他の言語圏でどうやって対処しているのかは不思議に思っていた様子。ただ、Javaのコードを見ながら話をした際にクラス名に対して日本語でコメントがつけられているのを見て、これではダメだと感じたようだった。「ドメインエキスパートがこの言葉（日本語コメントで書かれたクラス名）を使っているのなら、なぜクラス名にこれを使わない？」とのこと。「日本語でJava等を書くと、Java慣習にかたっぱしから違反してしまうので問題なんだ、コードも読みづらいし」と反論（？）してみたものの、「重要なのはドメインの概念であって、技術的な問題はそれに比べれば瑣末なものだろう？」と言われてしまい、もう納得するしかなかった。実際のところ、主語・動詞・目的語・修飾語等の位置が異なるため、英語に比べるとかなり違和感のあるコードが出来上がってしまうのだが、DDDがこれまで述べてきた「ドメイン重視、技術要素は二の次」という姿勢が貫かれていることを知ってすっきりした。これでDDDerは、日本語でコードを書いてみなくちゃならなくなった！実践した人は、Evans氏にフィードバックしてあげましょう。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;iframe frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="http://rcm-jp.amazon.co.jp/e/cm?t=lifeinshin-22&amp;amp;o=9&amp;amp;p=8&amp;amp;l=as1&amp;amp;asins=4798121967&amp;amp;ref=qf_sp_asin_til&amp;amp;fc1=000000&amp;amp;IS2=1&amp;amp;lt1=_blank&amp;amp;m=amazon&amp;amp;lc1=0000FF&amp;amp;bc1=000000&amp;amp;bg1=FFFFFF&amp;amp;f=ifr" style="height: 240px; width: 120px;"&gt;&lt;/iframe&gt;&lt;iframe frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="http://rcm-jp.amazon.co.jp/e/cm?t=lifeinshin-22&amp;amp;o=9&amp;amp;p=8&amp;amp;l=as1&amp;amp;asins=0321712943&amp;amp;ref=qf_sp_asin_til&amp;amp;fc1=000000&amp;amp;IS2=1&amp;amp;lt1=_blank&amp;amp;m=amazon&amp;amp;lc1=0000FF&amp;amp;bc1=000000&amp;amp;bg1=FFFFFF&amp;amp;f=ifr" style="height: 240px; width: 120px;"&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-8449082746795068031?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/8449082746795068031/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=8449082746795068031&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/8449082746795068031'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/8449082746795068031'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2011/04/qcon-tokyo-2011-ddd.html' title='QCon Tokyo 2011 アーキテクチャパネルディスカッション＋DDD雑多ネタ'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-1363572737151168043</id><published>2011-04-18T10:41:00.001+09:00</published><updated>2011-04-18T23:39:23.145+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ddd'/><category scheme='http://www.blogger.com/atom/ns#' term='report'/><title type='text'>QCon Tokyo 2011</title><content type='html'>QCon Tokyo 2011に、DDD読書会（JavaEE勉強会）のコミュニティ枠として参加させていただきました。初回開催となる2009以来2年ぶりの参加になります。&lt;br /&gt;&lt;br /&gt;今回の&lt;a href="http://qcontokyo.com/program.html"&gt;セッションプログラム&lt;/a&gt;はビアパーティまであわせると総数が21で、以下の6つに分類されています。総プログラム数からすると多彩な内容ですね。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;クラウド&lt;/li&gt;&lt;li&gt;Design &amp;amp; Patterns&lt;/li&gt;&lt;li&gt;技術&lt;/li&gt;&lt;li&gt;クオリティ &amp;amp; テスト&lt;/li&gt;&lt;li&gt;アーキテクチャ&lt;/li&gt;&lt;li&gt;ケーススタディ&lt;/li&gt;&lt;/ul&gt;しかし、なんといっても今回の目玉は、DDDの創始者Eric Evans氏の来日でしょう。基調講演に通常プログラム、パネルディスカッションと盛りだくさんの内容でした。僕はこのDDDと、クラウド関連のセッションに的を絞って出席してきました。具体的には、以下の7つ＋ビアパーティに参加、という形です。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;ドメイン駆動設計：複雑な問題群に対する有用なモデルたち&lt;/li&gt;&lt;li&gt;Webアプリケーションエンジニアが見てきたこの10年&lt;/li&gt;&lt;li&gt;クラウドのデータアーキテクチャー設計の原則&lt;/li&gt;&lt;li&gt;Understanding IA: The Extension of Man 2011&lt;/li&gt;&lt;li&gt;クラウドコンピューティングの未来：10年後の情報システムを考える&lt;/li&gt;&lt;li&gt;ドメイン駆動設計においてレガシーシステムを扱うための戦略&lt;/li&gt;&lt;li&gt;アーキテクチャパネルディスカッション&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;セッションの感想&lt;/span&gt;&lt;br /&gt;QCon2009風に感想を分類すると、こんな感じでした。&lt;br /&gt;&lt;br /&gt;[面白かった！]&lt;br /&gt;&lt;ul&gt;&lt;li&gt;クラウドのデータアーキテクチャー設計の原則&lt;/li&gt;&lt;li&gt;クラウドコンピューティングの未来：10年後の情報システムを考える&lt;/li&gt;&lt;li&gt;ドメイン駆動設計においてレガシーシステムを扱うための戦略&lt;/li&gt;&lt;li&gt;アーキテクチャパネルディスカッション&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;[ふつう]&lt;/div&gt;&lt;ul&gt;&lt;li&gt;ドメイン駆動設計：複雑な問題群に対する有用なモデルたち&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;[いまいち]&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Webアプリケーションエンジニアが見てきたこの10年&lt;/li&gt;&lt;li&gt;Understanding IA: The Extension of Man 2011&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;雑感&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;今回のQConでは、2年前に比べると統一的な方向性のようなものを見出すことはできませんでした。色々な人が色々なことをやっていて、その成果を個々に見ているような感じです。これは、僕が主に出席したクラウド系のセッションとDDD関係のセッションの方向性がかなり異なっているのが大きな理由かもしれません。&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;b&gt;クラウド系&lt;/b&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;クラウド系で特に面白かったのは、佐藤一郎氏の「クラウドコンピューティングの未来：10年後の情報システムを考える」でした。この講演では、クラウドコンピューティングをソフトウェア技術中心の他のセッションとは異なった視点から捉えており、クラウドコンピューティングと物流業態との類似性や他の業態を模した異なる形態でのクラウドコンピューティングの可能性、アプリケーションとの関係、アプリケーションのビジネス化のヒントが散りばめられていて、非常に新鮮なものでした。&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;b&gt;DDD系&lt;/b&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;DDDのセッションで面白かったのは、Eric Evans氏の「アーキテクチャパネルディスカッション」でした。ここでの収穫はなんといっても、Evans氏自らドメインエキスパートとのモデリングセッションについて、具体例を交えて生き生きと語ってくれたことでした。ドメインエキスパートとのモデリングセッション自体はDDD書籍にもいくつか例示されているのですが、どのようにしてドメインエキスパートとのモデリングに入っていくのか、的を絞ったモデリングセッションを続けるにはどうすればいいのか、どの程度の頻度でモデリングを行うのか、など実際に実行する上で不明な部分が多く、果たして現実的に可能なのだろうか、と疑問に思った人は多数いたように思います。今回は氏自らセッションへの入り方、雰囲気作り、関係の保ち方、焦点の絞り方といった部分を語ってくれたことで、こうした部分を現実感を持って理解することができました。こうした方法は、&lt;a href="http://domainlanguage.com/ddd/whirlpool/Domain_Language_Model_Exploration_Whirlpool_v2010-06-19.pdf"&gt;Model Exploration Whirlpool&lt;/a&gt;というミニプロセスとして形式的にまとめられており、DDDの前進を感じることができました。&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;# 面白かったものについては、備忘録的に個別にエントリを書こうかと思います。&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-1363572737151168043?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/1363572737151168043/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=1363572737151168043&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/1363572737151168043'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/1363572737151168043'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2011/04/qcon-tokyo-2011.html' title='QCon Tokyo 2011'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-4203116652473280445</id><published>2011-04-14T01:52:00.000+09:00</published><updated>2011-04-14T01:52:15.980+09:00</updated><title type='text'>ブレイクスルー体験記＠DevLove Beautiful Development</title><content type='html'>DevLoveさんのイベント「DevLove Beautiful Development ソフトウェアの核心にある複雑さに立ち向かう」にて発表させていただきました。&lt;br /&gt;僕のITスキルが低い＆緊張のために、画面が小さいことに気づかずにそのまま進めてしまいました。見えにくかった方、申し訳ありませんでしたorz&lt;br /&gt;イベント全体の情報は、&lt;a href="http://www.devlove.org/past-beneficiaries/devlove_ddd2"&gt;オフィシャルサイト&lt;/a&gt;にて非常にわかりやすく整理されています。ぜひそちらへ。&lt;br /&gt;&lt;div id="__ss_7571308" style="width: 425px;"&gt;&lt;strong style="display: block; margin: 12px 0 4px;"&gt;&lt;a href="http://www.slideshare.net/kentaro714/beautiful-development" title="Beautiful Development ブレイクスルー体験記"&gt;Beautiful Development ブレイクスルー体験記&lt;/a&gt;&lt;/strong&gt; &lt;iframe frameborder="0" height="355" marginheight="0" marginwidth="0" scrolling="no" src="http://www.slideshare.net/slideshow/embed_code/7571308" width="425"&gt;&lt;/iframe&gt; &lt;br /&gt;&lt;div style="padding: 5px 0 12px;"&gt;View more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/kentaro714"&gt;kentaro watanabe&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;実は、スライドの最後には僕の大好きな漫画である日本橋ヨヲコ先生の「G戦場ヘヴンズドア」の1シーンを入れてました。すさまじい才能を持ちながら、漫画編集者の父との確執からストーリーが作れなくなった鉄男と、漫画家の父との確執から歪んだ形で小説家を目指す町蔵が心を通わせ、ともに戦場に歩み出そうとするシーンです。&lt;br /&gt;&lt;br /&gt;町蔵「バカかお前…何こんな中途半端なモン世に出そうとしてんだよ！！オレは本気が見てえんだよ！！人の顔色うかがって描いてんじゃねえよ！！」&lt;br /&gt;鉄男「作れないんだ、ストーリーが。もう言いたいことがないんだ、オレは、からっぽだから堺田君にひかれたんだよ。」&lt;br /&gt;町蔵（……ああ、こいつもか。）&lt;br /&gt;町蔵（誰にも、）&lt;br /&gt;町蔵（期待してないんだな。）&lt;br /&gt;町蔵「お前は天才かもしれねえ。けどそれだけだ。才能だとか画力だとか、プロはもうそんなとこで生きてねえ。」&lt;br /&gt;町蔵「万人受け狙えば通用するような甘い世界でもねえ。」&lt;br /&gt;町蔵&lt;span class="Apple-style-span" style="font-size: large;"&gt;「いいか、オレと組むなら手加減すんな。」&lt;/span&gt;&lt;br /&gt;町蔵&lt;span class="Apple-style-span" style="font-size: large;"&gt;「…もしお前がもう一度…」&lt;/span&gt;&lt;br /&gt;町蔵&lt;span class="Apple-style-span" style="font-size: large;"&gt;「オレを震えさせてくれるなら、」&lt;/span&gt;&lt;br /&gt;町蔵&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;「この世界で、一緒に汚れてやる。」&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;ヘタレだから出せなかったよ。でももう何も言うことはないよ。&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=lifeinshin-22&amp;o=9&amp;p=8&amp;l=as1&amp;asins=409188301X&amp;ref=qf_sp_asin_til&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=000000&amp;bg1=FFFFFF&amp;f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"&gt;&lt;/iframe&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=lifeinshin-22&amp;o=9&amp;p=8&amp;l=as1&amp;asins=4798121967&amp;ref=qf_sp_asin_til&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=000000&amp;bg1=FFFFFF&amp;f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-4203116652473280445?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/4203116652473280445/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=4203116652473280445&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/4203116652473280445'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/4203116652473280445'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2011/04/devlove-beautiful-development.html' title='ブレイクスルー体験記＠DevLove Beautiful Development'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-2546247552592402249</id><published>2011-04-13T23:17:00.004+09:00</published><updated>2011-04-14T01:55:57.561+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dsl'/><title type='text'>Code Generation &amp; Language Workbenches＠DSL読書会</title><content type='html'>少し前になりますが、DSL読書会＠JavaEE勉強会でCode GenerationとLanguage Workbenchesのまとめを発表したので、ここにも載せておきます。&lt;br /&gt;&lt;br /&gt;&lt;iframe frameborder="0" height="342" src="https://docs.google.com/present/embed?id=dg472vvr_462dm9qmw2j" width="410"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;Google Docsで作ってみたのですが、Slide Shareと勝手が違っていて、埋め込んだ状態でうまく閲覧できそうにないです。まともに見たい人は、最大化ボタンをクリックするのが良いかと思います。&lt;br /&gt;&lt;br /&gt;僕の担当分はDSL本の最後の部分で、この資料はそれまでの部分のまとめが他の人から発表されている前提で作っています。これだけ見てもあまりわからないかもしれませんので、字だけになりますが少しだけ補足しておきます（&lt;a href="http://hibituredure.blogspot.com/2010/09/fowler-dsl.html"&gt;Fowler DSLのエッセンス&lt;/a&gt;にさらっと目を通しておかれると、少しは分かり良いかもしれません）。&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;DSL Overview&lt;/span&gt;&lt;br /&gt;DSL概念全体の中でCode Generationがどのような位置づけにあるかを俯瞰するために、Fowler DSLの全体像を示しています。&lt;br /&gt;&lt;br /&gt;DSLスクリプトを言語処理層（Language Processing Layer、パーサー/ビルダーなど）が処理することでセマンティックモデルが構築され、セマンティックモデルをアプリケーションから直接実行したり、他の環境向けにコードを生成してから実行することで望みの計算を行います。セマンティックモデルはFowler DSLのキーとなるもので、Fowler DSLを他のDSLアプローチと隔てている最も大きな要因の一つです。&lt;br /&gt;&lt;br /&gt;DSLは、DSLスクリプトと言語処理層の形態によって内部DSLと外部DSLに分類されます。内部DSLはDSLスクリプト、言語処理層、セマンティックモデルを同じプログラミング言語上に構築するもので、外部DSLはDSLスクリプトを独立した言語で記述するものです。&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;言語処理層を構成するパターン群を総称して、構文解析戦略（Syntactic Analysis Strategy）と呼び、特に内部DSLを構築するテクニックが豊富に語られています。&lt;/div&gt;&lt;br /&gt;セマンティックモデルから望みの結果を得るためのパターン群を総称して、出力生成戦略（Output Production Strategy）と呼びます。Code Generationはこのうちの1部分という位置づけです。&lt;br /&gt;&lt;br /&gt;ちなみに、ハートマークはFowler自身がセマンティックモデルを直接実行するスタイルを好んでいる印としてつけています。本命はセマンティックモデルの直接実行であり、コードジェネレーションは仕方なくやっている、という匂いが文章の端々から感じられるためです。&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Code Generation Patterns (What to produce)&lt;/span&gt;&lt;br /&gt;コード生成のためのパターンのうち、「何を（どのようなスタイルのコードを）生成するか」についてのパターンを示したスライドです。&lt;br /&gt;&lt;br /&gt;Model Ignorant Generationは、その名の通りモデルらしきものがまったく存在しないコードを生成するパターンです。モデルが持つ振る舞いはすべて、コードの中に手続きの形で平坦化されて埋めこまれます。これは、ターゲット環境がサポートする言語に抽象化能力が乏しく、モデルが構成できない場合や、モデルを実体化できるほどメモリリソースに余裕がない場合にある意味仕方なく取られるパターンです。もちろんFowlerはあまり好んではいません。&lt;br /&gt;&lt;br /&gt;Model Aware Generationは、ターゲット環境上にも（限られた形態かもしれないものの）モデルを構築し、モデルを操作する形のコードを生成するパターンです。Fowlerお気にです。&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Code Generation Patterns (How to produce)&lt;/span&gt;&lt;br /&gt;続いて、「どうコードを生成するか」についてのパターンを示したスライドです。「どう作るか」は「何を作るか」に強く依存することに注意が必要です。&lt;br /&gt;&lt;br /&gt;Templated Generationは、テンプレートエンジンを使ってコード出力するパターンです。生成対象となるコードで静的に決定される部分が多い場合に有効です。Model Ignorant Generationを使う場合、平坦化されたコードが一定のパターンで繰り返されることが多いため、このパターンが向いています。通常テンプレートエンジンは複雑な制御機構を持っていないため、分岐や選択が入り組んだ複雑な生成には向きません。&lt;br /&gt;&lt;br /&gt;Transformer Generationは、モデルを変換するコードをカスタムで作るパターンであり、要はTemplated Generation以外の場合を指しています。複雑な制御が必要であったり、コードに動的に決定される部分が多い場合に向いています。Model Aware Generationを使う場合、コードの記述は最小限となり、繰り返しも少なく静的に決定される部分も小さいため、このアプローチが向いています。&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Language Workbenches&lt;/span&gt;&lt;br /&gt;言語ワークベンチは、「独自のカスタムDSLを容易に構築できるようにしてくれる環境」です。さらに次のスライドで、言語ワークベンチに共通する要素を紹介しています。FowlerのDSL概念と似た形はとっていますが、異なる部分もいくつかあります。&lt;br /&gt;&lt;br /&gt;最も大きな違いは、セマンティックモデルが振る舞いを持つことはほとんどなく、必要な振る舞いはコードジェネレーションのプロセスでテンプレートエンジンによって埋め込まれる点です。&lt;br /&gt;セマンティックモデルが振る舞いを持たないのは、言語ワークベンチが汎用的・統一的に個々のセマンティックモデルを扱えるようにするために「メタモデル」を用意した（せざるを得なかった）のが主な原因のようです。あまり詳しくはないのですが、メタモデルに汎用的な振る舞いの表現を埋め込むのは確かに難しそうです。&lt;br /&gt;&lt;br /&gt;もう一つは、セマンティックモデルを様々な方法で視覚化したり、編集したりできる編集環境が用意されている点です。自分が見たツールでは、メタモデルと関連づけながら独自エディタを生成するための開発環境が用意されていました。&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;MOFとの関係&lt;/span&gt;&lt;br /&gt;最後のMOFとの関連はおまけみたいなもんです。とりあえずMOFは忘れてよし！&lt;br /&gt;&lt;br /&gt;手抜きで字だらけなのであまり分かりやすくはないと思いますが…&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=lifeinshin-22&amp;o=9&amp;p=8&amp;l=as1&amp;asins=0321712943&amp;ref=qf_sp_asin_til&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=000000&amp;bg1=FFFFFF&amp;f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-2546247552592402249?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/2546247552592402249/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=2546247552592402249&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/2546247552592402249'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/2546247552592402249'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2011/04/code-generation-language-workbenchesdsl.html' title='Code Generation &amp; Language Workbenches＠DSL読書会'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-971107865601352436</id><published>2010-09-19T15:17:00.003+09:00</published><updated>2011-04-14T01:57:34.809+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tips'/><category scheme='http://www.blogger.com/atom/ns#' term='dsl'/><title type='text'>外部DSL実装のためのAntlrチュートリアル</title><content type='html'>昨日、JavaEE勉強会で外部DSL実装に向けたAntlrのチュートリアルをやってきた。&lt;br /&gt;&lt;div id="__ss_5221932" style="width: 425px;"&gt;&lt;strong style="display: block; margin: 12px 0 4px;"&gt;&lt;a href="http://www.slideshare.net/kentaro714/antlrworks-for-dsl" title="AntlrWorks for DSL"&gt;AntlrWorks for DSL&lt;/a&gt;&lt;/strong&gt;&lt;object height="355" id="__sse5221932" width="425"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=antlrworks-100917080049-phpapp01&amp;stripped_title=antlrworks-for-dsl&amp;userName=kentaro714" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed name="__sse5221932" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=antlrworks-100917080049-phpapp01&amp;stripped_title=antlrworks-for-dsl&amp;userName=kentaro714" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;div style="padding: 5px 0 12px;"&gt;View more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/kentaro714"&gt;kentaro watanabe&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;JavaEE勉強会では今Fowler DSL本の読書会をやっており、導入、内部DSLを終え、外部DSLもほぼ終わったあたり（全体だと2/3くらい？）まで来ている。過去内部DSLが終わった際には、理解を深めるために各自で内部DSLを実装して発表するハンズオンを開催している。外部DSLでも同様のハンズオンが開かれる予定で、このチュートリアルはそのための準備という位置づけ。&lt;br /&gt;&lt;br /&gt;実際やってみると、以下のようなファイルの保存先パスに日本語が入っているとNGになるケースがあった模様。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;AntlrWorksのJAR保存先 &lt;/li&gt;&lt;li&gt;文法ファイル（*.g）の保存先&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;また、文法ファイル名と文法名（文法ファイルの先頭に定義された「grammer」に続く定義）が不一致なため、デバッグ時の自動コンパイルで失敗している人もいた。注意注意。&lt;/div&gt;&lt;br /&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=lifeinshin-22&amp;o=9&amp;p=8&amp;l=as1&amp;asins=0978739256&amp;ref=qf_sp_asin_til&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=000000&amp;bg1=FFFFFF&amp;f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"&gt;&lt;/iframe&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=lifeinshin-22&amp;o=9&amp;p=8&amp;l=as1&amp;asins=0321712943&amp;ref=qf_sp_asin_til&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=000000&amp;bg1=FFFFFF&amp;f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-971107865601352436?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/971107865601352436/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=971107865601352436&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/971107865601352436'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/971107865601352436'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2010/09/dslantlr.html' title='外部DSL実装のためのAntlrチュートリアル'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-3570439208933321677</id><published>2010-09-19T15:00:00.001+09:00</published><updated>2011-04-14T01:59:57.916+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dsl'/><title type='text'>Fowler DSLのエッセンス</title><content type='html'>とあることからFowler DSLのエッセンスを考える機会があり、昔内輪向けに作った資料を引っ張りだして眺めてみたが、わりと良い線いってると思う。&lt;br /&gt;&lt;br /&gt;&lt;div id="__ss_3299075" style="width: 425px;"&gt;&lt;strong style="display: block; margin: 12px 0 4px;"&gt;&lt;a href="http://www.slideshare.net/kentaro714/dsl-3299075" title="HEAD FIRST DSL"&gt;HEAD FIRST DSL&lt;/a&gt;&lt;/strong&gt;&lt;object height="355" id="__sse3299075" width="425"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=dsl-100228074316-phpapp01&amp;amp;stripped_title=dsl-3299075&amp;amp;userName=kentaro714"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;embed name="__sse3299075" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=dsl-100228074316-phpapp01&amp;amp;stripped_title=dsl-3299075&amp;amp;userName=kentaro714" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;div style="padding: 5px 0 12px;"&gt;View more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/kentaro714"&gt;kentaro watanabe&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;FowlerのDSL本が提示する価値は、おおまかに以下の3点にある。上記のスライドでは1と2にフォーカスしている。&lt;br /&gt;&lt;ol&gt;&lt;li&gt;モデルを中心に据えた思想の提示&lt;/li&gt;&lt;li&gt;実装スタイルの分類&lt;/li&gt;&lt;li&gt;実装テクニック集&lt;/li&gt;&lt;/ol&gt;これは、紙幅の大半が3に割かれており、書いた時点では実装テクニックを全て把握していなかったことや、そもそも3はまとめがほぼ不可能、ということもあった。&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;モデルを中心に据えた思想の提示&lt;/span&gt;&lt;br /&gt;従来のDSLでは、スクリプトによるモデルの組み立て、という考えが必ずしも明示的に意識されておらず、DSLがもたらす価値の源泉はDSL自身にある、と考える傾向が強かった。&lt;br /&gt;FowlerのDSL本では、&lt;u&gt;DSLによってモデルを組み立てる&lt;/u&gt;という点が非常に重視されている。DSLでモデルを構築する場合、今まではDSLによってもたらされている、と思われていた価値の多くは、実際はDSLによってではなくモデルによってもたらされている、ということがわかってくる。&lt;br /&gt;DSLの価値は、モデルによってもたらされる価値を高めることにある。&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;実装スタイルの分類&lt;/span&gt;&lt;br /&gt;これは、最近DSLについて書かれた文章ではほぼ常に述べられている内容で、実装スタイルを以下の2つに分類する、というもの。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;内部DSL&lt;/li&gt;&lt;li&gt;外部DSL&lt;/li&gt;&lt;/ul&gt;スライドだと言語ワークベンチを第３の実装スタイルにしていたが、言語ワークベンチは外部DSLの実装をサポートするためのツールという位置づけかと思う。&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;実装テクニック集&lt;/span&gt;&lt;br /&gt;内部DSL向け、外部DSL向け、共通トピック数多くのパターンが記述されており、DSL実装のためのパタンランゲージが構成されている。少なくとも、普段の仕事でこれらの語彙が使えるようになると非常に助かる。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;本の大半を読み終えてみて、1, 2について付け足したいことがあるとすれば、以下の概念同士の関係の補足だろうか。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;意味論モデル&lt;/li&gt;&lt;li&gt;（ドメインモデルを含む従来の）モデル&lt;/li&gt;&lt;li&gt;アクティブモデル&lt;/li&gt;&lt;li&gt;代替計算モデル&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;意味論モデル&lt;/span&gt;&lt;/div&gt;&lt;div&gt;意味論モデルは、一般のモデルをDSLの観点から構築対象として見た時の名称／概念。&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;意味論モデルは、従来のモデルである。&lt;/li&gt;&lt;li&gt;意味論モデルは、アクティブモデルである場合がある。&lt;/li&gt;&lt;li&gt;意味論モデルは、代替計算モデルを表す場合がある。この場合、意味論モデルはアクティブモデルである。&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;従来のモデル&lt;/span&gt;&lt;/div&gt;&lt;div&gt;最も一般的／汎用的なモデル概念。&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;従来のモデルは、意味論モデルである場合がある。&lt;/li&gt;&lt;li&gt;従来のモデルは、アクティブモデルである場合がある。&lt;/li&gt;&lt;li&gt;従来のモデルは、代替計算モデルを表す場合がある。&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;アクティブモデル&lt;/span&gt;&lt;/div&gt;&lt;div&gt;アクティブモデルは、従来のモデルであるが、インスタンス間の関係が変わるとモデル全体の振る舞いがきわめて大きく変更されるモデルのこと。この性質によって、個々のモデル要素の変更なしに、モデル構成を変更するだけで様々な計算を行うことができる。&lt;/div&gt;&lt;div&gt;語源はOOの「アクティブオブジェクトモデル」だが、オブジェクトパラダイムである必要はないため、アクティブモデルとした。&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;アクティブモデルは、従来のモデルである。&lt;/li&gt;&lt;li&gt;アクティブモデルは、意味論モデルである場合がある。&lt;/li&gt;&lt;li&gt;アクティブモデルは、代替計算モデルを表す場合がある。&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;代替計算モデル&lt;/span&gt;&lt;/div&gt;&lt;div&gt;命令型計算モデル以外の計算モデル。計算モデルとは、ざっくり言えば計算を表す方法を指す。&lt;/div&gt;&lt;div&gt;命令型計算モデルは、個々の計算ステップを逐次／選択／繰り返しといった制御フローを使って並べることで計算を表すモデル。これ以外の計算モデルとして、「デシジョンテーブル」「ステートマシン」「プロダクションルールシステム」などがあげられている。&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;代替計算モデルは、アクティブモデルで表現される場合がある。&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;20110414追記：ドラフト版では「アクティブモデル」と「アダプティブモデル」の間で揺れていた用語は、出版版では「アダプティブモデル」に統一されています。&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=lifeinshin-22&amp;amp;o=9&amp;amp;p=8&amp;amp;l=as1&amp;amp;asins=0978739256&amp;amp;ref=qf_sp_asin_til&amp;amp;fc1=000000&amp;amp;IS2=1&amp;amp;lt1=_blank&amp;amp;m=amazon&amp;amp;lc1=0000FF&amp;amp;bc1=000000&amp;amp;bg1=FFFFFF&amp;amp;f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"&gt;&lt;/iframe&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=lifeinshin-22&amp;amp;o=9&amp;amp;p=8&amp;amp;l=as1&amp;amp;asins=0321712943&amp;amp;ref=qf_sp_asin_til&amp;amp;fc1=000000&amp;amp;IS2=1&amp;amp;lt1=_blank&amp;amp;m=amazon&amp;amp;lc1=0000FF&amp;amp;bc1=000000&amp;amp;bg1=FFFFFF&amp;amp;f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"&gt;&lt;/iframe&gt;&lt;script src="http://b.scorecardresearch.com/beacon.js?c1=7&amp;amp;c2=7400849&amp;amp;c3=1&amp;amp;c4=&amp;amp;c5=&amp;amp;c6="&gt;&lt;/script&gt;&lt;script src="http://b.scorecardresearch.com/beacon.js?c1=7&amp;amp;c2=7400849&amp;amp;c3=1&amp;amp;c4=&amp;amp;c5=&amp;amp;c6="&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-3570439208933321677?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/3570439208933321677/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=3570439208933321677&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/3570439208933321677'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/3570439208933321677'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2010/09/fowler-dsl.html' title='Fowler DSLのエッセンス'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-3423918943586888738</id><published>2010-02-21T01:55:00.000+09:00</published><updated>2010-02-21T01:55:47.752+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ddd'/><title type='text'>デブサミ2010 - 出張！DDD難民救済キャンプで話してきました</title><content type='html'>DDD読書会＠JavaEE勉強会代表として、「DDD難民に捧ぐ」の佐藤さん、読書会主催syの角田さん、思想系プログラマの和智さん、モデレータのt-wadaさんと一緒にパネルをさせていただきました。&lt;br /&gt;推進派の佐藤さん、懐疑派の角田さん、受託開発現場の立場から自分、言葉を重視する立場から和智さんと、短い時間ながら立場を明確にしたパネルができたと思っています。&lt;br /&gt;&lt;br /&gt;&lt;div id="__ss_3222312" style="text-align: left; width: 425px;"&gt;&lt;a href="http://www.slideshare.net/kentaro714/19b5ddd-3222312" style="display: block; font: 14px Helvetica,Arial,Sans-serif; margin: 12px 0 3px 0; text-decoration: underline;" title="【19-B-5】出張！DDD難民救済キャンプ"&gt;【19-B-5】出張！DDD難民救済キャンプ&lt;/a&gt;&lt;object height="355" style="margin: 0px;" width="425"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=random-100218234036-phpapp02&amp;stripped_title=19b5ddd-3222312" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=random-100218234036-phpapp02&amp;stripped_title=19b5ddd-3222312" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;div style="font-family: tahoma,arial; font-size: 11px; height: 26px; padding-top: 2px;"&gt;View more &lt;a href="http://www.slideshare.net/" style="text-decoration: underline;"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/kentaro714" style="text-decoration: underline;"&gt;kentaro714&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;パネルの内容自体に関しては、SlideShareをながめながらtsudaってくれた方のTweet（#devsumi2010ハッシュタグ）を眺めれば、おおよその話は見えてくると思います。特に@yattom さんがとても詳細にtsudaってくださっています。&lt;br /&gt;# yattomさんありがとうございます！&lt;br /&gt;というわけで、ここでは内容について書くかわりに、パネルができる過程で起きた「ZENに導かれたブレイクスルー」とでもいうべき転換点について書き残しておきます。&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;&lt;b&gt;ZENに導かれたブレイクスルー&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;当日パネルでお話した内容のほかにも、DDDについて話したいことは山ほどありまして、打ち合わせの段階ではThe bookについてのより体系的な紹介や、最近のDDDコミュニティの広がり、実装レベルの具体的な話、BDDやTDD、DSL、PoEAA、アナリシスパターンなど他のアプローチとの関係などなど多くのトピックが候補としてあげられていました。&lt;br /&gt;# 機会があればこれらも何かしらの形でまとめられれば、と思いますが&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;パネルのタイトルは「出張！DDD難民救済キャンプ」なので、当初はパネルを聞いた人ができる限りDDDの内容を持って帰れることを目指して進めていました。が、これらの内容を50分で、しかもパネルの形式で伝えきるのは明らかに無理があります。やればやるほどパネル形式を取る意味がわからなくなってきて、一度行き詰まりました。&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;スライドを見ればわかるとおり、僕らはプレゼンテーションZEN廚状態でした。&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;「PCから離れよう」&lt;/span&gt;&lt;br /&gt;このZENの教えに従い、僕らは一度PCを閉じ、これまでの方針を忘れて一から考え直すことにしました。&lt;br /&gt;&lt;br /&gt;今回のパネルでは、ZENの言う&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;主要なメッセージ&lt;/span&gt;は一体何になるのか？つまり、来てくれた人が会場を出るときに持っていて欲しいものは一体何なのか？複数人が議論する「パネル」という形式でも主要なメッセージというのは可能なのか？パネリストがそれぞれ違う意見を持っているのではないか？それぞれが伝えたいことは何なのか？考えの違いを超えて伝えたいことはあるのか？&lt;br /&gt;&lt;br /&gt;こうして考えた結果、The bookの内容紹介やDDDの近況については思い切って省略し、かわりにDDDに対する自分たちのポジションを明確に打ち出す方向に転換しました。その上で、個々のメッセージを超えて、会場に来てくれた人に「ちょっとDDDについて調べてみようか」と思ってもらえるようにしたい。これが僕らのメッセージであり、このことに気づいたこの出来事が僕たちにとっての&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;ブレイクスルー&lt;/span&gt;だった、ということになっています。この思いが暴走した結果、「１、２、３、ディーーー！」みたいな事故が起きたわけですがw&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;&lt;b&gt;DDDをはじめてみよう！&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;実際のところ、どうだったんでしょう？メッセージ、伝わったんでしょうか？僕らはただの痛い人になってしまったんでしょうか？痛い人なのは全然かまわないんですが、少しでもDDDに興味を持ってくれる人がいたなら幸甚です。&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-3423918943586888738?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/3423918943586888738/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=3423918943586888738&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/3423918943586888738'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/3423918943586888738'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2010/02/2010-ddd.html' title='デブサミ2010 - 出張！DDD難民救済キャンプで話してきました'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-4849741393913690560</id><published>2010-02-17T13:04:00.000+09:00</published><updated>2010-02-17T13:04:35.616+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='book'/><title type='text'>共訳させていただいた「実用Git」が発売になります</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.amazon.co.jp/gp/product/4873114403?ie=UTF8&amp;amp;tag=lifeinshin-22&amp;amp;linkCode=as2&amp;amp;camp=247&amp;amp;creative=7399&amp;amp;creativeASIN=4873114403" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://www.oreilly.co.jp/books/images/picture978-4-87311-440-8.gif" /&gt;&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.jp/e/ir?t=lifeinshin-22&amp;amp;l=as2&amp;amp;o=9&amp;amp;a=4873114403" style="border: none !important; margin: 0px !important;" width="1" /&gt;&lt;/div&gt;&lt;br /&gt;このたび発売になる「実用Git」を、&lt;a href="http://d.hatena.ne.jp/hiratara/"&gt;hirataraさん&lt;/a&gt;、&lt;a href="http://d.hatena.ne.jp/kaiseh/"&gt;kaisehさん&lt;/a&gt;と共訳させていただきました。きょう配本だそうなので、ぼちぼち書店に並ぶのではないかと思います。&lt;br /&gt;&lt;br /&gt;この本は、前から順番に読みつつ出てくるコマンドを叩いていくことで、自然とGitが内部構造も含めてわかるようになっていることが特徴です。Gitを理解するには内部構造を知ることが近道なのですが、概念的な話だけでは頭に入ってきません。この本では、実際にリポジトリを用意し、コマンドを順に試していくことで、日常の作業と内部構造がつながりをもって理解できるように構成されています。&lt;br /&gt;コマンド出力も丁寧に載せられているので、Git環境が手元にない場合でも、実際にGitを使っているように学ぶことができます。&lt;br /&gt;&lt;br /&gt;自分自身、この翻訳をはじめた時は特にGitに詳しいわけではありませんでした。しかし、翻訳をすすめてGitを理解するにつれて、バージョン管理システムをもっとうまく使うことで、今の開発をよりよくできることに気づきました。いま開発でCSV/Subversionをなんとなく使っている人も、この本を読むことで開発をよりよくする道が見えるのではないかと思います。カオスなソースコード管理に悩んでいる人にもおすすめできる本です。興味がわきましたら、ぜひ読んでみてください。&lt;br /&gt;&lt;br /&gt;ちなみに、本には直接関係ありませんが、この本の翻訳もGitを使って進められました。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;翻訳者3人による編集&lt;/li&gt;&lt;li&gt;監訳者吉藤さんによる監訳&lt;/li&gt;&lt;li&gt;オライリー・ジャパンの宮川さんによる編集&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;こうした分散作業をGitで行っています。もしこういう仕事の進め方に興味がわいたなら、日本語版で追加された、瀧内元気さんによる「GitHub入門」や、hirataraさんによる「Gitにおける日本語の利用」が役に立つかもしれません。&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-4849741393913690560?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/4849741393913690560/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=4849741393913690560&amp;isPopup=true' title='2 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/4849741393913690560'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/4849741393913690560'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2010/02/git.html' title='共訳させていただいた「実用Git」が発売になります'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-7688915409194811264</id><published>2009-12-19T18:00:00.012+09:00</published><updated>2009-12-25T11:50:10.070+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='ddd'/><title type='text'>モデル上に明示されたトランザクションとしてのAggregate</title><content type='html'>&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;最初に読んだ時には今ひとつ理解できなかったAggregate。社内のDDD読書会で読み返してみて感じたのは、「Aggregateは、従来の手続き的な一貫性維持に関する情報（トランザクションスコープ含む）をモデル上に明示したものである」と捉えることで理解しやすくなる、ということ。以下もう少し詳しくみていく。&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;b&gt;&lt;span style="font-size: x-large;"&gt;Aggregateの定義と位置づけ&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;DDDのGlossaryを見るとAggregateは、&lt;br /&gt;&lt;/div&gt;&lt;blockquote&gt;A cluster of associated objects that are treated as a unit for the purpose of data changes. External references are restricted to one member of the AGGREGATE, designated as the root. A set of consistency rules applies within the AGGREGATE'S boundaries.&lt;br /&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;i&gt;データ変更を行う上で1単位として扱う必要があるような、相互に関連するオブジェクト群。外部からのAGGREGATEへの参照は、ルートとして識別されたものだけに制限される。一貫性を保つためのルールの集合は、AGGREGATE境界の内部に対して適用される。&lt;/i&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;このように説明されており、データの一貫性を保つ単位であることが強調されている。しかし、本を流し読みしただけでは、Repositoryと同レベルのビルディングブロックとして扱うほどの重要性は感じない。冒頭に述べたとおり、Aggregateの位置づけやその重要性は、従来のトランザクション設計と対比させることでわかりやすくなるのではないかと思う。&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;b&gt;&lt;span style="font-size: x-large;"&gt;手続き型トランザクション&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;まず最初に、従来の手続き型アプリケーションでのトランザクション設計を考えてみたい。従来自分が行っていた典型的なトランザクション設計は、手続きの範囲を指定することでトランザクションスコープを設定し、その内部で主にデータモデルに対して楽観・悲観の同時実行制御を行う、というものだった。DDDの構成要素で言えば、アプリケーション層のService（のメソッド）をトランザクション境界として設計し、SQLやストアドプロシージャでロックをかけることが多い。&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;DDDのAggregateで紹介されている、注文（PurchaseOrder）、注文明細（PurchaseOrderLineItem）、商品（Product）の例を使った例を考えてみる。&lt;br /&gt;&lt;br /&gt;[単純な注文のモデル]&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://yuml.me/diagram/scruffy/class/%5BPurchaseOrder%5D1-1..*%3C%3E%5BPurchaseOrderLineItem%5D,%20%5BPurchaseOrderLineItem%5D*-%3E1%5BProduct%5D" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="37" src="http://yuml.me/diagram/scruffy/class/%5BPurchaseOrder%5D1-1..*%3C%3E%5BPurchaseOrderLineItem%5D,%20%5BPurchaseOrderLineItem%5D*-%3E1%5BProduct%5D" width="400" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;（残念ながら自分が）よく見るコードはこんな感じだろうか。&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;[AddPurchaseOrderLineItemService]&lt;br /&gt;&lt;/div&gt;&lt;pre class="prettyprint"&gt;public class AddPurchaseOrderLineItemService {&lt;br /&gt;    @Transactional&lt;br /&gt;    public void addNewItem(Command cmd) {&lt;br /&gt;        ...&lt;br /&gt;        // PurchaseOrderとPOLineItemを結合したオブジェクトのList&lt;br /&gt;        List&amp;lt;PurchaseOrderResult&amp;gt; porList = poDao.findForUpdate(criteria);&lt;br /&gt;        ...&lt;br /&gt;        PurchaseOrderLineItem newItem = new PurchaseOrderLineItem(poList.get(0).getId(), ...);&lt;br /&gt;        ...&lt;br /&gt;        // 内部ではinsert&lt;br /&gt;        if (porList.get(0).getLimit() &amp;gt;= (totalPrice(porList) + newItem.getPrice())) {&lt;br /&gt;            poLineItemDao.insert(newItem);&lt;br /&gt;        }&lt;br /&gt;        ...&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;上記のコードでは、一貫性維持に関する知識は…&lt;br /&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;一貫性維持の範囲&lt;/li&gt;&lt;ul&gt;&lt;li&gt;=&amp;gt; ApplicationService上の@Transactionalアノテーション&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;一貫性維持範囲内で守るべき不変式&lt;/li&gt;&lt;ul&gt;&lt;li&gt;=&amp;gt; if文の条件式&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;同時実行制御戦略&lt;/li&gt;&lt;ul&gt;&lt;li&gt;=&amp;gt; DAOのメソッドによるロック&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;これらの中に分散して存在し、モデル（データモデルorオブジェクトモデル）上ではまったく表現されていない。&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;さらに、ApplicationServiceはユーザーイベント単位に作成されることが多いため、同じモデル（ここではPurchaseOrder）の一貫性に関する情報であるにも関わらず、ユーザーイベントごとにも散逸してしまうことになる。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-weight: normal;"&gt;&lt;b&gt;&lt;span style="font-size: x-large;"&gt;一貫性の知識を手続きからモデルへ&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;DDDでは、ドメイン知識はドメイン層のモデルとして表現するのが原則であり、重要な知識であればモデル上で明示的に表現することを強く推奨している。この方針に沿って上記の問題を解決しようとすれば、自然とモデル上への一貫性を表現する単位の導入に辿り着く。具体的には…&lt;br /&gt;&lt;ul&gt;&lt;li&gt;一貫性維持の範囲&lt;/li&gt;&lt;ul&gt;&lt;li&gt;=&amp;gt; 維持範囲のモデル表現としてAggregateを導入する&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;一貫性維持範囲内で守るべき不変式&lt;/li&gt;&lt;ul&gt;&lt;li&gt;=&amp;gt; Aggregateルートの変更操作内に移動&lt;/li&gt;&lt;li&gt;=&amp;gt; グローバルなルールや、ユビキタス言語に登場すべきルールであれば、Rule/Specificationの導入を検討&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;同時実行制御戦略&lt;/li&gt;&lt;ul&gt;&lt;li&gt;=&amp;gt; モデル側で表現&lt;/li&gt;&lt;li&gt;=&amp;gt; ドメイン知識ではないので、外部に追い出す&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;以下、具体的に見ていく。&lt;br /&gt;&lt;br /&gt;&lt;b&gt;一貫性維持の範囲を明示&lt;/b&gt;&lt;br /&gt;最終的にはService上で手続きに対する一貫性制約を明示することにはなると思うが、まずはモデルに対して一貫性の維持範囲を設定し、必要に応じてそれらをServiceで調整する、という方針に転換する。今回の例で用いた言語（Java5 or later）ではAggregateを明示的に扱うことができないため、設計上の決めごとに加え、対応するRepositoryを作ることで間接的にAggregateを表現する。&lt;br /&gt;&lt;br /&gt;今回の例での一貫性維持単位、つまりAggregateを構成する要素は、PurchaseOrderとPurchaseOrderLineItemとする。ルートは当然PurchaseOrderになる。&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;現状のDAOでは、Aggregateの子であるPurchaseOrderLineItemを直接取得・変更するようになっているので、AggregateルートであるPurchaseOrderを取得するように変更し、名称もPurchaseOrderRepositoryに変更する。&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;[AddPurchaseOrderLineItemService]&lt;br /&gt;&lt;/div&gt;&lt;pre class="prettyprint"&gt;public class AddPurchaseOrderLineItemService {&lt;br /&gt;    @Transactional&lt;br /&gt;    public void addNewItem(Command cmd) {&lt;br /&gt;        ...&lt;br /&gt;        PurchaseOrder po = poRepository.findForUpdate(cmd.id);&lt;br /&gt;        ...&lt;br /&gt;        PurchaseOrderLineItem newItem = new PurchaseOrderLineItem(po.getId(), ...);&lt;br /&gt;        ...&lt;br /&gt;        if (po.getLimit() &amp;gt;= po.getTotal() + newItem.getPrice())) {&lt;br /&gt;            po.add(newItem);&lt;br /&gt;            poRepository.save();&lt;br /&gt;        }&lt;br /&gt;        ...&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;また、最低限一貫性を持たせねばならない範囲はPurchaseOrderのAggregateであるため、トランザクションスコープはPurchaseOrderの状態変更メソッドであるaddItemに設定する。トランザクション設定値としては、このAggregateが必要とする値を設定する。&lt;br /&gt;# 今回はデフォルト値のまま&lt;br /&gt;&lt;br /&gt;[PurchaseOrder]&lt;br /&gt;&lt;pre class="prettyprint"&gt;public class PurchaseOrder {&lt;br /&gt;    List items = Lists.newArrayList();&lt;br /&gt; &lt;br /&gt;    @Transactional&lt;br /&gt;    public void addItem(PurchaseOrderLineItem item) {&lt;br /&gt;        if (limitOver(item.getPrice())) {&lt;br /&gt;            throw new ...&lt;br /&gt;        }&lt;br /&gt;        items.add(item);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private boolean limitOver(int price) {&lt;br /&gt;        return (price + total) &amp;gt; limit;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;これで、呼び出し側がトランザクションを開始していなくても、PuchaseOrderが必要なトランザクションを設定できる。&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;b&gt;不変式をモデル内に移動&lt;/b&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;if文内の条件式をAggregateルートの変更操作内に（不変式として）移動させる。これで、ドメイン層のモデル上で表現された。&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;[PurchaseOrder]&lt;br /&gt;&lt;/div&gt;&lt;pre class="prettyprint"&gt;public class PurchaseOrder {&lt;br /&gt;    List items = Lists.newArrayList();&lt;br /&gt;&lt;br /&gt;    public void addItem(PurchaseOrderLineItem item) {&lt;br /&gt;        if (limitOver(item.getPrice())) {&lt;br /&gt;            throw new ...&lt;br /&gt;        }&lt;br /&gt;        items.add(item);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private boolean limitOver(int price) {&lt;br /&gt;        return (price + total) &amp;gt; limit;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;移動後のサービスには、重要な知識は何も残っていない。&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;[AddPurchaseOrderLineItemService]&lt;br /&gt;&lt;/div&gt;&lt;pre class="prettyprint"&gt;public class AddPurchaseOrderLineItemService {&lt;br /&gt;    @Transactional&lt;br /&gt;    public void addNewItem(Command cmd) {&lt;br /&gt;        ...&lt;br /&gt;        PurchaseOrder po = poRepository.findForUpdate(cmd.id);&lt;br /&gt;        ...&lt;br /&gt;        PurchaseOrderLineItem newItem = new PurchaseOrderLineItem(po.getId(), ...);&lt;br /&gt;        ...&lt;br /&gt;        poRepository.save();&lt;br /&gt;        ...&lt;br /&gt;        }&lt;br /&gt;}&lt;/pre&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;b&gt;同時実行制御戦略の場所を移動&lt;/b&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;同時実行制御戦略を、取得操作側ではなくEntity側に設定する。また、具体的な制御戦略はドメイン知識ではないので、モデルから追い出すのが良い。&lt;br /&gt;&lt;br /&gt;[PurchaseOrder]&lt;br /&gt;&lt;/div&gt;&lt;pre class="prettyprint"&gt;@Entity&lt;br /&gt;@org.hibernate.annotations.Entity(&lt;br /&gt;    optimistcLock = OptimisticLockType.VERSION&lt;br /&gt;)&lt;br /&gt;public class PurchaseOrder {&lt;br /&gt;    List items = Lists.newArrayList();&lt;br /&gt;    &lt;br /&gt;    public void addItem(PurchaseOrderLineItem item) {&lt;br /&gt;        if (limitOver(item.getPrice())) {&lt;br /&gt;            throw new ...&lt;br /&gt;        }&lt;br /&gt;    items.add(item);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private boolean limitOver(int price) {&lt;br /&gt;        return (price + total) &amp;gt; limit;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;# TODO:とはいえ、ここの記述はイメージで、この設定でPurchaseOrderLineItemを追加した場合にPurchaseOrderのVERSIONが更新されるようにできるかは未確認…Hibernate詳しくない^^;&lt;br /&gt;&lt;br /&gt;Repositoryのインタフェースからは、同時実行制御戦略を消す。&lt;br /&gt;&lt;br /&gt;[AddPurchaseOrderLineItemService]&lt;br /&gt;&lt;pre class="prettyprint"&gt;public class AddPurchaseOrderLineItemService {&lt;br /&gt;    @Transactional&lt;br /&gt;    public void addNewItem(Command cmd) {&lt;br /&gt;    ...&lt;br /&gt;    PurchaseOrder po = poRepository.find(cmd.id);&lt;br /&gt;    ...&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;b&gt;維持範囲の変更／調整&lt;/b&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;DDD本書では、一貫性の維持範囲内にProductを含めるかどうかという議論が出ており、以下のような論点から組み入れるのは好ましくない、という結論になっている。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;個々の注文を編集するためにProductまで同時実行制御の対象となってしまい、編集エラーが多発する&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Productは、PurchaseOrder/PurchaseOrderLineItemに比べてHigh-Contention&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Productのpriceが変更になった場合、過去のPurchaseOrderの金額に影響を与えたくない&lt;/li&gt;&lt;/ul&gt;これらはいずれもドメイン知識（もしくはそこから得られる洞察）であるため、ドメインモデルに反映したい。Aggregateを明示的に示し、PurchaseOrderAggregateからProductを除外しておくことで、こうした設計判断をモデル上で示すことができる。&lt;br /&gt;いずれにせよ、ProductをPurchaseOrderAggregateの子にすると、Productの変更をPurchaseOrder経由で行うことになり、これは明らかにおかしいので、ソフトウェア設計の視点からも当然の判断だと思う。&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;b&gt;&lt;span style="font-size: x-large;"&gt;手続き＋データのパラダイムでは&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;一貫性を保たねばならない範囲をモデル上に表現すべき、というのはオブジェクトモデルに限った話ではなく、データモデル上で明示するのも良いプラクティスだろう。DAOやストアドプロシージャなどデータモデルにアクセスする各処理は、こうしたモデルに関する情報に基づいて適宜一貫性を保つようにすることで、一貫性上の問題を起きづらくできる。&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-7688915409194811264?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/7688915409194811264/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=7688915409194811264&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/7688915409194811264'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/7688915409194811264'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2009/12/aggregate.html' title='モデル上に明示されたトランザクションとしてのAggregate'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-5872836131831785160</id><published>2009-12-12T00:50:00.007+09:00</published><updated>2010-01-23T01:31:37.774+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='雑記'/><title type='text'>KPT2009</title><content type='html'>というわけで、&lt;a href="http://hibituredure.blogspot.com/2008/12/kpt2008.html"&gt;2008のKPT&lt;/a&gt;および&lt;a href="http://hibituredure.blogspot.com/2009/12/kpt2008.html"&gt;2009年のTRY評価&lt;/a&gt;を踏まえた上での2009年の振り返り。&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;■ KEEP&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* 英語&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;日常の情報ソースを含めた多聴・多読&lt;/li&gt;&lt;li&gt;定期的な実務翻訳&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;* 体系的な学習&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;コンピュータ科学の不足部分学習&lt;/li&gt;&lt;li&gt;「モデル」とその扱いの学習&lt;/li&gt;&lt;li&gt;数学とそこそこ仲良くする、関わり続ける&lt;/li&gt;&lt;li&gt;DDDの学習&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;* 交流&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;内外の勉強会への参加&lt;/li&gt;&lt;li&gt;社内勉強会の開催&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;* 現場の改善&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;現場での設計プラクティスの改善&lt;/li&gt;&lt;li&gt;現場の洗脳（自分がやりたいことをやるための土壌作り）&lt;/li&gt;&lt;li&gt;コードの適正化への働きかけ&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;* 趣味&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;楽器を定期的にさわって楽しむ&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;■ PROBLEM&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;数学の基礎知識が圧倒的に不足。数学系の勉強会に出続けるのはつらい。技術士の一次にも不足。&lt;/li&gt;&lt;li&gt;精読とリスニングの力があまりあがっていない。基礎からやらねば。&lt;/li&gt;&lt;li&gt;満足いくようなソフトウェアを作れていない。何か1つ作りたい。&lt;/li&gt;&lt;li&gt;相変わらず趣味と料理が…orz。好きなことを学ぶのが趣味みたいなもんだが…。&lt;/li&gt;&lt;li&gt;会いたい人に会いにいけてない。躊躇してもしょうがない。&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;■ TRY&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* 英語&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;来年こそTOEICで900点！&lt;/li&gt;&lt;li&gt;精読の力を身につける。&lt;/li&gt;&lt;li&gt;リスニングの力をつけるために、シャドウイングをもっと実践する。&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;* 実務&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;自信を持って内外に紹介できるシステムを作る。&lt;/li&gt;&lt;li&gt;DDDのアイディアを使って、現場の開発を改善する。コードの可読性も向上させる。&lt;/li&gt;&lt;li&gt;ESBをうまく使ってみる。&lt;/li&gt;&lt;li&gt;機会があればDSLをうまく使ってみる。&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;* その他学習&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;より利用者側にフォーカスしたアーキテクチャの学習。The Timeless Way of Buildingのシステム版のようなもの。いかにシステムと人間が同居するのかを探求。&lt;/li&gt;&lt;li&gt;数学。まずは技術士試験用に基本的なところから。&lt;/li&gt;&lt;li&gt;OOの原典。どうも、原典を読まないと話が空転する場合があるようだ。&lt;/li&gt;&lt;li&gt;コンピュータ科学。どのあたりに行くかは未定…&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;* 社交／発信&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;社外での勉強会開催。一度くらいやってみたい。&lt;/li&gt;&lt;li&gt;何か役に立つソフトウェアを1つ作って公開。&lt;/li&gt;&lt;li&gt;会うべき人に会いにいく。&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;* 趣味&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;今年こそバンド。無理か？&lt;/li&gt;&lt;li&gt;年賀状を自作の絵で。無理か？&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;思いつく限りではこんなところ。あまり面白くない！てか地味なんだよ！&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-5872836131831785160?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/5872836131831785160/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=5872836131831785160&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/5872836131831785160'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/5872836131831785160'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2009/12/kpt2009.html' title='KPT2009'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-3447878717744011757</id><published>2009-12-12T00:01:00.008+09:00</published><updated>2009-12-12T01:22:49.449+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='雑記'/><title type='text'>2009年TRYの評価</title><content type='html'>&lt;div&gt;明日のJavaEE勉強会のポジペネタでもあるので、この機会に整理。まずは、&lt;a href="http://hibituredure.blogspot.com/2008/12/kpt2008.html"&gt;KPT2008&lt;/a&gt;のTRY（つまり2009年のTRY）の評価から。今年のTRYはこんなんでした。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;■TRY&lt;/div&gt;&lt;div&gt; * 英語により慣れる&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;今年はTOEIC 900点を目指したい&lt;/li&gt;&lt;li&gt; オリジナルが英語の情報は全部英語で読む&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt; * 交流をより増やす&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;OSSプロジェクトに参加する or 書籍出版に関わる&lt;/li&gt;&lt;li&gt;何という無理くささ&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt; * 体系的な勉強&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;ドメイン工学系（GenarativeProgramming =&gt; Multiparadigm Design）&lt;/li&gt;&lt;li&gt;ビジネスモデリング系（Ericsson-Penker =&gt; Analysis Patterns =&gt; Data Moedl Patterns）&lt;/li&gt;&lt;li&gt;DSL系（Fowler DSL Books WIP =&gt; Meta Programming System）&lt;/li&gt;&lt;li&gt;ビジネス系（会計～中小企業診断士を趣味的に）&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt; * 趣味&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;ベース楽しく弾く&lt;/li&gt;&lt;li&gt;できればアマ志向でバンド組んでスタジオで騒ぐ&lt;/li&gt;&lt;li&gt;かっくいいのかいてpixivとかに投稿してみたい&lt;/li&gt;&lt;li&gt;もっかい将棋はじめてもいいかなぁ&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt; * 料理&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;とりあえずペペロンチーノで乳化あたりから&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;&lt;b&gt;英語に慣れる&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;TOEICは900点には届かず。相変わらず、リスニングでの取りこぼしと、文法まわりのミスが目立つ。反面、リーディング部分はほぼ満点で、高速でざっくり流し読みする、というのは非常に得意になった。ここ数年、インプットとしての英語情報の量に圧倒されていたため、多少の精度は犠牲にしてとにかく高速で流し読みするスキルを鍛えてきた。このスキルをどうやら取得できたのは歓迎すべきことだ。長文の英語を読む前の、あの「ヤだなー」という感じや、読んでいるとすぐに疲れてくる感じはほとんどなくなり、日本語を読むのと近い感覚で読み進められるようになってきた。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;しかしながら、文法を含めた精読のスキルはあまり向上しておらず、特に実務翻訳を行う場合に苦労した。わかりづらい英文に対して、論理的に英語の意味を確定していく、という作業の精度が、流し読みのレベルに比べると低いのだ。&lt;/div&gt;&lt;div&gt;今後はリスニングとあわせて、精読のスキルを重点的に鍛えていきたい。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;&lt;b&gt;交流をより増やす&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;交流…増えたのかなぁ。層・圏・トポスや檜山さんのセミナーである程度増えたんだけど、最近予定が合わずにあまり行けてないからなぁ…。&lt;/div&gt;&lt;div&gt;交流する人数が劇的に増えているわけではないと思う。そもそもそういうタイプの人間でもないし。今交流がある人とのつきあいを大事にしつつ、機会をみつけてちょこちょこ手を伸ばしていく感じにしたい。&lt;/div&gt;&lt;div&gt;書籍の出版に関しては、層・圏・トポスのご縁からお手伝いさせてもらえることに。色々ご迷惑をおかけします。お世話になってます。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;&lt;b&gt;体系的な勉強&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;今年やった勉強は、こんなところ。&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;圏（基礎およびモナドまわり）&lt;/li&gt;&lt;li&gt;ラムダ計算（初等テキスト）&lt;/li&gt;&lt;li&gt;コンパイラ基礎（ふつパイラで）&lt;/li&gt;&lt;li&gt;DDD（書籍勉強会開催＋現場でいくつか実践）&lt;/li&gt;&lt;li&gt;DSL（JavaEE勉強会でFowlerのDSL本輪講中）&lt;/li&gt;&lt;li&gt;微積分（技術士向けに勉強はじめた程度）&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;ドメイン工学系やビジネスモデリング系はあまり進んでいない。去年力を入れていた、「システム全体」や「人間系＋コンピュータ系の複合システム全体」をうまく捉えるための、より広範・抽象的で多分に曖昧さを含む方向にはあまり手を伸ばさず、詳細・厳密な方向へ行っている印象。コンピュータ科学の専門教育受けてないので、専門知識や土台の不足を実感したのが主な要因か。来年はもう1度そっち方面に向かうかもしれない。&lt;/div&gt;&lt;div&gt;ビジネス系にまったく手を出せていないのは、自分には基礎的な技術の勉強とビジネス系の勉強を同時に進めるほどの器用さがないと悟ったから。仕事での必要性を考えると、基礎技術を固めるのが重要だと考えて、ビジネス系は優先順位を下げている。来年もそうなりそう。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;&lt;b&gt;趣味&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;ベースはちょこちょこさわっているけど、継続してやっている感じではないなぁ。面白い曲を見つけたら耳コピして演奏、楽しんで満足している程度。バンドを組むにはほど遠い。環境だけは整えたんだけど。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;絵については、好きな漫画をパクってイラスト描いてみたり、会議中に色々描いて（^^;）描くことに慣れるようにしているんだけど、あまりうまくなった感なし。描き散らしているだけで、きちんとした作品にするまで頑張れていないんだよなぁ。基本的なスキルも身に付いてない印象。絶対的に量が足りてない。とりあえず形から入る意味で、ペンタブでも買ってみようかと画策中。来年の年賀状（メール）は、手書きの絵を送りたいものだ。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;&lt;b&gt;料理&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;orz…iPhoneにクックパッド入れたよ！&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;全体的に見ると、趣味系がいまいち、あとはそこそこ頑張っているが満点では決してない、という感じか。トータル65点くらいかな。KPT2009に続きます。&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-3447878717744011757?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/3447878717744011757/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=3447878717744011757&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/3447878717744011757'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/3447878717744011757'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2009/12/kpt2008.html' title='2009年TRYの評価'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-2877885982499059996</id><published>2009-10-02T16:26:00.008+09:00</published><updated>2009-10-08T23:50:01.763+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='ddd'/><title type='text'>ユビキタス言語と日本語</title><content type='html'>数ヶ月前から社内でDDD勉強会を実施していて、最近「ユビキタス言語(Ubiquitous Language)」まで来たんだけど、ここでやっぱり「日本語を使ったら1つの言語、モデルになるのか？」という疑問が出てきた。JavaEE勉強会でも同様の意見が（確かhirataraさんから）出てきていたものの、残りの部分に答えが書いてある可能性もあったので、その時点では「まぁ、用語の一覧みたいなのを作ってなんとかすればいいんじゃないの？」と流したものの、あらためて同じ問題に直面してみると、なかなかやっかいな問題だ。先に進む前に、この時点での自分なりの結論を書いておく。&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;&lt;b&gt;DDDの世界観&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;まずは、DDDにおけるユビキタス言語やモデルの扱いについて簡単にまとめておく。&lt;/div&gt;&lt;div&gt;# 断るまでもないと思うけど、もちろん個人的な理解。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;ユビキタス言語はドメインモデルに基づく言語であり、ドメイン専門家と開発者の双方が作り、双方が使う。これら2つは一体となっており、片方が変更されればもう一方も変更される。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;ユビキタス言語が構成する世界−−言い換えれば、言語によって制限された物の見方−−がモデルであり、モデルは第一義的には概念上の存在である。わかりやすく言い換えると、モデルのマスターは頭の中に存在している、ってこと。これを文章やダイヤグラム、コードで表現することもできるけど、そうして表現されたものはすべてモデルの死体のようなもので、作った瞬間から古くなっていく。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;モデルが頭の中にしかないのであればユビキタス言語も同様で、会話の中にあらわれるものこそが第一義的な「ユビキタス言語」になる。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;僕たちはソフトウェアを開発したいので、モデルが頭の中にしかないってのはあまりうれしくない。最低でも（モデル表現としての）コードは必要になってくるけど、DDDではモデルを複数作らないのが原則だ。となると、コードの構造は頭の中のモデルを投影したものになり、コードはユビキタス言語で表現されることになる。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;DDDの世界観は、こんな感じ。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;&lt;b&gt;で、問題は何よ&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;日本で開発する場合、顧客と開発者の会話はふつう日本語で行われる。よって、ユビキタス言語は日本語として構築されることになる。&lt;/div&gt;&lt;div&gt;一方、プログラミング言語は通常英語（というよりは英数字）がベースだ。日本語プログラミング言語も存在しているが、少なくとも業務システムではほとんど使われていない。最近の言語はたいていUnicodeをサポートしているので、識別子として日本語を使えばいいじゃん、と思うかもしれないが、言語が持つ標準的なコーディングスタイルから著しく逸脱するので、信じられないほど可読性が低下する。&lt;/div&gt;&lt;div&gt;# 一度Javaでやってみたことがあるが、正直2度と読みたくない。&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;&lt;b&gt;どうするべき？&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;ここで取るべき道は2つ。&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;コードは英語、その他は日本語&lt;/li&gt;&lt;li&gt;コードはローマ字による日本語表現、その他も日本語&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;ここで、僕のような西洋かぶれは1番目の方法を選びたがるわけだけど、これはおそらく大きな誤りだ。&lt;/div&gt;&lt;div&gt;&lt;div&gt;英語と日本語は、単に文法や単語が違うだけではなく、世界の見方自体が異なっているので、どうやってもうまく対応させられない部分が出てくる。それがわかっていればまだ良い方で、うまく対応させたと思っているものの、実際は完全に間違えていることだって少なくない。そうした無理な変換によって、実質的にはモデルが2つできてしまいかねない。&lt;/div&gt;&lt;div&gt;そもそも母国語だけ使っていても、単一のモデルを（言語、文章、コードにわたって）維持するのは非常に困難なので、基本的な道具立てに撹乱要因が入るのはできればご遠慮願いたい。&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;2番目は、おそらく現場で一般的に取られている方法だろう。コードを見ると頭が痛くなるような識別子が並ぶことになるのだが、無理に英語を使って混乱するよりはまだマシだろう。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;&lt;b&gt;言語学との関連&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;実際のところ、一番興味深いと感じたのは、Evansのユビキタス言語に関する考え方が、最近読んだ言語学の本での言語に対する態度とかなり近いという点。言語として会話を重視する、といった態度のことね。考えてみれば当たり前なんだけど、言語の中には文字がないものだって存在するし、何より頻繁に変わっていく（設計のためのユビキタス言語のような）言語に追随するには、話されている生きた言語を捕える必要がある。&lt;/div&gt;&lt;div&gt;にもかかわらず、自分も含めて、言語を「紙に書かれた文字や文章」や「文法書」、「辞書」である、と考える人が異常に多いということに気づいて愕然としてしまった。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;b&gt;2009/10/8追記：&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;勉強会でさらに話し、名詞の厳格な扱いのおかげで概念をより厳密な言語（プログラム言語）に落とし込みやすい英語と比べ、日本語では概念を明確にしづらい…といった話が。結局、ユビキタス言語は混成言語（ピジン語）のようなものにせざるを得ないのかもしれない。ただし、文法の混成はかなり限定的になりそうだけど。&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-2877885982499059996?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/2877885982499059996/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=2877885982499059996&amp;isPopup=true' title='1 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/2877885982499059996'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/2877885982499059996'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2009/10/blog-post_02.html' title='ユビキタス言語と日本語'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-8529061341571754317</id><published>2009-10-01T13:48:00.008+09:00</published><updated>2009-10-07T15:27:34.521+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='system'/><title type='text'>コンテキストあれこれ</title><content type='html'>&lt;div&gt;知り合いのu1hoshinoががんばってAP設計のノウハウをまとめはじめたようです。手始めは&lt;a href="http://u1hoshino.wordpress.com/2009/09/21/%E3%82%B3%E3%83%B3%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88/"&gt;コンテキスト&lt;/a&gt;ですが、前半の概念を導入している部分でいろいろ消化不良感があったのでコメントに書こうと思ったのですが、長くなりそうだったのでこっちに書きます。脳内ダンプ的なものなので、特に結論はないです。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;&lt;b&gt;コンテキストって何&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;計算機の話に限定すれば、「コンテキスト」は「特定の計算における環境」だと言えます。ここで言う「環境」としては、広義には言語やランタイムを表すこともありますが、今回は（元記事の想定に基づいて）「変数と値のセット」に限定します。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;特定の計算を構成する命令（ステートメント）を、何かしらの形（関数、プロシージャ、クラス…）でモジュール化することを考えた場合、計算に必要な入力値すべてを引数や戻り値で渡せば、環境は不要になります。実際、純粋関数型言語ではこのようにして計算を組み立てます。しかし、モジュール（の複数の命令）をまたがって同じ情報を繰り返し参照するなら、その情報はパラメータで渡すのではなく、環境として設定してどこからでも参照できるようにすることで、モジュール間の結びつきが煩雑化するのをある程度抑えられます。これが、コンテキストを利用する比較的大きな理由だと思います。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;# 他方で、抽象化された「環境」を引数や戻り値として受け渡していくことで、副作用を排除しつつモジュールの煩雑化を防ぐ、モナドのようなアプローチもあります。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;&lt;b&gt;何故Webでコンテキストを作るのか？&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Javaで標準的なWebインフラ（Servlet）には、組み込みでリクエスト・セッション・アプリケーションなどのコンテキストオブジェクトが存在しており、自由に利用できます。&lt;/div&gt;&lt;div&gt;これらのコンテキストにはServlet内から自由にアクセスできるため、まさに「特定のリクエスト実行における環境」になっており、Servlet内部に命令を書いている限り、これらがまさにコンテキストとして機能したはずです。&lt;/div&gt;&lt;div&gt;しかし現状では、レイヤパターンの適用によってリクエスト処理を複数モジュールに分割し、Webレイヤ以外では上記のコンテキストは使えないように設計するのが一般的になりました。これによって、ビジネスロジックと呼ばれる命令群が特定インフラへ依存することは少なくなったものの、コンテキストの喪失によって最初に設定した問題が発生することになりました。これを解決するために、Web非依存の独自コンテキストを再設計している、というのが元記事で言うところの「コンテキスト」が誕生した経緯です。&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;&lt;b&gt;コンテキスト情報として何を設定する？&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;これは、計算の性質や、どのようにモジュール分割するかによって変わりそうです。また、リクエスト処理のコンテキスト設定がアプリケーションプログラム側で許可されていないケースも多く、基盤や（APじゃない）アーキテクチャが把握できる範囲となると、相当広範囲で共通的に使われるものに限られるケースが多くなります。結果的に、元記事でも書いてあるような&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;ユーザー情報&lt;/li&gt;&lt;li&gt;日付&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;などが多くなるわけですね。&lt;/div&gt;&lt;div&gt;また、コンテキスト情報として設定するものの中で、レイヤ指針に反するような内容を設定した場合、不適切な依存関係が発生する可能性があるので注意する必要があります。ビジネスロジックをインフラから切り離すためのレイヤ化だったのに、コンテキストに端末IDやIPアドレスが設定されていると、ロジックがこれらに依存する可能性があります。単なるデータとして扱っているうちは良いですが、不用意にインフラに特化した「型」に依存してしまうと、物理モジュールの管理が面倒になるので、注意が必要です。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;&lt;b&gt;結局&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;結局、「コンテキスト」が何で、どうして必要なのかを自分の中でもう少し整理しておきたかったというわけでした。書いてみると当たり前というか、しょーもない話ですね。&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-8529061341571754317?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/8529061341571754317/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=8529061341571754317&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/8529061341571754317'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/8529061341571754317'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2009/10/blog-post.html' title='コンテキストあれこれ'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-8286675406198015053</id><published>2009-06-29T13:34:00.005+09:00</published><updated>2009-06-29T13:44:31.701+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='セミナー/勉強会'/><category scheme='http://www.blogger.com/atom/ns#' term='数学'/><category scheme='http://www.blogger.com/atom/ns#' term='report'/><title type='text'>第4回「層・圏・トポス」読書会にいってきた</title><content type='html'>めでたく読書会が開催されるようになってから、めっきり自分で勉強しなくなってしまったんだけど、もともと数学的な知識や素養があるわけでもないので毎回結構辛い ^^; その辛い感じが結構楽しいんだけども。&lt;br /&gt;&lt;br /&gt;というわけで、今回から（iPhone3GSを買ったこともあり！）黒板を写真に撮ってきて、Descriptionつけながら復習することにした。Picasaにあげようかと思ったけど、iPhotoがFlickrに対応していてアップロードが楽だったので、Flickrにあげた。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/33201663@N07/sets/72157620683685222/"&gt;Flickr : 第4回 層・圏・トポス読書会&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;まだ半分くらいしかDescription書いていないけど、思い出しながら地道に埋めていく予定。ちなみに、読書会はGoogle Groupsも出来ました。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://groups.google.co.jp/group/sheaf-category-and-topos"&gt;Google Groups : 『層・圏・トポス』読者の会&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;謎の合宿（水着のおねえちゃん目当て？）も企画されているようなので、興味があれば是非。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-8286675406198015053?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/8286675406198015053/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=8286675406198015053&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/8286675406198015053'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/8286675406198015053'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2009/06/4.html' title='第4回「層・圏・トポス」読書会にいってきた'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-298443133501257982</id><published>2009-05-15T21:13:00.008+09:00</published><updated>2009-05-15T22:07:00.479+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='product'/><category scheme='http://www.blogger.com/atom/ns#' term='report'/><title type='text'>Poken[Rockstar]が来た。</title><content type='html'>&lt;span style="font-weight: bold;font-size:130%;" &gt;Poken 到着〜ユーザー登録&lt;/span&gt;&lt;br /&gt;QCon Tokyo 2009 のアンケートで当たったPokenが来た。こんなの。この子はどうも、&lt;a href="http://www.amazon.co.jp/gp/product/B0026DOI0C?ie=UTF8&amp;amp;tag=lifeinshin-22&amp;amp;linkCode=as2&amp;amp;camp=247&amp;amp;creative=7399&amp;amp;creativeASIN=B0026DOI0C"&gt;Rockstar&lt;/a&gt;&lt;img src="http://www.assoc-amazon.jp/e/ir?t=lifeinshin-22&amp;amp;l=as2&amp;amp;o=9&amp;amp;a=B0026DOI0C" alt="" style="border: medium none  ! important; margin: 0px ! important;" border="0" height="1" width="1" /&gt;っていうらしい。まぁまぁかわいい…よね？&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Sde1cTDCAXc/Sg1dgDOpfWI/AAAAAAAAA_k/V5wcyoMTIBs/s1600-h/DSCF1148.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_Sde1cTDCAXc/Sg1dgDOpfWI/AAAAAAAAA_k/V5wcyoMTIBs/s320/DSCF1148.JPG" alt="" id="BLOGGER_PHOTO_ID_5336023938707848546" border="0" /&gt;&lt;/a&gt;思ったよりずいぶん小さい。大きめの消しゴムくらいの大きさ。箱から出すと…&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Sde1cTDCAXc/Sg1dxs3eNVI/AAAAAAAAA_s/GknwQo-_Oc4/s1600-h/DSCF1149.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_Sde1cTDCAXc/Sg1dxs3eNVI/AAAAAAAAA_s/GknwQo-_Oc4/s320/DSCF1149.JPG" alt="" id="BLOGGER_PHOTO_ID_5336024241942705490" border="0" /&gt;&lt;/a&gt;こんな。コレ以外何も入っていない。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Sde1cTDCAXc/Sg1d7ppfqII/AAAAAAAAA_0/-M3hgEd06p0/s1600-h/DSCF1150.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_Sde1cTDCAXc/Sg1d7ppfqII/AAAAAAAAA_0/-M3hgEd06p0/s320/DSCF1150.JPG" alt="" id="BLOGGER_PHOTO_ID_5336024412877465730" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;キャップ（Rockster氏）を取ると、USB端子が。これをUSBポートに差し込むと、autorun が有効になっている（危険な）PCでは、Poken の登録サイトが表示される。&lt;br /&gt;autorun が無効になっている場合は、マスストレージになっているので、中に入って"Start_Poken.html"をブラウザで表示すればOK。&lt;br /&gt;# ちなみに、Chrome では正常に表示できない模様（友人談）。&lt;br /&gt;&lt;br /&gt;あとは、表示された Poken サイトで Poken 専用アカウントを作成し、個人情報をポチポチ入れていけば完了。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Pokenの仕組み&lt;/span&gt;&lt;br /&gt;"Start_Poken.html"の中を見てみると…&lt;br /&gt;&lt;pre class="prettyprint"&gt;&amp;lt;META http-equiv="Refresh" content="1;    URL=http://p.poken.ch/u/なんかデバイス固有のトークンっぽいもの-+の大量繰り返し"&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;てな感じになっている。http-equiv="Refresh" で自動的にサイトに接続される仕掛けのようだ。肝心の URL は、デバイストークンと-+の繰り返し。-+ の繰り返し部分にはおそらく、交換した名刺の情報が入るのだろう。Poken で情報を交換するたびに、Poken デバイスがこの URL を書き換えているのだと思われる。&lt;br /&gt;# このファイルは当然、ユーザーからは書き換え不能。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Poken on Mac&lt;/span&gt;&lt;br /&gt;初回接続（新規ユーザー登録）時には Poken サイト上に表示されているPoken デバイス接続状態を示すアイコンが正常に表示されておらず、もしかして Win + IE でしか使えないデバイス認識プラグインとか使ってるのか！？ と思ったが、2回目は正常に認識された。どうやら、デバイストークンが送付されていれば接続状態だと認識しているようだ。デバイスが接続されていても、トップページから普通に（"Start_Poken.html"を使わず）ログインすると、デバイスは認識されていなかった。&lt;br /&gt;というわけで、ネイティブ環境にアクセスできるプラグインを使っているわけでもなさそうだ。Mac ユーザーも安心。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;セキュリティ&lt;/span&gt;&lt;br /&gt;&lt;a href="http://d.hatena.ne.jp/okdt/20090418/1240011375"&gt;Poken/セキュリティ上のご注意 - オートログインはoff、でね。&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;仕組みのところで見たけど、接続先の scheme は https ではなくhttp になっている。上記のサイトではこれが問題視されてるんだけど、なんでだろう？情報は全部 URL で送っているんだから（それはそれで問題なわけだが）、SSL だろうがなんだろうが関係ない気がするけど。Poken サイト自体は SSL に対応しているし。昔は対応してなかったのかなぁ。セキュリティはあんま詳しくないからわからないんだけども。&lt;br /&gt;&lt;br /&gt;デバイストークンや交換した名刺の情報がURL経由で漏洩する可能性については、どうにもならないから割り切ってあきらめるしかなさそうだ。信頼できないネットワーク環境（Proxy含む）では使わないように心がけよう。&lt;br /&gt;&lt;br /&gt;さーて、誰か交換できる人見つかるかな。&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=lifeinshin-22&amp;amp;o=9&amp;amp;p=8&amp;amp;l=as1&amp;amp;asins=B0026DOI0C&amp;amp;md=1X69VDGQCMF7Z30FM082&amp;amp;fc1=000000&amp;amp;IS2=1&amp;amp;lt1=_top&amp;amp;m=amazon&amp;amp;lc1=0000FF&amp;amp;bc1=FFFFFF&amp;amp;bg1=FFFFFF&amp;amp;f=ifr&amp;amp;nou=1" style="width: 120px; height: 240px;" marginwidth="0" marginheight="0" frameborder="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-298443133501257982?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/298443133501257982/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=298443133501257982&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/298443133501257982'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/298443133501257982'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2009/05/pokenrockstar.html' title='Poken[Rockstar]が来た。'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_Sde1cTDCAXc/Sg1dgDOpfWI/AAAAAAAAA_k/V5wcyoMTIBs/s72-c/DSCF1148.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-2808836727077095335</id><published>2009-05-06T15:57:00.006+09:00</published><updated>2009-05-07T08:24:52.973+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='ddd'/><category scheme='http://www.blogger.com/atom/ns#' term='調べてみた'/><title type='text'>DDD Sample Application version1.1.0: ユースケーススライスから見たアプリケーション構造の確認（2）</title><content type='html'>前回は、シンプルな参照の機能が、サンプル上でどのように構成されているかを確認した。今回は、積荷の一覧・詳細表示で参照機能の構成を確認しつつ、積荷の新規登録・状態更新まで確認してみたい。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;s&gt;配送状況の詳細表示&lt;/s&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;積荷の一覧・詳細表示&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li style="font-weight: bold;"&gt;積荷の新規登録&lt;/li&gt;&lt;li style="font-weight: bold;"&gt;積荷の状態更新&lt;/li&gt;&lt;li&gt;配送ルート候補検索&lt;/li&gt;&lt;li&gt;積荷への配送ルート設定&lt;/li&gt;&lt;li&gt;配送状況の更新&lt;/li&gt;&lt;li&gt;配送状況の更新（バッチ）&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;積荷一覧・詳細表示の概要&lt;/span&gt;&lt;br /&gt;これは、商品発送側が現在管理対象になっている積荷の情報を確認するためのもの。おなじみの一覧・詳細表示アプリだ。アプリケーション内では、Booking と呼ばれている。Booking （Trackingもそうだが）はコンテキストなのだろうか？&lt;br /&gt;この機能は、一見すると配送状況の詳細表示と同じように思えるが、内部的には異なった作りになっており、Web層の Controller からリモートサービスとして構成された BookingServiceFacade を呼び出す形になっている。&lt;br /&gt;&lt;br /&gt;&lt;img src="http://yuml.me/diagram/class/%5BCargoAdminController%5D-%3E%5BBookingServiceFacade%5D,%5BBookingServiceFacade%5D-%3E%5BBookingService%5D,%5BBookingServiceFacade%5D-%3E%5BLocationRepository%5D,%5BBookingServiceFacade%5D-%3E%5BCargoRepository%5D,%5BBookingServiceFacade%5D-%3E%5BVoyageRepository%5D,%5BBookingService%5D-%3E%5BCargoRepository%5D,%5BBookingService%5D-%3E%5BLocationRepository%5D,%5BBookingService%5D-%3E%5BRoutingService%5D" width="100%" /&gt;&lt;br /&gt;&lt;br /&gt;BookingServiceFacadeの先も、前回のように単純にRepositoryを呼ぶだけではなく Application層（BookingService）を経由しているため、多少複雑な構成になっている。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;積荷の一覧・詳細表示&lt;/span&gt;&lt;br /&gt;よくあるエンティティの一覧・詳細表示。検索の種類が違うだけで、アプリケーションの構成はどちらもほとんど同じ。なので、ここでは一覧検索だけを見ていくこととする。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;INTERFACES&lt;/span&gt;&lt;br /&gt;エントリポイントは、上記の図でわかるとおり interafaces パッケージの CargoAdminController。&lt;br /&gt;&lt;br /&gt;[CargoAdminController]&lt;pre class="prettyprint"&gt;public final class CargoAdminController extends MultiActionController {&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;このクラスは Spring WebMVC のMultiActionController を継承しているが、これは複数のリクエストを1つのController で処理するためのクラス。デフォルトでは、リクエストURIのスラッシュで区切られた末尾部分と同じ名前のメソッドを呼び出す。その他は SimpleFormController と大差ない。&lt;br /&gt;&lt;br /&gt;一覧表示は index.jsp から「/admin/list」で呼び出されているが、「/admin」は web.xml で BookingDispatcherServlet に割り当てられており、booking-servlet.xml 経由で上述のCargoAdminControllerに割り振られ、最終的に list メソッドが呼び出されている。&lt;br /&gt;&lt;br /&gt;[CargoAdminController#list]&lt;pre class="prettyprint"&gt;  public Map list(HttpServletRequest request, HttpServletResponse response) throws Exception {&lt;br /&gt;    Map&lt;string,&gt; map = new HashMap&lt;string,&gt;();&lt;br /&gt;    List&lt;cargoroutingdto&gt; cargoList = bookingServiceFacade.listAllCargos();&lt;br /&gt;&lt;br /&gt;    map.put("cargoList", cargoList);&lt;br /&gt;    return map;&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;BookingServiceFacade#listAllCargos() を呼び直しているだけだ。&lt;br /&gt;&lt;br /&gt;[BookingServiceFacadeImpl#listAllCargos]&lt;pre class="prettyprint"&gt;  public List&lt;cargoroutingdto&gt; listAllCargos() {&lt;br /&gt;    final List&lt;cargo&gt; cargoList = cargoRepository.findAll();&lt;br /&gt;    final List&lt;cargoroutingdto&gt; dtoList = new ArrayList&lt;cargoroutingdto&gt;(cargoList.size());&lt;br /&gt;    final CargoRoutingDTOAssembler assembler = new CargoRoutingDTOAssembler();&lt;br /&gt;    for (Cargo cargo : cargoList) {&lt;br /&gt;      dtoList.add(assembler.toDTO(cargo));&lt;br /&gt;    }&lt;br /&gt;    return dtoList;&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Repository で Cargo の一覧を取得している。ただし BookingFacadeService はリモートサービスなので、呼び出し元に結果を返却するために DTO を作っている。DTO には Cargo の情報だけでなく、関連する配送ルートの情報まで展開した上で返却している。&lt;br /&gt;&lt;br /&gt;[CargoRoutingDTOAssembler#toDTO]&lt;pre class="prettyprint"&gt;  public CargoRoutingDTO toDTO(final Cargo cargo) {&lt;br /&gt;    final CargoRoutingDTO dto = new CargoRoutingDTO(&lt;br /&gt;      cargo.trackingId().idString(),&lt;br /&gt;      cargo.origin().unLocode().idString(),&lt;br /&gt;      cargo.routeSpecification().destination().unLocode().idString(),&lt;br /&gt;      cargo.routeSpecification().arrivalDeadline(),&lt;br /&gt;      cargo.delivery().routingStatus().sameValueAs(RoutingStatus.MISROUTED));&lt;br /&gt;    for (Leg leg : cargo.itinerary().legs()) {&lt;br /&gt;      dto.addLeg(&lt;br /&gt;        leg.voyage().voyageNumber().idString(),&lt;br /&gt;        leg.loadLocation().unLocode().idString(),&lt;br /&gt;        leg.unloadLocation().unLocode().idString(),&lt;br /&gt;        leg.loadTime(),&lt;br /&gt;        leg.unloadTime());&lt;br /&gt;    }&lt;br /&gt;    return dto;&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;ちなみに、CargoAdminController から BookingServiceFacade へのリモート呼び出しは RmiProxyFactoryBean でうまく隠蔽されている。&lt;br /&gt;&lt;br /&gt;[booking-servlet.xml]&lt;pre class="prettyprint"&gt;  &amp;lt;bean id=&amp;quot;remoteBookingService&amp;quot; class=&amp;quot;org.springframework.remoting.rmi.RmiProxyFactoryBean&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;property name=&amp;quot;serviceUrl&amp;quot; value=&amp;quot;rmi://localhost:1099/BookingService&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;property name=&amp;quot;serviceInterface&amp;quot; value=&amp;quot;se.citerus.dddsample.interfaces.booking.facade.BookingServiceFacade&amp;quot;/&amp;gt;&lt;br /&gt;  &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;bean name=&amp;quot;/*&amp;quot; class=&amp;quot;se.citerus.dddsample.interfaces.booking.web.CargoAdminController&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;property name=&amp;quot;bookingServiceFacade&amp;quot; ref=&amp;quot;remoteBookingService&amp;quot;/&amp;gt;&lt;br /&gt;  &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;ここまでがINTERFACES。というか、ここまででほとんど終わりだ。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;APPLICATION&lt;/span&gt;&lt;br /&gt;今回はアプリケーションサービスとして BookingService が存在するが、このシナリオでは使われていない。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;INFRASTRUCTURE&lt;/span&gt;&lt;br /&gt;Tracking との目立った違いはない。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;積荷の新規登録&lt;/span&gt;&lt;br /&gt;エンティティの新規登録。新規登録画面の初期化・表示と、入力された積荷情報の登録の2ステップにわかれている。&lt;br /&gt;新規登録画面の初期化時は、出発地・到着地を選択するためのドロップダウンメニューに設定する情報を取得しているのみであるため、ここでは積荷情報の登録を見ていく。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;INTERFACES&lt;/span&gt;&lt;br /&gt;エントリポイントは、CargoAdminController の register メソッド。&lt;br /&gt;&lt;br /&gt;[CargoAdminController#register]&lt;pre class="prettyprint"&gt;  public void register(HttpServletRequest request, HttpServletResponse response,&lt;br /&gt;                       RegistrationCommand command) throws Exception {&lt;br /&gt;    Date arrivalDeadline = new SimpleDateFormat("M/dd/yyyy").parse(command.getArrivalDeadline());&lt;br /&gt;    String trackingId = bookingServiceFacade.bookNewCargo(&lt;br /&gt;      command.getOriginUnlocode(), command.getDestinationUnlocode(), arrivalDeadline&lt;br /&gt;    );&lt;br /&gt;    response.sendRedirect("show.html?trackingId=" + trackingId);&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;BookingServiceFacade に丸投げ。&lt;br /&gt;&lt;br /&gt;[BookingServiceFacadeImpl#bookNewCargo]&lt;pre class="prettyprint"&gt;  public String bookNewCargo(String origin, String destination, Date arrivalDeadline) {&lt;br /&gt;    TrackingId trackingId = bookingService.bookNewCargo(&lt;br /&gt;      new UnLocode(origin),&lt;br /&gt;      new UnLocode(destination),&lt;br /&gt;      arrivalDeadline&lt;br /&gt;    );&lt;br /&gt;    return trackingId.idString();&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;さらにアプリケーションレイヤに丸投げ。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;APPLICATION&lt;/span&gt;&lt;br /&gt;ついにアプリケーションサービスが登場。&lt;br /&gt;&lt;br /&gt;[BookingServiceImpl#bookNewCargo]&lt;pre class="prettyprint"&gt;  @Override&lt;br /&gt;  @Transactional&lt;br /&gt;  public TrackingId bookNewCargo(final UnLocode originUnLocode,&lt;br /&gt;                                 final UnLocode destinationUnLocode,&lt;br /&gt;                                 final Date arrivalDeadline) {&lt;br /&gt;    // TODO modeling this as a cargo factory might be suitable&lt;br /&gt;    final TrackingId trackingId = cargoRepository.nextTrackingId();&lt;br /&gt;    final Location origin = locationRepository.find(originUnLocode);&lt;br /&gt;    final Location destination = locationRepository.find(destinationUnLocode);&lt;br /&gt;    final RouteSpecification routeSpecification = new RouteSpecification(origin, destination, arrivalDeadline);&lt;br /&gt;&lt;br /&gt;    final Cargo cargo = new Cargo(trackingId, routeSpecification);&lt;br /&gt;&lt;br /&gt;    cargoRepository.store(cargo);&lt;br /&gt;    logger.info("Booked new cargo with tracking id " + cargo.trackingId().idString());&lt;br /&gt;&lt;br /&gt;    return cargo.trackingId();&lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;処理の流れとしては、Command から取得したコードをもとに ENTITIES や VALUE OBJECTS を復元して新規 Cargo に設定し、最後に Repository で保存している。ごくごく基本的な流れではあるが、設定項目が多すぎて少しぎこちなくなっているため、将来的には CargoFactory を作ってそこに移すのが良いと考えているようだ。&lt;br /&gt;この時点で既にトラッキングIDが発行されていることから、ビジネス的には配送ルートが設定されていなくても、正当な積荷らしい。また、Cargo が状態を持っている様子もない。&lt;br /&gt;@Transaction でこのメソッドをトランザクション境界に設定している点にも注意。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;INFRASTRUCTURE&lt;/span&gt;&lt;br /&gt;一件検索系はもういいので無視して、トラッキングIDの新規発行を担っている CargoRepository#nextTrackingId を確認したい。&lt;br /&gt;&lt;br /&gt;[CargoRepositoryHibernate#nextTrackingId]&lt;pre class="prettyprint"&gt;  public TrackingId nextTrackingId() {&lt;br /&gt;    // TODO use an actual DB sequence here, UUID is for in-mem&lt;br /&gt;    final String random = UUID.randomUUID().toString().toUpperCase();&lt;br /&gt;    return new TrackingId(&lt;br /&gt;      random.substring(0, random.indexOf("-"))&lt;br /&gt;    );&lt;br /&gt;  }&lt;/pre&gt;&lt;br /&gt;あぁ…TODO とかついちゃってるよ…。現段階では UUID が使われているが、本来はDBシーケンスを使う、とのこと。もうバージョン1.1.0なんですけど :-D&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;積荷情報（到着地点）の更新&lt;/span&gt;&lt;br /&gt;基本的な流れは積荷の新規登録と同じなので省略する。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;まとめ&lt;/span&gt;&lt;br /&gt;リモートファサードを使う場合の実装方針がわかった、ってところだろうか。あえてドメインの構造には立ち入っていないが、このユースケースではドメイン層に入る余地もなさそう。おそらく、配送ルートの検索あたりでないとロジックらしいロジックは出てこないだろうな。&lt;br /&gt;&lt;br /&gt;目次：&lt;br /&gt;&lt;a href="http://hibituredure.blogspot.com/2009/05/ddd-sample-application-version110.html"&gt;DDD Sample Application version1.1.0を確認する&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-2808836727077095335?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/2808836727077095335/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=2808836727077095335&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/2808836727077095335'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/2808836727077095335'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2009/05/ddd-sample-application-version110-2.html' title='DDD Sample Application version1.1.0: ユースケーススライスから見たアプリケーション構造の確認（2）'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-118805850223058492</id><published>2009-05-06T12:06:00.010+09:00</published><updated>2009-05-07T08:24:52.973+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='ddd'/><category scheme='http://www.blogger.com/atom/ns#' term='調べてみた'/><title type='text'>DDD Sample Application version1.1.0: ユースケーススライスから見たアプリケーション構造の確認（1）</title><content type='html'>前回まででユースケース、アプリの全体構造までを確認したところで、今回はユースケースごと（ユーザーイベントごと）のアプリケーション構造を追っていく。ユーザーイベントを再掲する。&lt;br /&gt;&lt;ul&gt;&lt;li style="font-weight: bold;"&gt;配送状況の詳細表示&lt;/li&gt;&lt;li&gt;積荷の一覧・詳細表示&lt;br /&gt;&lt;/li&gt;&lt;li&gt;積荷の新規登録&lt;/li&gt;&lt;li&gt;積荷の状態更新&lt;/li&gt;&lt;li&gt;配送ルート候補検索&lt;/li&gt;&lt;li&gt;積荷への配送ルート設定&lt;/li&gt;&lt;li&gt;配送状況の更新&lt;/li&gt;&lt;li&gt;配送状況の更新（バッチ）&lt;/li&gt;&lt;/ul&gt;まとめてやろうかと思っていたが、思った以上に長くなったので1イベント per 1エントリで進めることにした。今回は一番上、配送状況の詳細表示。&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;配送状況詳細表示の概要&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;主に、顧客が発注商品の配送状況を確認するために使う機能。アプリケーション内では、Tracking という言葉で呼ばれている。&lt;br /&gt;Web インタフェースから情報を参照するだけの機能なので、Spring WebMVCのコントローラから Repository 経由でデータを取得して表示するだけのシンプルな作りになっている。アプリケーション層のクラスは存在しない。&lt;br /&gt;&lt;img src="http://yuml.me/diagram/class/%5BCargoTrackingController%5D-%3E%5BCargoRepository%5D,%20%5BCargoTrackingController%5D-%3E%5BHandlingEventRepository%5D" width="100%" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;INTERFACES&lt;/span&gt;&lt;br /&gt;se.citerus.dddsample.interfaces.tracking の CargoTrackingController がエントリポイントになっている。このクラスは、Spring WebMVC のSimpleFormController を拡張している。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;補足：Spring WebMVC の仕組み&lt;/span&gt;&lt;br /&gt;中身に行く前に、これから何度も出てくるであろう Spring WebMVC の仕組みを確認しておく。SimpleFormController は Form のサブミットをハンドリングするために用意されたクラスだ。onSubmit メソッドを決められたメソッドシグネチャで作成しておくと、Form が送信された際に自動的に呼び出される。メソッド引数は、HttpServletRequest, HttpServletResponse[, AnyObject as Command] [, AnyExceptionClass] のようになっているらしい。&lt;br /&gt;リクエストが送信された際には、CommandClass プロパティに設定されたクラスがインスタンス化され、リクエストパラメータが設定されて onSubmit の引数として渡されてくることになる。&lt;br /&gt;&lt;br /&gt;[CargoTrackingController.java]&lt;pre class="prettyprint"&gt;public final class CargoTrackingController extends SimpleFormController {&lt;br /&gt;&lt;br /&gt;  private CargoRepository cargoRepository;&lt;br /&gt;  private HandlingEventRepository handlingEventRepository;&lt;br /&gt;&lt;br /&gt;  public CargoTrackingController() {&lt;br /&gt;    setCommandClass(TrackCommand.class);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  @Override&lt;br /&gt;  protected ModelAndView onSubmit(final HttpServletRequest request, final HttpServletResponse response,&lt;br /&gt;                                  final Object command, final BindException errors) throws Exception {&lt;br /&gt;&lt;br /&gt;    final TrackCommand trackCommand = (TrackCommand) command;&lt;br /&gt;    final String trackingIdString = trackCommand.getTrackingId();&lt;br /&gt;&lt;br /&gt;    final TrackingId trackingId = new TrackingId(trackingIdString);&lt;br /&gt;    final Cargo cargo = cargoRepository.find(trackingId);&lt;br /&gt;&lt;br /&gt;    final Map&lt;string,&gt; model = new HashMap&lt;string,&gt;();&lt;br /&gt;    if (cargo != null) {&lt;br /&gt;      final MessageSource messageSource = getApplicationContext();&lt;br /&gt;      final Locale locale = RequestContextUtils.getLocale(request);&lt;br /&gt;      final List&lt;handlingevent&gt; handlingEvents = handlingEventRepository.lookupHandlingHistoryOfCargo(trackingId).distinctEventsByCompletionTime();&lt;br /&gt;      model.put("cargo", new CargoTrackingViewAdapter(cargo, messageSource, locale, handlingEvents));&lt;br /&gt;    } else {&lt;br /&gt;      errors.rejectValue("trackingId", "cargo.unknown_id", new Object[]{trackCommand.getTrackingId()}, "Unknown tracking id");&lt;br /&gt;    }&lt;br /&gt;    return showForm(request, response, errors, model);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void setCargoRepository(CargoRepository cargoRepository) {&lt;br /&gt;    this.cargoRepository = cargoRepository;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void setHandlingEventRepository(HandlingEventRepository handlingEventRepository) {&lt;br /&gt;    this.handlingEventRepository = handlingEventRepository;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;設定可能なプロパティには以下のようなものがある。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;sessionForm&lt;ul&gt;&lt;li&gt;Commandオブジェクトをセッションに保存するかどうか&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;commandName&lt;ul&gt;&lt;li&gt;CommandオブジェクトをRequest/Sessionにバインドする際の名前&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;formView&lt;ul&gt;&lt;li&gt;初回アクセスまたはバリデーションエラー時に表示するビュー名&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;successView&lt;ul&gt;&lt;li&gt;onSubmitが成功した場合に表示するビュー名&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;validator&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Commandのバリデータ&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;これらは、Bean定義ファイルを用いて以下のように設定されている。&lt;br /&gt;&lt;br /&gt;[tracking-servlet.xml]&lt;pre class="prettyprint"&gt;&amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&lt;br /&gt;       xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;       xsi:schemaLocation=&amp;quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd&amp;quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;bean class=&amp;quot;org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;property name=&amp;quot;interceptors&amp;quot;&amp;gt;&lt;br /&gt;      &amp;lt;list&amp;gt;&lt;br /&gt;        &amp;lt;ref bean=&amp;quot;openSessionInViewInterceptor&amp;quot;/&amp;gt;&lt;br /&gt;      &amp;lt;/list&amp;gt;&lt;br /&gt;    &amp;lt;/property&amp;gt;&lt;br /&gt;  &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;bean name=&amp;quot;/track&amp;quot; class=&amp;quot;se.citerus.dddsample.interfaces.tracking.CargoTrackingController&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;property name=&amp;quot;sessionForm&amp;quot; value=&amp;quot;true&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;property name=&amp;quot;commandName&amp;quot; value=&amp;quot;trackCommand&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;property name=&amp;quot;formView&amp;quot; value=&amp;quot;track&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;property name=&amp;quot;successView&amp;quot; value=&amp;quot;start&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;property name=&amp;quot;validator&amp;quot; ref=&amp;quot;trackCommandValidator&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;property name=&amp;quot;cargoRepository&amp;quot; ref=&amp;quot;cargoRepository&amp;quot;/&amp;gt;&lt;br /&gt;    &amp;lt;property name=&amp;quot;handlingEventRepository&amp;quot; ref=&amp;quot;handlingEventRepository&amp;quot;/&amp;gt;&lt;br /&gt;  &amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;bean id=&amp;quot;trackCommandValidator&amp;quot; class=&amp;quot;se.citerus.dddsample.interfaces.tracking.TrackCommandValidator&amp;quot;/&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/beans&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;onSubmitの処理内容&lt;/span&gt;&lt;br /&gt;onSubmit では、コマンドオブジェクトから取り出したトラッキングID を使って CargoRepository から Cargo オブジェクトを、HandlingEventRepository から HandlingEvent のリストを取得してビューに返しているだけだ。ただし、ビューにはドメインオブジェクトをそのまま返すのではなく、アダプタを作って返している。この点は後述する。&lt;br /&gt;TrackingCommand は trackingId しか持っておらず、TrackingCommand のバリデーターは、trackingId が空でないことを確認しているだけだ。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;プレゼンテーションモデルの選択&lt;/span&gt;&lt;br /&gt;DDD では、プレゼンテーション層のモデルとしてどのようなものを採用するかがよく議論になっている。一般的なものとしては、以下のような候補がある。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;DomainObject をそのまま返す&lt;/li&gt;&lt;li&gt;DomainObject のアダプタを作り、View にはアダプタインタフェースを返す&lt;/li&gt;&lt;li&gt;専用のプレゼンテーションモデルを作り、DomainObject のデータをコピーした上で返す&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;今回は2番目の、アダプタを作ってビューに返す方法を取っている。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;OpenSessionInView の採用&lt;/span&gt;&lt;br /&gt;Hibernate の Lazy 用として、openSessionInViewInterceptor がインターセプタとして設定されているのが面白い。Seasar コミュニティでは Dxo の導入が一般的になっていた気がするけど、こちらは OpenSessionInView パターンを使っているのか。OpenSessionInView は嫌われているようだけど、自分は別に嫌いではない。常に Dxo 層導入するの面倒くさいし。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;APPLICATION&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;存在しない。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;INFRASTRUCTURE&lt;/span&gt;&lt;br /&gt;ここで出てくるのは、（上記で説明したSrpring WebMVCを除けば）Repository のHibernate 実装の部分だ。中を見てみると実際はあまり大したことをしておらず、ほとんどの処理を Hibernate に丸投げしている。ORM 万歳。&lt;br /&gt;&lt;br /&gt;[CargoRepositoryHibernate.java]&lt;pre class="prettyprint"&gt;@Repository&lt;br /&gt;public class CargoRepositoryHibernate extends HibernateRepository implements CargoRepository {&lt;br /&gt;&lt;br /&gt;  public Cargo find(TrackingId tid) {&lt;br /&gt;    return (Cargo) getSession().&lt;br /&gt;      createQuery("from Cargo where trackingId = :tid").&lt;br /&gt;      setParameter("tid", tid).&lt;br /&gt;      uniqueResult();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void store(Cargo cargo) {&lt;br /&gt;    getSession().saveOrUpdate(cargo);&lt;br /&gt;    // Delete-orphan does not seem to work correctly when the parent is a component&lt;br /&gt;    getSession().createSQLQuery("delete from Leg where cargo_id = null").executeUpdate();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public TrackingId nextTrackingId() {&lt;br /&gt;    // TODO use an actual DB sequence here, UUID is for in-mem&lt;br /&gt;    final String random = UUID.randomUUID().toString().toUpperCase();&lt;br /&gt;    return new TrackingId(&lt;br /&gt;      random.substring(0, random.indexOf("-"))&lt;br /&gt;    );&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public List&lt;cargo&gt; findAll() {&lt;br /&gt;    return getSession().createQuery("from Cargo").list();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;今回は、find メソッドしか使っていない。これは、単に JPQL を使って一件検索しているだけだ。すべての XxxxRepositoryHibernate は HibernateRepository を継承しているが、HibernateRepository はサブクラスからの getSession 呼び出しに応じて Session を提供しているだけだ。&lt;br /&gt;&lt;br /&gt;[HibernateRepository.java]&lt;pre class="prettyprint"&gt;public abstract class HibernateRepository {&lt;br /&gt;&lt;br /&gt;  private SessionFactory sessionFactory;&lt;br /&gt;&lt;br /&gt;  @Required&lt;br /&gt;  public void setSessionFactory(final SessionFactory sessionFactory) {&lt;br /&gt;    this.sessionFactory = sessionFactory;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  protected Session getSession() {&lt;br /&gt;    return sessionFactory.getCurrentSession();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;HandlingEventRepository はさらにシンプルで、メソッドは1つしかない。こちらも、JPQL で一覧検索しているだけ。&lt;br /&gt;&lt;br /&gt;[HandlingEventRepository.java]&lt;pre class="prettyprint"&gt;@Repository&lt;br /&gt;public class HandlingEventRepositoryHibernate extends HibernateRepository implements HandlingEventRepository {&lt;br /&gt;&lt;br /&gt;  @Override&lt;br /&gt;  public void store(final HandlingEvent event) {&lt;br /&gt;    getSession().save(event);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  @Override&lt;br /&gt;  public HandlingHistory lookupHandlingHistoryOfCargo(final TrackingId trackingId) {&lt;br /&gt;    return new HandlingHistory(getSession().createQuery(&lt;br /&gt;            "from HandlingEvent where cargo.trackingId = :tid").&lt;br /&gt;            setParameter("tid", trackingId).&lt;br /&gt;            list()&lt;br /&gt;    );&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-size:130%;"&gt;まとめ&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;シンプルな検索は、（アプリケーションレイヤをスキップして）Web-FWから直接 Repository を呼び出すことで実現している。プレゼンテーションモデルとしては、Adapter アプローチを取っている。&lt;br /&gt;&lt;br /&gt;もともとシンプルなユースケースであることも手伝って、なんだか依存テクノロジの説明がほとんどになってしまった。次回からはこういった説明は少なくなるはずなので、もっとさくさく進むはず！&lt;br /&gt;&lt;br /&gt;目次：&lt;br /&gt;&lt;a href="http://hibituredure.blogspot.com/2009/05/ddd-sample-application-version110.html"&gt;DDD Sample Application version1.1.0を確認する&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-118805850223058492?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/118805850223058492/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=118805850223058492&amp;isPopup=true' title='1 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/118805850223058492'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/118805850223058492'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2009/05/ddd-sample-application-version110-1.html' title='DDD Sample Application version1.1.0: ユースケーススライスから見たアプリケーション構造の確認（1）'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-5187383085909488068</id><published>2009-05-06T03:33:00.009+09:00</published><updated>2009-05-07T08:24:52.974+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='ddd'/><category scheme='http://www.blogger.com/atom/ns#' term='調べてみた'/><title type='text'>DDD Sample Application version1.1.0: アプリケーション全体構造の確認</title><content type='html'>続いては、アプリケーション全体構造の確認。ここからようやく、ソースコードレベルでの確認に入っていく。単にソースを見るだけなら&lt;a href="http://dddsample.sourceforge.net/download.html"&gt;ダウンロードページ&lt;/a&gt;からダウンロードすればいいが、効率よく読んでいくためには Eclipse 等 IDE のサポートが必要だろう。Maven を使っているので多少面倒くさいが、&lt;a aiotarget="false" aiotitle="ダウンロードページ" href="http://dddsample.sourceforge.net/download.html"&gt;ダウンロードページ&lt;/a&gt;には IDE で使うための情報も書かれているので、（特に Eclipse ユーザーは）参考にすると良い。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;インフラストラクチャが依存するテクノロジ&lt;/span&gt;&lt;br /&gt;実際のアプリケーションに入る前に、まずはインフラが依存する基本的なテクノロジ（ライブラリやフレームワーク）を確認しておく。採用するテクノロジは列挙にとどめる。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;IoC (DI)コンテナ&lt;ul&gt;&lt;li&gt;Spring 2.5.6&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Webフレームワーク&lt;ul&gt;&lt;li&gt;Spring WebMVC 2.5.6&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;ORM&lt;ul&gt;&lt;li&gt;Hibernate 3.3.1&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;ロギング&lt;ul&gt;&lt;li&gt;log4j 1.2.14&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;パッケージ&lt;/span&gt;の概要&lt;/span&gt;&lt;br /&gt;アプリケーションは、大きく以下の3つのパッケージに分割されている。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;com.pathfinder&lt;/li&gt;&lt;li&gt;com.aggregator&lt;/li&gt;&lt;li&gt;se.citerus.dddsample&lt;/li&gt;&lt;/ul&gt;com.pathfinder は配送ルート候補を計算するために使われているのだが、これは一般的なグラフ構造を扱うパッケージになっており、Distillation の観点から見ると COHESIVE MECHANISMS（一般的な問題を解決するためのメカニズムを表す部分） になっている。もしかすると、GENERIC SUBDOMAINS（ドメインの観点から見て重要性が低い部分）とみなしても良いのかもしれない。&lt;br /&gt;&lt;br /&gt;aggregator は 配送状況を一括更新するための Java-XML マッピングと Webサービスを扱っているパッケージだが、この部分を interfaces に含めず独立したパッケージとして扱っている理由がよくわからない。Webインタフェース用の Servlet や Spring WebMVC の Controller が interfaces パッケージに含まれることを考えると、Webサービス用だけが独立しているのは理解しづらい。&lt;br /&gt;&lt;br /&gt;se.citerus.dddsample は、CORE DOMAIN（ドメインの観点から重要度の最も高い部分）、またはCORE DOMAINを含むパッケージとなっているはずで、主要な機能はすべてここにおさめられている。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;レイヤの確認&lt;/span&gt;&lt;br /&gt;se.citerus.dddsample パッケージはさらに、以下の4つのパッケージで構成されている。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;interfaces&lt;/li&gt;&lt;li&gt;infrastructure&lt;/li&gt;&lt;li&gt;application&lt;/li&gt;&lt;li&gt;domain&lt;/li&gt;&lt;/ul&gt;このうち、interfaces を除く3つは、the book で基本的なレイヤとして紹介されているもので、それがそのままパッケージ構造に反映されている。これらレイヤの概要は、&lt;a href="http://dddsample.sourceforge.net/architecture.html"&gt;Architectureと題されたページ&lt;/a&gt;に書かれている。&lt;br /&gt;# なお、テストパッケージにはこれらに加えて「scenario」が存在し、シナリオテストが収められている。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;INTERFACES&lt;/span&gt;&lt;br /&gt;今回から新たに導入されたレイヤ。Webブラウザ等のヒューマンインタフェースを含む、外部システムとのインタフェースすべてが配置される。入力データの解釈、検証、変換や、出力データのシリアライズはこのレイヤが担う。DTO も含まれる。&lt;br /&gt;# だったらなおさら、なんで aggregator が独立パッケージなのかわからないが&lt;br /&gt;&lt;br /&gt;このパッケージは、さらに以下の3つのパッケージで構成されている。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;tracking&lt;/li&gt;&lt;li&gt;booking&lt;/li&gt;&lt;li&gt;handling&lt;/li&gt;&lt;/ul&gt;これは、ビデオで紹介されている主要なインタフェースに対応…つまり、 tracking が Customer による配送状況の確認に、booking が配送手配者による積荷の管理に、handling が配送業者による配送状況の更新に対応している。&lt;br /&gt;&lt;br /&gt;これらのパッケージは、それぞれがさらにテクノロジ依存のサブパッケージ（web, file, wsなど）を持っているが、この部分の詳細は次回以降で確認する。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;APPLICATION&lt;/span&gt;&lt;br /&gt;積荷の新規登録（Booking）と配送状況更新（Handling）に関するアプリケーションサービスとその実装、それに ApplicationEvent というイベント通知用のインタフェースから構成されている。アプリケーションサービスに配送状況確認（Tracking）がないのは、おそらくシンプルすぎてサービスが必要ないからだと思われる。Tracking は参照のみなので、Repository のメソッドを呼ぶだけですんでしまう。次回参照するが、この処理は interfaces パッケージ内の Controller に直接記述されている。&lt;br /&gt;ApplicationEvent はいわゆるイベントオブジェクトではなく、ステートレスなイベント通知インタフェースで、ほぼサービスと考えても良いくらいのものだ。ApplicationEvent の実装はメッセージングを使うようになっており、そのインフラ色の強さからか infrastructure パッケージに配置されている。&lt;br /&gt;&lt;br /&gt;テストやサンプルデータ生成用のユーティリティも配置されているが、これらは本来ならテストソースフォルダなりリソースフォルダなりに移すべきものだろう。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;INFRASTRUCTURE&lt;/span&gt;&lt;br /&gt;infrastructure パッケージは、以下の3つのパッケージで構成されている。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;persistence.hibernate&lt;/li&gt;&lt;li&gt;messaging.jms&lt;/li&gt;&lt;li&gt;routing&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt; persistence.hibernate パッケージには、何度も the book で述べられているとおり（ドメイン層にインタフェースだけ存在する） Repository の Hibernate 実装が配置されている。&lt;br /&gt;&lt;br /&gt;messaging.jms にはその名のとおり JMS 関連のコードが配置されており、infrastructure の観点では特に興味深い点はないが、ApplicationEvent のような application レイヤの実装も含まれている点は面白い。Sample Application 1.0 にはinfrastructure パッケージが存在せず、すべて application につっこまれていたことから、application は infrastructure-aware で良いのかと思っていたが、application もきちんとインフラから分離するようだ。&lt;br /&gt;&lt;br /&gt;routing パッケージに唯一存在する ExternalRoutingSerivice は、なんとドメインサービスの実装だ。ドメインサービスの実装が infrastructure に配置されるなんて構成は考えたこともなかった。このサービスは、COHESIVE MECHANISMS として紹介した pathfinder へのリモート接続を含むため、infrastructure に配置されているようだ。接続先の pathfinder サービスは javax.rmi.Remote を実装しているため、RemoteException をスローする。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;DOMAIN&lt;/span&gt;&lt;br /&gt;すべての中心となる部分。パッケージは以下のように分割されている。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;model&lt;/li&gt;&lt;li&gt;service&lt;/li&gt;&lt;li&gt;shared&lt;/li&gt;&lt;/ul&gt;model には、ENTITIES, VALUE OBJECTS, DOMAIN EVENTS, REPOSITORIES, FACTORIES といったDDDのビルディングブロックが含まれている。また、各種 Exception も含まれている。あまり説明はいらないだろう。&lt;br /&gt;&lt;br /&gt;service には、ドメインサービスが含まれている。今回は、先ほど infrastructure で説明した RoutingService しか配置されていない。&lt;br /&gt;&lt;br /&gt;shared には、DDDビルディングブロックを表す各種インタフェースや、Specification 関連の基本クラスなど、まさにドメインレイヤの基盤になるクラスたちが配置されている。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;まとめ&lt;/span&gt;&lt;br /&gt;まずは主要な部分である se.citerus.dddsample と補助的な部分である com.aggregator/com.pathfinder とは明確に分離できる。主要なドメインである dddsample は、（interfacesが追加されているものの）基本的には the book に忠実に分割されていることがわかる。&lt;br /&gt;&lt;br /&gt;目次：&lt;br /&gt;&lt;a href="http://hibituredure.blogspot.com/2009/05/ddd-sample-application-version110.html"&gt;DDD Sample Application version1.1.0を確認する&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-5187383085909488068?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/5187383085909488068/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=5187383085909488068&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/5187383085909488068'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/5187383085909488068'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2009/05/ddd-sample-application-version110_9820.html' title='DDD Sample Application version1.1.0: アプリケーション全体構造の確認'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-3468317099841218909</id><published>2009-05-06T02:15:00.017+09:00</published><updated>2009-05-07T08:24:52.974+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='ddd'/><category scheme='http://www.blogger.com/atom/ns#' term='調べてみた'/><title type='text'>DDD Sample Application version1.1.0: ユースケースの確認</title><content type='html'>さて、まずは Sample Applicatin のユースケースを確認する。これには、実際に動かしてみるのが一番だが、そこまでするのが面倒な人のために、丁寧にもビデオが用意されている。なので、確認はこのビデオに沿って進めていきたい。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;概要&lt;/span&gt;&lt;br /&gt;細かい説明に入る前に断っておきたいのだが、このアプリケーションは the book（Evans の DDD本）で何度も例としてあげられている、積荷の出荷とトラッキングを扱ったアプリケーションがもとになっている。イメージとしては、DELL やら Amazon やらで商品を買った際に通知されてくる、配送状況確認ページを思い浮かべてもらうとわかりやすいと思う。&lt;br /&gt;このアプリケーションではさらに、上記のような商品を買った側（Customer）からの配達状況の確認だけでなく、商品提供側（DELL や Amazon）による配送の手配や、配送業者による配達状況の更新までできるようになっている。最初にこれくらいのイメージを持っているとわかりやすい。&lt;br /&gt;というわけで、ビデオはこれ。とりあえずは、ざっと画面のイメージだけ確認できればOK。細かい内容はこの後にも書いてます。逆に、ビデオの内容が完璧にわかれば、この後はほとんど読む必要ないです ^^;&lt;br /&gt;&lt;br /&gt;&lt;object height="340" width="560"&gt;&lt;param name="movie" value="http://www.youtube.com/v/eA8xgdtqqs8&amp;amp;hl=ja&amp;amp;fs=1"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/eA8xgdtqqs8&amp;amp;hl=ja&amp;amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="340" width="560"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;このアプリケーションには、以下のような3つのインタフェースがある。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;積荷（Cargo）のトラッキングインタフェース&lt;/li&gt;&lt;li&gt;配送予約とルートの管理用インタフェース&lt;/li&gt;&lt;li&gt;配送状況の更新インタフェース&lt;/li&gt;&lt;/ul&gt;最初の2つは Web、3つ目には Swing によるリッチクライアントアプリケーションと、ファイルトリガのバッチアプリケーションの2種類が用意されている。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;積荷のトラッキング&lt;/span&gt;&lt;br /&gt;これは、顧客（Customer）が注文した積荷の配送状況を確認するためのもので、トラッキングIDを入力できるだけのシンプルなインタフェースになっている。ここにトラッキングIDを入力して送信すると、以下の情報が表示される。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;積荷の到着予定時刻&lt;br /&gt;&lt;/li&gt;&lt;li&gt;現在の積荷の場所&lt;/li&gt;&lt;li&gt;次に積荷が向かう場所&lt;/li&gt;&lt;li&gt;積荷の配送履歴&lt;/li&gt;&lt;/ul&gt;積荷が間違って（予定とは異なるルートで）配送されてしまった場合には、画面上に「Cargo is misdirected」とエラーメッセージが表示され、次に積荷が向かう場所は表示されず、積荷の到着予定時刻は不明と表示される。また、配送履歴のうちミスがあった部分に「×」がつく。&lt;br /&gt;# 実際、顧客に直接こんな情報表示するんかいなという感じがするが…。&lt;br /&gt;後で出てくるのだが「配送状況の更新インタフェース」にて誤った情報を送信した場合にこのように表示されることになる。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;配送予約とルートの管理&lt;/span&gt;&lt;br /&gt;商品の配送者（DELLとかAmazonとか）が、積荷の新規登録や配送ルートの選択を行うインタフェース。以下のようなことが可能。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;積荷の状況確認&lt;/li&gt;&lt;li&gt;積荷情報の更新&lt;br /&gt;&lt;/li&gt;&lt;li&gt;積荷の新規登録（配送予約）&lt;/li&gt;&lt;li&gt;積荷の配送ルート候補の検索および確定&lt;/li&gt;&lt;/ul&gt;積荷の状況確認機能では、積荷情報の一覧表示、詳細表示ができる。詳細画面では積荷情報の更新に進むことができ、配送先のみが変更できる。「モノ」を管理するための典型的なインタフェース構成で、業務システムを作ったことがある人なら見飽きているだろう。&lt;br /&gt;積荷の新規登録では、一度にすべての情報を入力しきるのではなく、まずは出発地点と到着地点、そして到着デッドラインのみを登録する。この時点でトラッキングIDが払い出されるが、配送ルートはまだ決まっていない。配送ルートは、配送ルート候補の検索および確定機能で別途確定させる。&lt;br /&gt;&lt;br /&gt;配送ルートの検索と確定は、このシステムで一番面白いところだろう。入力された情報をもとに、配送ルートの候補がいくつか表示される。管理者はこの候補を確認し、好ましいルートを選択して配送ルートを確定させる。&lt;br /&gt;&lt;br /&gt;なお、ビデオでは到着地点の更新は実行されていないが、既に配送ルートが選択された状態で到着地点を変更しても、エラーになることもなく警告メッセージのようなものも表示されない。かなり寛容な作りなようだ。&lt;br /&gt;&lt;br /&gt;個人的には、こんなことに興味がある。後で確認してみたい。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Cargoに別々の状態を持たせているのかどうか&lt;/li&gt;&lt;li&gt;トラッキングIDをどのように払い出しているのか&lt;/li&gt;&lt;li&gt;配送ルート候補の検索で使われる、ルート選択ポリシーの種類とその扱い&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;配送状況の更新&lt;/span&gt;&lt;br /&gt;配送業者（クロネコとか佐川とか）が、配送状況を随時更新するためのインタフェース。このアプリケーションはシンプルで、1画面しかない。ここに、以下のような情報を入力する。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;更新時刻&lt;/li&gt;&lt;li&gt;トラッキングID&lt;/li&gt;&lt;li&gt;便（Voyage）&lt;/li&gt;&lt;li&gt;イベント発生場所のコード&lt;/li&gt;&lt;li&gt;イベントタイプ&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;便は必須項目ではないらしく、イベントタイプによっては必要ないようだ。例えば、工場から積荷を受け取るイベントが発生した場合、この時点では便は関係ないので入力は不要だ。&lt;br /&gt;&lt;br /&gt;項目名に「イベント」とあるように、これは DDDのビルディングブロックの1つである「DomainEvent」を発生させるためのインタフェースであるらしい。これだけがリッチクライアントとして作られているのは、配送の現地（倉庫や船）から更新することを考えるとバーコードなどの専用端末からの更新が現実的なためで、Swingは端末を簡易にエミュレートしているのだろう。&lt;br /&gt;&lt;br /&gt;個人的には、このあたりに興味がある。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;バリデーションが存在しないのは、DomainEventパターンの適用によるものなのか、端末エミュレートによるものなのか&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;配送状況の更新（バッチ）&lt;/span&gt;&lt;br /&gt;Swingアプリケーションとは別に、配送状況を一括更新するインタフェースも存在する。これは、タブ区切りのテキストデータが指定のフォルダに置かれると、そのデータをもとに自動的に配送状況が一括更新されるというものだ。一括更新であること以外の機能は Swingアプリケーションと同じで、テキストデータの1行として記述する項目も、Swing アプリケーションと同じ。ビデオでは、配送状況の更新インタフェースの一部として扱われている。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;まとめ&lt;/span&gt;&lt;br /&gt;というわけで、ビデオを見るとだいたい何をやっているかはつかめると思う。一応、次回以降で確認するイベントをあげておく。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;配送状況の詳細表示&lt;/li&gt;&lt;li&gt;積荷の一覧・詳細表示&lt;br /&gt;&lt;/li&gt;&lt;li&gt;積荷の新規登録&lt;/li&gt;&lt;li&gt;積荷の状態更新&lt;/li&gt;&lt;li&gt;配送ルート候補検索&lt;/li&gt;&lt;li&gt;積荷への配送ルート設定&lt;/li&gt;&lt;li&gt;配送状況の更新&lt;/li&gt;&lt;li&gt;配送状況の更新（バッチ）&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;次回は、これらイベントの個別のハンドリング方法を確認する前段階として、アプリケーションの全体構造を確認する。&lt;br /&gt;&lt;br /&gt;目次：&lt;br /&gt;&lt;a href="http://hibituredure.blogspot.com/2009/05/ddd-sample-application-version110.html"&gt;DDD Sample Application version1.1.0を確認する&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-3468317099841218909?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/3468317099841218909/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=3468317099841218909&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/3468317099841218909'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/3468317099841218909'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2009/05/ddd-sample-application-version110_06.html' title='DDD Sample Application version1.1.0: ユースケースの確認'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-567424916173237587</id><published>2009-05-06T01:04:00.008+09:00</published><updated>2009-05-07T08:24:52.975+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='ddd'/><category scheme='http://www.blogger.com/atom/ns#' term='調べてみた'/><title type='text'>DDD Sample Application version1.1.0 を確認する</title><content type='html'>ようやく Evans の DDD本（the book）をすべて読み終わった（長かった！）ので、オフィシャルに提供されているサンプルアプリケーションである &lt;a href="http://dddsample.sourceforge.net/"&gt;DDD Sample Application&lt;/a&gt; を確認し、具体的な実装方法やビルディングブロックの実例を見つつ理解を深めておきたい。昨年リリースされたバージョン1.0は軽く確認したのだが、3月25日にリリースされたバージョン1.1.0はまた結構変わっているようなので、あらためて最新のDDDアプリケーション構造を確認していく。&lt;br /&gt;とりあえずは、こんな感じで進めていく予定。&lt;br /&gt;&lt;ol&gt;&lt;li&gt;ユースケースの確認&lt;/li&gt;&lt;li&gt;アプリケーション全体構造の確認&lt;br /&gt;&lt;/li&gt;&lt;li&gt;ユースケーススライスから見たアプリケーション構造の確認&lt;br /&gt;&lt;/li&gt;&lt;li&gt;ドメイン構造の確認&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;ユースケースの確認&lt;/span&gt;&lt;br /&gt;このアプリケーションが何を目的として作られ、どんな機能を提供するのかをユーザー視点で確認する。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;アプリケーション全体構造の確認&lt;/span&gt;&lt;br /&gt;細かいコードの確認に入る前に、アプリケーション全体の構造がどのようになっているのかを確認する。主に、Distillation や Large-Scale Structure の観点からアプリケーション全体構造の特徴を把握する。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;ユースケーススライスから見たアプリケーション構造の確認&lt;/span&gt;&lt;br /&gt;機能的な観点から見たアプリケーションの構造を確認する。各ユーザーイベントに対してどのようなソフトウェア要素が対応し、どのようにドメインレイヤにつなげていくのかを把握する。主にプレゼンテーション層（interfacesパッケージ）、サービス・アプリケーション層（applicationパッケージ）、インフラ層（infrastructureパッケージ）を確認する。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;ドメイン構造の確認&lt;/span&gt;&lt;br /&gt;ドメイン層がどのように構成されているのかを確認する。メインの部分。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;最後までできるかな…てか予定どおりいくかな…。&lt;br /&gt;&lt;br /&gt;コンテンツ一覧：&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="http://hibituredure.blogspot.com/2009/05/ddd-sample-application-version110_06.html"&gt;DDD Sample Application version1.1.0: ユースケースの確認&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://hibituredure.blogspot.com/2009/05/ddd-sample-application-version110_9820.html"&gt;DDD Sample Application version1.1.0: アプリケーション全体構造の確認&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-567424916173237587?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/567424916173237587/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=567424916173237587&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/567424916173237587'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/567424916173237587'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2009/05/ddd-sample-application-version110.html' title='DDD Sample Application version1.1.0 を確認する'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-7476156009273741827</id><published>2009-05-02T01:14:00.011+09:00</published><updated>2009-05-05T17:58:24.001+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='ddd'/><category scheme='http://www.blogger.com/atom/ns#' term='report'/><title type='text'>DSM(DomainSpecificModeling) + DDD</title><content type='html'>DDDオフィシャルサイトに掲載されている、DSM(Domain Specific Modeling)に関するインタビューを起こしてみた。オリジナルのビデオは&lt;a href="http://www.domaindrivendesign.org/library/bell_gitlevich_2009"&gt;ここ&lt;/a&gt;。どうでもいいと思ったところや一部よくわからなかったところは飛ばしてるし、間違っているところもあると思います ^^;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;はじめに&lt;br /&gt;&lt;/span&gt;Interviewer(以下"I"):&lt;br /&gt;Peter Bellが来てくれた。自己紹介してくれる？&lt;br /&gt;&lt;br /&gt;Peter Bell(以下"P"):&lt;br /&gt;カンファレンスなど、色んな場面でこのトピックについて話している。DSMやコードジェネレーションについて話すのにベストな人間だと思う。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;DSMとは&lt;/span&gt;&lt;br /&gt;I: 今日はDSMについて話したいが、まずはDSMが何か教えてもらえるだろうか？&lt;br /&gt;&lt;br /&gt;P:  役に立つ良い定義としては「開発プロセスのスピードアップ、アプリケーションの一部または全体の生成、コードベースのメンテナンスなどのためにDSLを使うこと」のように言えると思う。&lt;br /&gt;&lt;br /&gt;I: じゃあ、DSLって何？&lt;br /&gt;&lt;br /&gt;P: 3つのコンポーネントがあると思っている。&lt;br /&gt;まず1つは、Javaなどの汎用言語とは異なり、特定の問題を解決するためのものであるということ。&lt;br /&gt;2つ目は、コンストラクションのレベルをひきあげるものであること。JavaやC#とおなじようにかかなくても良い。&lt;br /&gt;3つ目は、実行可能であるということ。ユビキタス言語は必ずしも実行可能でなくてもいいが、DSLはジェネレーションやインタープリタを通して実行できる。&lt;br /&gt;&lt;br /&gt;I: それがユビキタス言語とDSLの違いなんだね？&lt;br /&gt;&lt;br /&gt;P: その通り。DSMはアプリケーションを生成したり実行したりするのに十分なユースケースのセットにフォーカスしていて、ユビキタス言語から直接アプリケーションを生成する。こうすることで色々メリットがある。&lt;br /&gt;&lt;br /&gt;I: プロジェクトでは、会話で使われるようなユビキタス言語もあればコードにあらわれるユビキタス言語もある。後者は実行可能なユビキタス言語、つまりDSLなのか？&lt;br /&gt;&lt;br /&gt;P: そう言える。えーとここで、DSMの世界で重要なDSLの興味深い区別について話しておきたい。内部DSLと外部DSLだ。内部DSLはAPIとかRuby Groovyのような言語を使って、人間が読めるようなDSLをコード内に作るアプローチだ。このアプローチではDSLの利点をフルに受けることはできない。なぜなら、ホスト言語の構文上の問題を気にしなければならないからだ。&lt;br /&gt;外部DSLはよりパワフルで、DSLをコードの外部に持ち出し、DSLのステートメントを書くためのツールを別途用意できる。これは、箱と線で書けるようにもできるし、テキストで書くようにもできるし、スプレッドシートで書くようにもできる。&lt;br /&gt;外部DSLの利点はジェネレートされた個々のステートメントをテストしなくていいので開発やメンテナンスのスピードをあげることができること。&lt;br /&gt;&lt;br /&gt;I: 利点についての話があったが、他に利点はある？&lt;br /&gt;P: 最も大きなものとしては、テスティングコストの低下があげられる。よくできたユビキタス言語は確かに、ステークホルダーとプログラマの間のコミュニケーションの問題を改善できる。しかし、コードへの変換時にはインピーダンスミスマッチがあるため、ここで理解の齟齬が発生し、バグの発生につながってしまう。DSMではこのような事態を完全に避けられる。ステークホルダーとコミュニケートし、彼らが話すことをそのまま書き、コードをジェネレートできる。&lt;br /&gt;&lt;br /&gt;I: 言語が正しければ、テストの必要はない？&lt;br /&gt;P: セマンティクスはもちろんテストする。DSLのステートメントが正しくその意図を表しているか、つまり与えられたステートメントが正しくジェネレートされるか、もしくは正しくインタープリタで実行されるかどうかはテストするということだ。しかし、すべての個々のステートメントをテストする必要はない。&lt;br /&gt;&lt;br /&gt;I: 開発のスピードがあがるとのことだが、アップグレードも頻繁になるのでは？&lt;br /&gt;P: その通り。頻繁にビルドするようにもなる。だが、メンテナンスの際に細かなコードブロックを見るのではなく、意図が明示されたDSL（ユビキタス言語）を見ればいいからメンテナンスも楽になる。&lt;br /&gt;&lt;br /&gt;I: 利点にはすべてトレードオフがある。モデルが変更された場合、言語も変更することになると思うが、既存のツールでこの変更に対応するのはどれくらい難しい？&lt;br /&gt;P: シンプルなリファクタリングサポートは既に存在しており、軽微な変更には問題なく対応できるが、根本的な変更に対しては無力。ただし、これはJavaやらC#を使っていても同じ。&lt;br /&gt;ドメイン（に関する理解）が安定するまで、ジェネレータやインタープリタの作成を先延ばしにするのも良いかもしれない。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;DSMにまつわる誤解&lt;/span&gt;&lt;br /&gt;I: 誤解について話したい。DSMについては色んな話（誤解？）を聞いたが、そのうちのいくつかはUMLについてだった。&lt;br /&gt;P: そりゃDSMではもっとも有害な誤解だと思う。仮に私がDSMをMDAやUMLからはじめていたとしても、UMLは使い続けなかったと思う。UMLは世界中で多くの人が使っていて、標準化もされており、多くの利点がある。しかしUMLの問題は、記述のレベルは抽象的すぎるということ。ステレオタイプでドメインのコンセプトを表せるようになってはいるが、クラスやメソッドが何をすべきかは何も決められていない。クラスごとに箱が1つ用意されるだけだ。なので、モデルからモデルへの変換やモデルからのテキストへの変換は簡単ではない。XMIみたいに。MDAがDSMの小さなサブセットにすぎないことを理解しておくことは非常に重要だと思う。&lt;br /&gt;MetaCaseとかOpenArchitectureWareはEclipseプラグインも提供していて、開発者はテキスト指向のDSLを書く事ができる。これは、MDAに比べるとだいぶ使いやすいと思う。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;DSLとドメインエキスパート&lt;/span&gt;&lt;br /&gt;I: DSLはドメインエキスパートが書けるようにするべき？&lt;br /&gt;P: ここはDSMに関してさまざまな関心がある部分だ。秘書が会計システムを書けるようにしようとしている、とかね。DSMアプローチでドメインエキスパートがDSLを書けるようにすることはできる。が、より利点があるのはドメインエキスパートが読めるようなDSLを作る事。ドメインエキスパートとプログラマの間のミスコミュニケーションを防ぐ事ができる。ユビキタス言語が引き起こしがちな、実装時の齟齬を防ぐ事ができる。&lt;br /&gt;&lt;br /&gt;I: 少し自分の経験について話させてもらうと、ユニットテストやシナリオテストを書いてドメインエキスパートと共有した時、ドメインエキスパートはJavaなどのシンタックスノイズに悩まされていた。ユビキタス言語を使っていたとしても、ドメインエキスパートには（コードが何を意味しているのか）説明しなくてはならない。DSLを使えばわかりやすくできるように思うが、どうか？&lt;br /&gt;&lt;br /&gt;P: BDDのようなアプローチが既に存在しているよね。統合テストではあまりできていないが、DSLが貢献できるいい例だと思う。統合テストにDSLのアプローチを持ち込むことで、ドメインエキスパートにとってとても読みやすくなる。将来はもっとよくなって欲しい。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Big Design Upfront or Agile&lt;/span&gt;&lt;br /&gt;I: ドメインを前もって知っていれば、急激な変更が少なくなり、DSLにとって利点が大きいとするなら、前もってヘビーな分析作業をしなくてはならないのでは？&lt;br /&gt;P: Big Design Upfrontをやりたがる人は最近ではほとんどいないと思う。コミュニティは、よりアジャイルなアプローチを取ろうとしている。&lt;a href="http://www.metacase.com/ja/mep/"&gt;MetaEdit + MetaCase&lt;/a&gt;などが良い例だ。これは、頻繁なモデルの変更を助けるような機能が豊富に用意されている。DSMは決してBDUではないことを強調しておきたい。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;どの程度コード生成すべきか&lt;/span&gt;&lt;br /&gt;I: アプリケーション全体を生成すべきか？&lt;br /&gt;P: コード生成については色んな考えがある。アプリケーション全体を生成しなければならない、というものもあれば、アプリケーション全体を生成なんてできっこない、というものもある。これは、どちらも間違っていると思う。&lt;br /&gt;100%の自動生成は可能ではある。変数のないテンプレートのようなものを使えば、既存のコードに1対1対応するようなコード生成はできる。だが現実には、（このようなアプローチで）すべてのコードを生成するのは意味がない。&lt;br /&gt;DSMの世界では、色んなコードジェネレーションのツールがあり、コードを書くのが非常につらい、クラスやAOP、イベントドリブンプログラミングなどを書かなくてすむようにしている。これらのツールではジェネレートされたコードとカスタムコードは分離して扱うことができ、これら両方でアプリケーション全体を構成することができる。100%のコードを自動生成する必要はない。ドメインモデルが比較的リッチな場所を探し、ドメインエキスパートとコミュニケートして、DSLを作る、といった作業にスタッフをあてるといいだろう。そういうエリアにDSMを適用するのは労力に見合った利点があるからだ。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;DSMに適したプロジェクト&lt;/span&gt;&lt;br /&gt;I: DSMはどんなプロジェクトに向いている？&lt;br /&gt;P: 良い質問だ。プロジェクトをよりDSMに適したものにしてくれるいくつかの要素があると思う。&lt;br /&gt;1つ目、これはあまり言ってないことだが、DSMの熟達度だ。SpringやAOPを導入する時と同じで、最初に技術を導入するときには色んな面倒なことがある。また、動的言語、パーシャルクラス、クロージャなどを使う事でエレガントなアプリケーションをすばやく作り上げる事ができるが、開発者がそれをメンテナンスできるとは限らない。&lt;br /&gt;なので、DSMの経験がある人をプロジェクトにいれて、経験をプロジェクトに持ち込むことが重要だ。これは非常に助けになる。&lt;br /&gt;&lt;br /&gt;他の話としては、能力が許す範囲でいくつものプロジェクトを並行にすすめられるしても、投資を回収するには、ドメインの特定のエリアにとどまり、DSMがより長い時間使われるようにしなければならないということだ。DSMにはかなりのオーバーヘッドがあるので、6回以上やりたいかもしれないが…外部DSL用のツールがこの種の問題を解決しようとしてはいる。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;水平的ドメインと垂直的ドメイン&lt;/span&gt;&lt;br /&gt;ドメインは水平的にも垂直的にもなり得ることを理解するのも重要だ。&lt;br /&gt;垂直的なドメインでは、成果は（例えば）1つの保険会社のためだけに使われる。&lt;br /&gt;&lt;br /&gt;だが一方で、Webの部分は何度も同じようなものを生成することになる。例えば、ドレスショップ向けのeコマースと法律事務所向けの文書リポジトリなど。これが水平的で技術的なドメイン。水平的な技術ドメインはどこでも変わらないので、我々はモデル、コントローラー、バリデーション、リレーションシップなどWebアプリケーションを迅速に構築するための一連のDSLを既にもっている。&lt;br /&gt;1つの企業で働いている人…つまり垂直的ドメインを対象にしている人たちは、領域を限定することで、DSMの能力を最大限に生かし、素早くアプリケーションを作ったりメンテナンスしたりしている。多量のJavaのコードに戻ることなく、少ない文で正確に意図が表現されているからだ。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;現実のDSL/DSLの構築方法&lt;/span&gt;&lt;br /&gt;I: HibernateはDSL？&lt;br /&gt;P: HibernateはORMに関するDSLをいくつか示している。&lt;br /&gt;こういう言語を作る場合、どのように始めればいいか聞かれることがあるのだが、盗めばいい。&lt;br /&gt;ORM, DI, AOPのような水平的ドメインを扱うなら、既に多数のDSLが存在するので、この上にかぶせる形でシンプルな、カスタマイズされた自分のユースケース向けの小さなサブセットを作れば良い。&lt;br /&gt;水平的ドメイン（たぶん垂直的の間違い）では、XMLスキーマも良い出発点になるだろう。銀行や保険の業界では、標準がすでに存在している。それらのサブセットを作る形で、必要に応じて自分の状況に応じてカスタマイズすればいい。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;ドメインのコアコンセプトを理解する方法&lt;/span&gt;&lt;br /&gt;I: ある特定のドメインを扱うような場合、ドメインに関する市販本などもあるが、読んでる？ドメインのコアコンセプトをどうやって知っている？&lt;br /&gt;P: DDDと連携していくのがいいと思っている。&lt;br /&gt;DDDは（DSLにつながる）ユビキタス言語を作るためのアプローチをあげており、DSMはジェネレートやインタープリタを使って効率的に実行する方法を持っている。これら2つのコミュニティは、お互いにディスカッションするといいと思う。既に2つのコミュニティでは活発なコミュニケーションがあると思っているが、より強くしていきたい。DSMコミュニティはDDDコミュニティからよりよく言語を設計する方法を学べるし、DDDは言語を実行可能にする方法を学べる。&lt;br /&gt;&lt;br /&gt;I: 今日はどうもありがとう。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;雑感&lt;/span&gt;&lt;br /&gt;一部マーケ的においはするものの、全体としてはまっとうなことを話している印象。コード生成に関するスタンスも現実的だとは思う。しかし、DSMという新たな用語は必要なんだろうか？世の中を混乱させたり、コミュニティの評判を下げかねないので"DSL"を使い続けた方が良いのではないかと感じた。&lt;br /&gt;また、DDDが向かうべき方向として良いのかどうか、今ひとつ確信が持てない。実行可能なユビキタス言語を作ることで、色んなロスがなくなるというが、それが本当かどうかは具体例を見てみないとなんとも言えないな。ドメインエキスパートの可読性を保ったままDSLを構築できるのだろうか？ユビキタス言語全体がDSLとして構築されるとは思えないのでサブセットになるのだろうが、一部だけ妙に形式的になるのだろうか？モノが見てみたい。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-7476156009273741827?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/7476156009273741827/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=7476156009273741827&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/7476156009273741827'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/7476156009273741827'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2009/05/dsmdomainspecificmodeling-ddd.html' title='DSM(DomainSpecificModeling) + DDD'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-708097122844777720</id><published>2009-04-24T10:20:00.028+09:00</published><updated>2009-05-07T08:26:07.602+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='セミナー/勉強会'/><category scheme='http://www.blogger.com/atom/ns#' term='数学'/><category scheme='http://www.blogger.com/atom/ns#' term='コンピュータ科学'/><category scheme='http://www.blogger.com/atom/ns#' term='report'/><title type='text'>技術者／プログラマのためのモナドと圏論 第1回 行ってきた</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Sde1cTDCAXc/SfFTDVfzXmI/AAAAAAAAA_c/MOFUgFgv5qw/s1600-h/mapfo-1.png"&gt;&lt;/a&gt;&lt;div&gt;またまた行ってきた。前回（論理・ラムダ・圏）、タイトルに「圏」とありながら、実際は圏の話がほとんどできなかったことを受けてはじまった、新シリーズ。細かいところや背景知識なんてわかるわけがない（数学ほとんどやってないし）ので、わかった範囲で書きとめておく。間違いまくってる可能性大。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;全体的に&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;教科書的に進めようかと思っていたそうだが、檜山さんが体調不良で方針転換。形式的なものより、お絵かきメインで進めることになった。&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;というわけで、第1回の予定はこうでした。&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;まえおき／まえせつ&lt;/li&gt;&lt;li&gt;いろいろな図の描き方&lt;/li&gt;&lt;li&gt;圏の定義と実例&lt;/li&gt;&lt;li&gt;休憩&lt;/li&gt;&lt;li&gt;行列の圏で遊ぶ&lt;/li&gt;&lt;li&gt;コレクション・データ&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;実際は、3の途中まで（休憩はやったよ！）で終了しました:-D&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;まえおき／まえせつ&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;シリーズ全体の目標としては…&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;圏の基本概念を学ぶ&lt;br /&gt;&lt;/li&gt;&lt;li&gt;モナドの実例をたくさん知る&lt;/li&gt;&lt;li&gt;モナド法則に慣れる&lt;/li&gt;&lt;li&gt;モナドのクライスリ圏の作り方を知る&lt;/li&gt;&lt;li&gt;モナドがモノイドであることを理解する&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;こんなとこで、4くらいまではいきたいそうだ。自分としては、ここまでいければ当面満足なので、しばらくは独学であがかなくてもよさそうなのが非常に嬉しい。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;今日の目標は…&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;圏の定義と直感的なイメージの両方を知る&lt;br /&gt;&lt;/li&gt;&lt;li&gt;お絵かき実習する&lt;br /&gt;&lt;/li&gt;&lt;li&gt;圏の実例をいじって体になじませる&lt;br /&gt;&lt;/li&gt;&lt;li&gt;横道にそれて面白そうな話題を紹介する&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;モナドの意義&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;今のところさっぱりわかっていないモナドの意義。計算の観点からは、&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;コレクション・データ構造に統一的見方を与える、らしい&lt;/li&gt;&lt;li&gt;関数計算を拡張・一般化できる、らしい&lt;/li&gt;&lt;li&gt;文や式の構文論を整理できる&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;どれもこれも現段階では具体例がわからないのでいまいちピンと来ないんだけど、1番目と2番目はHaskellやらの関数型言語をさわる際に、（気持ち・理解的な）役に立ちそう。特に、関数計算に部分関数、エラー・例外、状態・副作用などを導入する形で拡張するのに出てくる、というあたりはとても興味深い。楽しみだ。&lt;/div&gt;&lt;div&gt;圏論の観点からの意義は、知らない語ばっかりでいまいちよくわからなかった。好奇心の観点からは、色んなものがモナドでっせーみたいな話のようで、もしかしたら後で出てくる「色んなものを圏の枠組みで見ると同じように見え、同じような問題が同じように解ける」とかいう話と関係しているのかもしれない。が、よくわからない。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;回路とか関数とかの書き方&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;[ ボックス図 ]&lt;br /&gt;&lt;/div&gt;&lt;div&gt;関数をブラックボックスとして記述。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 238);"&gt;&lt;img src="http://2.bp.blogspot.com/_Sde1cTDCAXc/SfEf49jLBLI/AAAAAAAAA8o/WHYXYQfSfYs/s320/box.png" alt="" id="BLOGGER_PHOTO_ID_5328074897611228338" style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 186px; height: 320px;" border="0" /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;[ オダンゴ図 ]&lt;/div&gt;&lt;div&gt;ボックス図の省略版。箱を書くのがめんどうくさいので生まれたらしい。ボックス図もそうだが、ブラックボックスの内部を書くこともできる。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 238);"&gt;&lt;img src="http://3.bp.blogspot.com/_Sde1cTDCAXc/SfEgBy40C_I/AAAAAAAAA8w/5IVkxNqfp2g/s320/dango.png" alt="" id="BLOGGER_PHOTO_ID_5328075049368030194" style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 170px; height: 320px;" border="0" /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;[ ストリング図 ]&lt;/div&gt;&lt;div&gt;オダンゴが小さくなった感じ。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 238);"&gt;&lt;img src="http://4.bp.blogspot.com/_Sde1cTDCAXc/SfEgLmYe1NI/AAAAAAAAA84/x1HI26RkILA/s320/string.png" alt="" id="BLOGGER_PHOTO_ID_5328075217809888466" style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 182px; height: 320px;" border="0" /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;さて、以下の3つの関数で…&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;f(x, y) = 3x + y&lt;br /&gt;&lt;/li&gt;&lt;li&gt;g(z) = z + 1&lt;br /&gt;&lt;/li&gt;&lt;li&gt;h(x) = x * x + x&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;f(x, y) と g(z) のComposition（結合・合成）をオダンゴ図で書いてみる。&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 238);"&gt;&lt;img src="http://4.bp.blogspot.com/_Sde1cTDCAXc/SfEgb-6lKVI/AAAAAAAAA9A/x4-QWv-vALs/s320/fg.png" alt="" id="BLOGGER_PHOTO_ID_5328075499273267538" style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 266px; height: 320px;" border="0" /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;きたねええええええ！&lt;/div&gt;&lt;div&gt;…h(x) をオダンゴ図で書いてみる。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 238);"&gt;&lt;img src="http://4.bp.blogspot.com/_Sde1cTDCAXc/SfEgqW7vUeI/AAAAAAAAA9I/KK2IlnUBEJk/s320/h.png" alt="" id="BLOGGER_PHOTO_ID_5328075746238747106" style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 226px; height: 320px;" border="0" /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;h が少し面白いのは、普通に書こうとすると、x が1つしかないので2乗などができずに困ってしまう点。xを複製するようなワイヤリングをすればいいのだけど、このようにに、引数も消尽され得るリソースだと考えると、コンピュータによる計算のリソースセンシティブな部分をうまく表現できるようだ。これは、論理の世界で考えると&lt;a href="http://ja.wikipedia.org/wiki/%E7%B7%9A%E5%BD%A2%E8%AB%96%E7%90%86"&gt;線形論理&lt;/a&gt;に対応しているらしい。なんか前回そんなことを言っていた。この複製（や交差）なんかのワイヤリングを計算と考えることもできる。&lt;/div&gt;&lt;div&gt;テキスト表記（Symbolic Calculationというらしい）だとわからなかったことが、絵算（Pictorial Calculationというらしい）だとわかる、というのも面白いところ。これらは一長一短があるので、状況によって使い分けるといい、とのこと。&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;引数・戻り値の数&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;引数は複数あるが、戻り値は常に1つでないといけないのか？&lt;/div&gt;&lt;div&gt;そんなことはない。実際、先ほどの f と g の合成関数の例では、ボックス（ダンゴ）の位置を少し変えれば（合成関数自体は同じでも）簡単に戻り値が複数あるような関数に変更できる。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 238);"&gt;&lt;img src="http://1.bp.blogspot.com/_Sde1cTDCAXc/SfEk_rIXQdI/AAAAAAAAA9Q/pMvf425p7rI/s320/fgh.png" alt="" id="BLOGGER_PHOTO_ID_5328080510484169170" style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 202px; height: 320px;" border="0" /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;が、人間は多値（特に戻り値）を扱うのはあまり得意ではないので、1つにしていることが多い。複数必要になった場合には、タプルで対応する。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;f: A, B =&gt; C&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;これはAとBの2引数を取り、Cを返す関数だが、&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;f': A×B =&gt; C&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;このような、A×B型のタプルを引数として取る関数とまぁ同じと考えて良い。掛け算記号の×は、タプル型をあらわす。タプルは色んな表記法があり、（特にプログラミング言語では）()だったり[]だったり{}だったりする。プログラミング言語から中立であることを示しつつタプルを表記するため、&lt;&gt;をよく使うらしい。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;f'(&amp;lt;x, y&amp;gt;&lt;x, y=""&gt;&lt;x,&gt;) = f(x, y)&lt;/x,&gt;&lt;/x,&gt;&lt;/div&gt;&lt;div&gt;g'(x, y) = g(&amp;lt;x, y&amp;gt;&lt;x,&gt;&lt;x, y=""&gt;)&lt;/x,&gt;&lt;/x,&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;これは、絵算で言うと、ワイヤーを束ね（て1本にす）ることに相当する。フラットケーブルとかそういうやつ。こんな感じ。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 238);"&gt;&lt;img src="http://2.bp.blogspot.com/_Sde1cTDCAXc/SfEmoYsF6UI/AAAAAAAAA9Y/uyyOjloc200/s320/tuple.png" alt="" id="BLOGGER_PHOTO_ID_5328082309420017986" style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 270px; height: 320px;" border="0" /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;ダンゴ図で書くときは、右下にちっちゃく書いてるように、ゴムみたいなので束ねるように書いたりする。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;ストリング図とアロー図&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;今まで書いてきた、ボックス図・オダンゴ図は、どちらもストリング図という種類になるが、一般的に図（Diagram）というと、たいていはアロー図を指す。以下のような関数について考えてみる。&lt;/div&gt;&lt;div&gt;f: A =&gt; B&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;[ ストリング図 ]&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 238);"&gt;&lt;img src="http://4.bp.blogspot.com/_Sde1cTDCAXc/SfEoPLFAPbI/AAAAAAAAA9g/eEudb6ugncg/s320/string-d.png" alt="" id="BLOGGER_PHOTO_ID_5328084075292933554" style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 276px;" border="0" /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;関数が箱（または点）、引数や戻り値が矢印（アロー）になっている。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;[ アロー図 ]&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 238);"&gt;&lt;img src="http://4.bp.blogspot.com/_Sde1cTDCAXc/SfEofrVO5TI/AAAAAAAAA9o/lid-hTi-MR4/s320/arrow-d.png" alt="" id="BLOGGER_PHOTO_ID_5328084358828844338" style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 305px; height: 126px;" border="0" /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;関数が矢印（アロー）、引数や戻り値が点になっている。&lt;/div&gt;&lt;div&gt;# なんか、圏っぽい。てか圏のセミナーでした。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;この2つの違いは単に趣味的なものではなく、大きな差である、らしい。ちなみに、アロー図はペースティング（Pasting）図や球状（Globular）図とも言うらしいが、これは絵を2次～3次元に拡張した場合に円や球に見えるから、だそう。スライドには高次圏とか書いてあるし、とりあえず今はわからなさそうなので飛ばしてしまう。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;矢印で何を表すのか&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;矢印は、色んな意味で使われるので注意が必要。違うことが同じ記号や同じ言葉で語られるため、混乱しやすい。これから出てくるものとしては…&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;要素関の対応関係（集合の要素、元同士の対応関係）&lt;/li&gt;&lt;li&gt;集合同士の対応関係（集合同士の対応関係、写像？）&lt;/li&gt;&lt;li&gt;関手（どうやら圏と圏の対応のようなものらしい）&lt;/li&gt;&lt;li&gt;自然変換（関手同士の対応のようなものに見えるが）&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;こんなものが、すべて矢印であらわされる。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;圏、しりとり圏&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;はじめての圏論で書かれていた、&lt;a href="http://d.hatena.ne.jp/m-hiyama/20060821/1156120185"&gt;しりとり圏&lt;/a&gt;をもとに圏を説明。以下、しりとり圏の構成要素の転記。&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;対象の集合: H -- ひらがな文字全体の集合&lt;/li&gt;&lt;li&gt;射の集合: HStr -- ひらがな文字列全体の集合&lt;/li&gt;&lt;li&gt;域 dom と余域 cod ： first, last : HStr =&gt; H（最初と最後の文字）&lt;/li&gt;&lt;li&gt;恒等 id : unit : H =&gt; HStr（1文字からなる文字列）&lt;/li&gt;&lt;li&gt;結合（composition） : しりとり結合 s;t は last(s) = first(t) のときだけ定義される&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;まずは、圏のなんとなーくのイメージをつかむ。といっても、今まで出てきた話の延長線上にある。というか、もちろんそういう風に話を持っていっているんだと思います :-D&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;対象というのは、アローダイアグラムでの点みたいなもの。射というのは、アローダイアグラムでの矢印のようなもの。域というのは、矢印の出発点側にくっついている点のようなもの。余域というのは、アローダイアグラムの終点側についている点のようなもの。&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 238);"&gt;&lt;img src="http://1.bp.blogspot.com/_Sde1cTDCAXc/SfExjMJVyNI/AAAAAAAAA9w/fhySGr_W6os/s320/omdc.png" alt="" id="BLOGGER_PHOTO_ID_5328094314781591762" style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 231px;" border="0" /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;結合は、（つなげられる）矢印同士をつなげること。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 238);"&gt;&lt;img src="http://2.bp.blogspot.com/_Sde1cTDCAXc/SfExyh_YS8I/AAAAAAAAA94/Fsa4NHeC30U/s320/composition.png" alt="" id="BLOGGER_PHOTO_ID_5328094578343431106" style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 272px;" border="0" /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;# f;g は、fとgの結合です。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;恒等は…ものすごくぶっちゃけていえば、ある点から出て同じ点に帰ってくる矢印みたいなもの。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Sde1cTDCAXc/SfE1NbhuSpI/AAAAAAAAA-A/vYlVa8bNmo8/s1600-h/id.png"&gt;&lt;img src="http://3.bp.blogspot.com/_Sde1cTDCAXc/SfE1NbhuSpI/AAAAAAAAA-A/vYlVa8bNmo8/s320/id.png" alt="" id="BLOGGER_PHOTO_ID_5328098338999782034" style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 146px; height: 145px;" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;で、同じ点に帰ってくる矢印なんだから、他の矢印と結合しても、元の矢印（がたどり着く点）は変わらないでしょう、というようなもの。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Sde1cTDCAXc/SfE1X3afArI/AAAAAAAAA-I/-BPwGi-p_YM/s1600-h/id-composition.png"&gt;&lt;img src="http://2.bp.blogspot.com/_Sde1cTDCAXc/SfE1X3afArI/AAAAAAAAA-I/-BPwGi-p_YM/s320/id-composition.png" alt="" id="BLOGGER_PHOTO_ID_5328098518284305074" style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 227px; height: 193px;" border="0" /&gt;&lt;/a&gt;なんかこんなイメージ。これを、しりとりにあてはめると、こんな感じになる。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 238);"&gt;&lt;img src="http://1.bp.blogspot.com/_Sde1cTDCAXc/SfE5ftr3fRI/AAAAAAAAA-Q/Vo6EBrwhdA8/s320/siritori.png" alt="" id="BLOGGER_PHOTO_ID_5328103051158322450" style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 271px; height: 320px;" border="0" /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;# 実際には、点や線はもっとたくさんある。&lt;/div&gt;&lt;div&gt;以下、圏の構成要素がしりとり（圏）において何に対応しているのか考える。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;[ 対象 ]&lt;br /&gt;&lt;/div&gt;&lt;div&gt;対象は、ここで言えばひらがな1文字1文字のことにしてある。'あ' とか 'い' とかそういうやつ。なので、対象の集合は、ひらがな文字全体の集合になる。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;[ 射 ]&lt;/div&gt;&lt;div&gt;射は、対象、つまりひらがな文字の間に引く矢印みたいなもので、今回は（ひらがな文字を並べた）文字列、ということにする。射の集合は、ひらがな文字列全体の集合。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;[ 域と余域 ]&lt;/div&gt;&lt;div&gt;域は、文字列の先頭の文字とする。"きまいら"の域は、'き'。余域は、文字列の末尾の文字とする。"きまいら"の余域は、'ら'。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;[ 結合 ]&lt;/div&gt;&lt;div&gt;結合は、射（つまり文字列）同士をくっつけることで、定義では「1つめの射の余域」と「2つめの射の域」が同じでなくては結合できない。これを今までの定義で言い換えると、「1つめの文字列の末尾の文字」と、「2つめの文字列の最初の文字」が同じでなければ結合できない、となる。つまり、しりとりできる文字列しか結合できない。今回の結合では、（しりとり可能な）文字列同士を結合し、重複した文字を（1つ）取り除くこと、とする。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;"きまいら";"らいおん" =&gt; "きまいらいおん"&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;こんな感じ。なんかしりとりっぽくなってきた。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;[ 恒等 ]&lt;/div&gt;&lt;div&gt;恒等は、射と結合しても変わらない射なので、これまで決めてきたことから考えると、長さ1の文字列になる。"あ"とか"い"とか。例としては…&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;"きまいら";"ら" =&gt; "きまいら"&lt;/div&gt;&lt;div&gt;"き";"きまいら" =&gt; "きまいら"&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;こんな感じ。少し前のざっくりした説明だと、同じ点に帰ってくる矢印みたいなもん、って書いてたんだけど、同じ点に帰ってくる射（文字列）でも、"きつつき" なんかは恒等にはならない。これは、他の射と結合した場合に違う射になってしまい、定義を満たさないから。たぶん。&lt;/div&gt;&lt;div&gt;# 射が同じってのは、定義しなくても大丈夫なんだろうか？文字列が同じって考えていいんだよなぁ…？&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;恒等自体は射（矢印）なので、"あ"とか"い"とかは、文字ではなく文字列なのに注意。&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 238);"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;圏の法則&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;ここで、圏の法則をば。下つき文字の書き方がわからないので unit はプログラミング言語っぽく書いちまいます。今作ったしりとりの圏が、この法則を満たしていることを確認する。&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;first(unit(x)) = last(unit(x)) = x (x∈H)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;first(s;t) = first(s), last(s;t) = last(t)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;(s;t);u = s;(t;u)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;x = first(s), y = last(s) なら、unit(x);s = s;unit(y) = s&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;[ 1つめ ]&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;対象xの恒等（射）の域は、対象xに等しい。&lt;/li&gt;&lt;li&gt;対象xの恒等（射）の余域は、対象xに等しい。&lt;/li&gt;&lt;/ul&gt;と言っている。しりとりで文字をあてはめてみると…&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;文字: 'あ'&lt;br /&gt;&lt;/li&gt;&lt;li&gt;対応する1文字の文字列: "あ"&lt;br /&gt;&lt;/li&gt;&lt;li&gt;文字列 "あ" の域: 'あ'&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;というわけで、きちんと法則を満たしている。当たり前か。末尾も同じ。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;[ 2つめ ]&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;射sと射tを結合した射の域は、射sの域に等しい&lt;br /&gt;&lt;/li&gt;&lt;li&gt;射sと射tを結合した射の余域は、射tの余域に等しい&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;これもしりとりで文字をあてはめてみると…&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;射s: "きまいら"&lt;/li&gt;&lt;li&gt;射t: "らいおん"&lt;/li&gt;&lt;li&gt;射sとtの結合: "きまいらいおん"&lt;/li&gt;&lt;li&gt;射sとtの結合の域: 'き'&lt;br /&gt;&lt;/li&gt;&lt;li&gt;射sの域: 'き'&lt;/li&gt;&lt;li&gt;射sとtの結合の余域: 'ん'&lt;/li&gt;&lt;li&gt;射tの余域: 'ん'&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;というわけで、成り立っている。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;[ 3つめ ]&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;射sと射tを結合し、それに射uを結合したものは、射sに射tと射uの結合を結合したものと同じ&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;全然わかりやすくなってないな…。しりとり。&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;射s: "でんき"&lt;/li&gt;&lt;li&gt;射t: "きまいら"&lt;/li&gt;&lt;li&gt;射u: "らいおん"&lt;/li&gt;&lt;li&gt;(s;t);u: ("でんき";"きまいら");"らいおん = "でんきまいら";"らいおん" = "でんきまいらいおん"&lt;/li&gt;&lt;li&gt;s(t;u): "でんき";("きまいら";"らいおん") = "でんき";"きまいらいおん" =  "でんきまいらいおん"&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;成り立っている。なんかむなしくなってきた。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;[ 4つめ ]&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;射sの域がxであり、余域がyであるならば…&lt;/li&gt;&lt;li&gt;xの恒等（射）unit(x) と 射sの結合は、射sに等しい&lt;/li&gt;&lt;li&gt;射sとyの恒等（射）unit(y) の結合は、射sに等しい&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;しりとりで。&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;射s: "きまいら"&lt;/li&gt;&lt;li&gt;射sの域 x: 'き'&lt;/li&gt;&lt;li&gt;射sの余域 y: 'ら'&lt;/li&gt;&lt;li&gt;xの恒等 : "き"&lt;/li&gt;&lt;li&gt;yの恒等 : "ら"&lt;/li&gt;&lt;li&gt;xの恒等と射sの結合 : "き";"きまいら" = "きまいら"&lt;br /&gt;&lt;/li&gt;&lt;li&gt;射sとyの恒等の結合 : "きまいら";"ら" = "きまいら"&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;OK。しりとり圏はちゃんとした圏。らしい。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;unitで混乱&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;セミナーの最後に、unitに関して質問があり、微妙に混乱した。内容は…&lt;/div&gt;&lt;div&gt;構成要素には、unit が「対象」から「射」への写像（って言ってたかなぁ…）だとされているけど、絵で見ると恒等というのは「対象」から「対象」への射になっているので、別のものですよね？というもの。&lt;/div&gt;&lt;div&gt;これはたぶん…&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;unit: unit(x) で「対象xに関する恒等（射）」をあらわすもの、つまり対象から射への写像&lt;/li&gt;&lt;li&gt;unit(x) : ある対象xに関する恒等（射）、unitに具体的に対象が与えられたもの&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;というものがごっちゃになって混乱した、という話だと思った。あってるのだろうか。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;Map Finite Ordinals&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;２つめの圏の例。こんな対象を考えてみる。&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;[0] = {}&lt;/li&gt;&lt;li&gt;[1] = {1}&lt;/li&gt;&lt;li&gt;[2] = {1, 2}&lt;/li&gt;&lt;li&gt;[3] = {1, 2, 3}&lt;/li&gt;&lt;li&gt;[4] = {1, 2, 3, 4}&lt;/li&gt;&lt;li&gt;…&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;射の具体的な内容は、要素間の対応関係（の組み合わせ）になる。ここで、対象間の矢印と要素間の矢印は違うものをあらわしていることに注意。&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 238);"&gt;&lt;img src="http://4.bp.blogspot.com/_Sde1cTDCAXc/SfFTDVfzXmI/AAAAAAAAA_c/MOFUgFgv5qw/s320/mapfo-1.png" alt="" id="BLOGGER_PHOTO_ID_5328131150931254882" style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 249px; height: 320px;" border="0" /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;具体的に域が[2], 余域が[3]であるような射について考えてみると、射の数は9つになる。これは、実際に書いてみればわかる（が省略！）。[1]も加えて射の数を考えてみると…&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 238);"&gt;&lt;img src="http://2.bp.blogspot.com/_Sde1cTDCAXc/SfFLNWTBA9I/AAAAAAAAA-g/GXsY7mtDXmc/s320/mapfo-2.png" alt="" id="BLOGGER_PHOTO_ID_5328122526851728338" style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 203px; height: 320px;" border="0" /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;こんな感じ。一般化すると、[n] から [m]への射の数は、mのn乗になる。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;# この先はハイスピードでとばしまくり。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;部分圏&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;MapFOの中でも、こんなものは部分圏になる。&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;InjFO 単射の圏&lt;/li&gt;&lt;li&gt;IsoFO 同型射の圏&lt;/li&gt;&lt;li&gt;IncFO 包含写像の圏&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;IncFOよくわからなかった。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;関手&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;スライド0.2秒くらい、説明ゼロでした :-D&lt;/div&gt;&lt;div&gt;例を見ると、HSiri =&gt; KSiri が関手になっているので、圏を「対象」として見たとき、つまり圏の圏を考えたときの射が関手、ということなんだと思う。けど、具体的なイメージが…。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;同じに見える色んな問題&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;スライドに書いてある色んな問題たちが同じようにみなせるらしい。が、どれとどれが同じなのか、はたまた全部同じなのか、よくわからなかった。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;時間切れ、終了。なんか飲み会行ってテンションあがったので頑張って書いてみた。他の出席者の方のように、「あー、なるほど、あれがあれね！」とか「じゃああれはこうですか？」みたいなつっこんだ話は全然できず、道のりの長さが感じられたんだけど、それはそれでよかった。わかってること勉強しにいってもしょうがないしね。もう少し初級者向け（幻想？）の圏論読書会も立ち上がるかもしれない雰囲気。&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-708097122844777720?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/708097122844777720/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=708097122844777720&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/708097122844777720'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/708097122844777720'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2009/04/1.html' title='技術者／プログラマのためのモナドと圏論 第1回 行ってきた'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_Sde1cTDCAXc/SfEf49jLBLI/AAAAAAAAA8o/WHYXYQfSfYs/s72-c/box.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-6606802808605277497</id><published>2009-04-18T23:00:00.009+09:00</published><updated>2009-04-27T08:42:45.798+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='セミナー/勉強会'/><category scheme='http://www.blogger.com/atom/ns#' term='report'/><title type='text'>アーキテクトの審美眼</title><content type='html'>&lt;div   style="border-width: 0px; margin: 0px; padding: 3px; font-size-adjust: none; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; text-align: left; width: auto;font-family:Georgia,serif;font-size:100%;"&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;MS萩原さんのセッション。同名の書籍（元ネタはDBマガジンの同名の連載）が元になっていて、そのダイジェスト版＋最新の動向の補足、という形。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;とても示唆に富んでいるんだけど、抽象的な上に、1つ1つのトピックがめちゃめちゃ重たいので、きちんと理解しようとすると調べる量がとても多くなってしまう上に、そもそも理解しきるのが難しすぎる。とりあえずは現段階の自分の稚拙な理解をもとに、こんなことじゃないかなーと補足しながら書いていく。&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=";font-family:'MS PGothic';font-size:130%;"  &gt;&lt;span style="font-weight: bold;"&gt;アーキテクチャの原則&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;アーキテクトにとっては、アーキテクチャの原則を理解することが重要。アーキテクチャの原則は、インフラなどが変化しても変わらず、クラウドでも通用する。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=";font-family:'MS PGothic';font-size:130%;"  &gt;&lt;span style="font-weight: bold;"&gt;アーキテクチャ先行定義の原則&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;アーキテクチャは先行定義せねばならぬ、という原則。アーキテクチャ設計を含むソフトウェア開発は、こんな風な流れになるはず。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;a href="http://2.bp.blogspot.com/_Sde1cTDCAXc/SeaXdVn40BI/AAAAAAAAA8Y/NLGd2e-oplc/s1600-h/architecture.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" id="BLOGGER_PHOTO_ID_5325110139688636434" src="http://2.bp.blogspot.com/_Sde1cTDCAXc/SeaXdVn40BI/AAAAAAAAA8Y/NLGd2e-oplc/s320/architecture.png" style="margin: 0px auto 10px; cursor: pointer; display: block; height: 315px; text-align: center; width: 320px;" border="0" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;モデリングとアーキテクチャ設計の双方のインプットとして、システムの機能要求・非機能要求があげられていた。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;■ モデリング&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;この部分は、システム化対象（ドメイン）を何らかのパラダイム（DOA/OOAなど）でモデル化する作業だと思われる。ドメインモデリングであれば、主に機能要件がそのインプットとなりそうだ。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;■ アーキテクチャ設計&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;アーキテクチャパターンやリファレンスモデルをもとに、機能/非機能要件を満たしうるアーキテクチャを整備していく作業だと思われる。アーキテクチャ設計では、例として以下のような項目を（仮）決めしていくようだ。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;# メモしきれなかったので一部のみ ^^;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;li&gt;プラットフォーム&lt;/li&gt;&lt;li&gt;フレームワーク&lt;/li&gt;&lt;li&gt;データモデル&lt;/li&gt;&lt;li&gt;トランザクションモデル&lt;/li&gt;&lt;li&gt;セキュリティ&lt;/li&gt;&lt;/span&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;[メモ]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;図では、モデリングとアーキテクチャ設計が並列になっているが、モデリングとアーキテクチャ設計を完全に独立で実施できるとは思えない。アーキテクチャ設計にフレームワークやデータモデルが入っていることから、お互いになんらかの関係があることを示唆している気もする。もしかしたら、順序関係や依存関係を定義した図ではないのかもしれないし、マッピング/設計のフェーズがそれを包含しているのかもしれないが、セッションからはよくわからなかった。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;個人的にここで重要だと思うのは、システム開発にはなんらかの形での「システム化対象のモデリング」が存在することを明示している点。そして、DOAやOOAを包含して「モデリング」としている点。データモデリングやオブジェクト指向モデリングをしているんじゃなく、「システム化対象」を「データの観点」や「オブジェクトの観点」からモデリングしているんだ、というのは、個人的になんだかしっくりくる。&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:'MS PGothic';"&gt;[/メモ]&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=";font-family:'MS PGothic';font-size:130%;"  &gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=";font-family:'MS PGothic';font-size:130%;"  &gt;&lt;span style="font-weight: bold;"&gt;データアーキテクチャの原則&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;データには、マスターデータとトランザクションデータが存在するが、それぞれのデータには特性があり、扱う方法にも原則がある、という話。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;■ マスターデータ&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;li&gt;複数のアプリケーションで共通的に使われるデータ&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;論理的には&lt;/span&gt;アプリケーションの外に出すのが原則&lt;/li&gt;&lt;/span&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;■ トランザクションデータ&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;li&gt;属性として「時間」を持っている&lt;/li&gt;&lt;li&gt;追加（新規作成）のみで、変更も削除もされない&lt;/li&gt;&lt;li&gt;ETLなどでDWHやDMにぶちこまれる&lt;/li&gt;&lt;/span&gt;&lt;/ul&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;span style="color: rgb(0, 0, 238);"&gt;&lt;img alt="" id="BLOGGER_PHOTO_ID_5325118038219482242" src="http://1.bp.blogspot.com/_Sde1cTDCAXc/SeaepF8Y5II/AAAAAAAAA8g/s3TII3Lj8m8/s320/dataarchitecture.png" style="margin: 0px auto 10px; cursor: pointer; display: block; height: 242px; text-align: center; width: 320px;" border="0" /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;# なんかこんな感じだった気がする。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;実際は、特にマスターデータに関してはこのようになっていないことが多い。これは、マスターデータ自体の共通性は高いのだが、ビューが異なると必要な属性が異なってくる（属性にバリエーションがある）ため、Factor outしづらいのが原因。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;なお、マスターデータは論理的に一箇所で管理すればよく、必ずしも物理的に一箇所で管理する必要はない。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;[メモ]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;li&gt;マスター、トランザクションの区分はデータモデリングの王道中の王道。THでもTMでも、定義の厳密性や名前の違い（イベント/リソースなど）こそあれ、基本的なスタンスは同じ。&lt;br /&gt;&lt;/li&gt;&lt;li&gt;マスターデータをアプリケーションにまたがって共通的に持つ、というのは、最近DOA界隈（と言ってしまっていいのだろうか）ではやりのMDM（Master Data Management）と同じですね。データ総研の椿さんも同じこと言ってました。&lt;br /&gt;&lt;/li&gt;&lt;li&gt;マスターデータがコンテキストごとに属性のバリエーションを持つ、という問題を解決する方法は明示されなかった気がするんだけど、どのように考えているんだろうか？「外だしする＝共通性として認識する」、「コンテキスト（アプリケーションやビュー）ごとに持つ＝可変性として認識する」と考えると、結局は共通性と可変性の認識の問題になる気がする。負の可変性とか。この境界は、時間の経過や事業領域の変更でも変わっていくのだと思われる。&lt;br /&gt;&lt;/li&gt;&lt;li&gt;物理的に一箇所にする（大福帳DB？）のではなく、論理的に一箇所にすれば良い、というのは現実を考えると非常に重要だと思う。&lt;br /&gt;&lt;/li&gt;&lt;/span&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;[/メモ]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=";font-family:'MS PGothic';font-size:130%;"  &gt;&lt;span style="font-weight: bold;"&gt;Entity（個体）識別の問題&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;Entityはそれ単独（そのものが持つ本質的な特性）では決まらず、他との相対的な関係でしか決定できない。Relationshipは関数従属性であり、ビジネスから決まる、とも言っていた。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;[メモ]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;これは、データモデリング（OOも）の永遠の課題である、個体（Entity）をどうやって認識するのか、という話だと思うが、CoddのRelationalモデルとChecnのEntity-RelationshipモデルはどちらもEntityの識別方法を与えてくれない。詳しくは忘れてしまったけど、そもそもRelationalModelにはEntityなんてなかったと思うし。ChenのE-Rモデルでは、Eのまともな定義がないため、抽出の役に立たない。&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;TMとTH、両方のセミナーを受けたことがあるんだけど、ChenのERモデルが工学的（実務的？）に問題があることまでは共通の認識として持っていて、それぞれに定義を補足した上で抽出手順を決めている。詳しくはそれぞれのモデリング技法をどぞ！&lt;br /&gt;&lt;br /&gt;追記：&lt;br /&gt;書籍の方では、データモデリングにおいては既存の帳票や画面からのボトムアップ＋関数従属性による正規化によって、Entityは一意に識別できる。が、OOの場合はトップダウンにならざるを得ず、一意性を保証できない点が問題だ、という感じで書いてあった。&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;[/メモ]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;アプリケーションの設計モデルは、データモデルと独立して定義可能。ビジネスモデルをそのまま反映することもできる。アプリケーション設計モデルのコアな部分は、ユースケースと独立して、先行して定義する。関係はユースケースが決まらないと確定しないので、ブレが大きくなる。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;[メモ]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;「アプリケーション設計モデル」が少しわかりづらいんだけど、自分はアプリケーションの構造（特に、PoEAAのDomain Logic Patternsに相当するもの）の選択と、それがドメインごとに具体化されたものだと理解した。そうすると、Domain Logicのモデルはデータモデルとはある程度独立になる話も理解できるし、アプリケーション設計モデルのコアがUCの定義に先立つ、という話も、勘定構造（Accounting Patterns）の導入などと絡めて考えれば理解しやすい。気がする。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;[/メモ]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=";font-family:'MS PGothic';font-size:130%;"  &gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=";font-family:'MS PGothic';font-size:130%;"  &gt;&lt;span style="font-weight: bold;"&gt;縦の構造と横の構造&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;アプリケーションの構造は、縦の構造（Entity）と横の構造（Relationship）から成ると考えることができる。縦の構造は比較的固定化されており、横の構造は比較的流動的。変更要求があった際に、それが縦の構造に影響を与えるか、横の構造に影響を与えるかによって、修正コストは大幅に違ってくる。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;# よって、（このコンテキストでは）いかにEntityを安定なものにするかが重要になってくる。&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;[メモ]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt; この「縦の構造」と「横の構造」は、ソフトウェア（ひいてはビジネス）は視点によって複数の構造を取りうることを表している。&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:'MS PGothic';"&gt;ただ、モデルとしては複数の構造を持っていたとしても、複数の構造をソフトウェアとして実装するのは&lt;/span&gt;&lt;span style="font-family:'MS PGothic';"&gt;単一のパラダイムでは&lt;/span&gt;&lt;span style="font-family:'MS PGothic';"&gt;難しい。&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:'MS PGothic';"&gt;手続き型では階層的に詳細化された手続きを呼び出すような単純な構成になるし、オブジェクト指向であってもクラス構造は基本的に単一で、まったく違うクラス構造を重ね合わせて実装することはできない（多重継承やMix-inはある程度これを可能にするが）。&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:'MS PGothic';"&gt;複数のパラダイムが形作る構造が対等な関係で関連し合うようなアーキテクチャも考えられるのかもしれないが、現段階では主たるパラダイムが主たる構造を構成し、それ以外のパラダイム（やメカニズム）が補足的な構造を形作ることが多い。この、主たる構造が縦の構造、補足的な構造が横の構造と呼ばれているのかなーと感じた。&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:'MS PGothic';"&gt;補足的な構造を導入するためのパラダイムがアスペクト指向で、現状では主としてアスペクト指向プログラミングが、（ビジネス構造を表す主たるクラス構造に）非機能要求の実現を表す構造を導入する形で用いられている。ヤコブソンは、アスペクト指向による分析・設計を考えており、ユースケース（というアスペクト）を分析・設計段階で扱うことを考えているようだが…。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;[/メモ]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=";font-family:'MS PGothic';font-size:130%;"  &gt;&lt;span style="font-weight: bold;"&gt;パラダイムの進化&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;オブジェクト指向には限界がある。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;li&gt;言語間の通信が困難&lt;/li&gt;&lt;li&gt;動的なオブジェクトのブートやシャットダウン&lt;/li&gt;&lt;li&gt;非機能の扱いが困難&lt;/li&gt;&lt;/span&gt;&lt;/ul&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;[メモ]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;言語間の通信とか、OOの問題ではなく、OOの典型的なプラットフォームが持つ問題のような気がするんだけど…。動的なオブジェクトのブートやシャットダウンも同じく。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;[/メモ]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;パラダイムは進化してきた。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;手続き型 =&amp;gt; オブジェクト指向 =&amp;gt; コンポーネント指向 =&amp;gt; サービス指向 =&amp;gt; Web指向&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;[メモ]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;コンポーネント指向は、言語間の通信が困難である点を解消する。サービス指向が改善するものはなんだろう？再利用可能性だろうか？&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;Web指向というのは聞いたことがなかったんだけど、分散化され、メッシュ上にリンクされたリソースをコードが扱う、というモデルらしい。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;[/メモ]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;これらの進化は、古いものを置き換えてきた&lt;span style="font-weight: bold;"&gt;というわけではない&lt;/span&gt;点が重要。新たに登場したパラダイムでの開発には、以前にパラダイムも必要になる。組み合わせて使うことが必要。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;[メモ]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;フレームワークやミドルウェアの登場で開発はどんどん簡単になっているはずなのに、なぜか難しく感じる理由は、これである程度説明できるのかもしれない。抽象の破れとあわせて説明すれば、直接開発に関わらない人が「うまく開発することが、なぜいまだに難しいのか」を理解する助けになるだろうか。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;[/メモ]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=";font-family:'MS PGothic';font-size:130%;"  &gt;&lt;span style="font-weight: bold;"&gt;モデルをどう作るか？&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;システムはさまざまな視点からのモデル化することになるが、どのようにすればうまく表現できるのか？&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;# モデルの話再び。個人的にはここが最重要トピック。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;問題をうまく分類し、分割することが重要。単一のパラダイムではうまく対応できないため、マルチパラダイムで対応する。これから、いくつかのパラダイムとその問題点を見ていく。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;■ オブジェクト指向&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;クラス決定に一意性がなく、属人的であることが問題とみなされる。このせいで、手続き指向への回帰が起こっているケースが多々見られる。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;（個別UCの）要求によってクラスの構造を変えてはならない。要求の実現ではなく、保守性を目的としてクラス構造を取る。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;OOには多くの制約があり、これを乗り越える・補完するためにさまざまなパラダイムが考案・導入されつつある。&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;■ アスペクト指向&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:'MS PGothic';"&gt;可変性にフォーカスした技術。メモで前述。このあたりから全部、ものすごいさらっと紹介していく流れに。&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;[メモ]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:'MS PGothic';"&gt;可変性というのは、ドメイン工学やマルチパラダイムデザインの用語で、システム・もしくは概念の変わりうる部分のこと。AOPが可変性にフォーカスした技術である、ということは、システムの変わりうる部分をアスペクトとして実装することが意図されている、ということだろうか。あまりそんな風に使ってないような気がするが。&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:'MS PGothic';"&gt; ユースケースをアスペクトとして扱うのであれば、この言説に合致するんだけど、あってるのだろうか。&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:'MS PGothic';"&gt; [/メモ]&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;■ サブジェクト指向（Subject Oriented）&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:'MS PGothic';"&gt;再利用にフォーカスした技術らしい。こちらもさらっとした紹介程度で終了。&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:'MS PGothic';"&gt;[メモ]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:'MS PGothic';"&gt;どんなものかもわからないので、Webで調べてみた。&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;a href="http://en.wikipedia.org/wiki/Subject-oriented_programming"&gt;サブジェクト指向プログラミング&lt;/a&gt;（Wikipedia英語版）：&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;サブジェクト指向プログラミングは、下記をサポートするようなプログラミング手法を指す。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;サブジェクトの組み合わせによるオブジェクト指向システムの構築&lt;/li&gt;&lt;li&gt;システムの、既存サブジェクトおよび新規サブジェクトの組み合わせによる拡張&lt;/li&gt;&lt;li&gt;サブジェクトの組み合わせによる、システムの統合&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;サブジェクトの組み合わせがもたらす柔軟性によって、OOプログラムの開発やモジュール化に新たな機会がもたらされる。&lt;br /&gt;広義のサブジェクト指向は、システムのサブジェクトへの分割や、サブジェクトを正確に組み合わせるためのルールの記述を含む。サブジェクト指向はOOPを補完し、以下のような問題を解決する。&lt;br /&gt;&lt;ul&gt;&lt;li&gt; OOPが大規模システム開発に用いられた際に発生する問題&lt;/li&gt;&lt;li&gt;OOPが、相互運用可能または統合されたアプリケーションスイート開発に用いられた際に発生する問題&lt;/li&gt;&lt;/ul&gt; SOPは、サブジェクトを作る事で、プログラマの認知能力にまつわる問題も解決しようとしている。サブジェクトはその出自からして、アスペクトと大きくは違わない。アスペクトは初期に、主としてコンパイルタイムに先立ってソースを組み立てるようなコードウィーバーのコンセプトに労力を向けていたが、SOPパラダイムはクラスの組み立てに多くを依存している。&lt;/blockquote&gt;&lt;br /&gt;なんのこっちゃ。雰囲気からすると、オブジェクト指向システムをクラスとは別の構造（サブジェクト）に分解し、サブジェクトを組み合わせることでオブジェクト指向システムを構築する、というコンセプトらしい。これも、補完的な構造（横の構造）を導入するためのパラダイムのようだ。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.alphaworks.ibm.com/tech/hyperj"&gt;Hyper/J&lt;/a&gt;：&lt;br /&gt;IBMによる、サブジェクト指向開発環境のJava実装らしい。暇があれば使ってみようかな。&lt;br /&gt;&lt;br /&gt;DCIA：&lt;br /&gt;講演の中で出てきた、サブジェクト指向アプローチか製品のようだけど、調べてもよくわからなかった。&lt;br /&gt;[/メモ]&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;■  &lt;a href="http://domaindrivendesign.org/"&gt;DDD（Domain Driven Design）&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;ビジネスのモデルをそのままソフトウェアクラスの構造に反映する。ユースケースの要求はサービスとして実現することで、ビジネスのモデルを安定にできる。&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:'MS PGothic';"&gt;[メモ]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:'MS PGothic';"&gt; DDDによる本来のサービスの定義は、ビジネスで認知されている純粋な手続きや、複数のドメインクラス（Entity/ValueObjet）にまたがる処理をサービスに記述することになっている。 &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:'MS PGothic';"&gt;結果的にユースケース要求がサービスに実装されることになることもあるかもしれないが、本来のDDDの意図とは少し違っているように思える。DDD本で紹介されている本でも、ユースケースによって徐々にドメインクラスを変更していっているしなぁ。このあたりはできれば直接質問したかったんだけど、できずじまい。&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:'MS PGothic';"&gt; [/メモ]&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;■ フィーチャ指向&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;可変点をフィーチャとして分析する。フィーチャ指向は、静的・コンパイル時バインディングが基本だが、これを動的にバインドできるようにしたものとして、コンテキスト指向というものがある。&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="font-family:'MS PGothic';"&gt;かなりさらっとした紹介で終了。もう少し掘り下げて調べてみようと思ったけど、それはそれで膨大になりそうなので今回は省略。それにしても、フィーチャ指向のフィーチャって可変点だけだっただろうか？システム自体を概念とフィーチャで分析していく手法で、フィーチャの分析として可変かどうかを調べていたような記憶があるんだけど、間違っているかもしれない…。&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;■ セル生産方式&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:'MS PGothic';"&gt;プロセスの抽象化と再利用らしい。さらっと終了シリーズ。&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:'MS PGothic';"&gt;[メモ]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:'MS PGothic';"&gt;セル生産方式の解決する問題が、プロセスの再利用だとは知らなかった。簡単にしか紹介されなかったので、詳しいことはわからずじまい。書籍に期待。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;[/メモ]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:'MS PGothic';"&gt;■ 関数型パラダイム&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:'MS PGothic';"&gt;すべてが関数。クラウドの普及によって、中〜長期的には重要になってくるはず。&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;以上紹介してきたように、パラダイムは多数存在しているが、いずれにしろドメインに特化したパラダイムを選ぶのが重要。&lt;/span&gt;&lt;/div&gt;&lt;div style="font-weight: bold;"&gt;&lt;span style=";font-family:'MS PGothic';font-size:130%;"  &gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-weight: bold;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-family:'MS PGothic';"&gt;妥協のない意思決定の方法&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;目的－手段の階層を意識するのが重要。手段のレベルでトレードオフが発生した場合には、同じレベルでは選択できない。目的−手段階層をさかのぼり、上位の階層でトレードオフを解消できないか（まったく別の手段を取る事ができないか、目的レベルで考えると手段の1つは不要になるのでは、などなど）を考えることで、妥協せずに意思決定することができる。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;span style="font-family:'MS PGothic';"&gt;[メモ]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:'MS PGothic';"&gt;これ重要っすよね。事業戦略もまったく同じで、経営レベルから自分へいたる意思決定のパスが明示されていないと、現場レベルでは判断つかないことが多い。&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:'MS PGothic';"&gt;[/メモ]&lt;/span&gt;&lt;br /&gt;&lt;span style=";font-family:'MS PGothic';font-size:130%;"  &gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size:130%;"&gt;&lt;b&gt;&lt;span style="font-family:'MS PGothic';"&gt;萩原さんの夢とメッセージ&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;プログラミングやインフラなどの実装に近い部分や、ビジネスや要求よりの部分は注目され、色んなことが試されているが、その間の設計の部分は意外と注目されておらず、軽視されているとも言える。ここにはまだまだ向上の可能性があるので、ここをきちんとやっていくということを夢として持っている。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family:'MS PGothic';"&gt;みなさんへのメッセージとしては、&lt;/span&gt;&lt;span style="font-family:'MS PGothic';"&gt;ユニーク性を持つ、ということをすすめたい。ユニーク性のない仕事は、どんどん代替可能な人材に置き換えられ、価値も下がってしまう。ユニーク性を持てば代替は不可能となり、価値を発揮できる。ぜひユニーク性を持ってください。&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:large;"&gt;&lt;b&gt;&lt;span style="font-family:'MS PGothic';"&gt;雑感&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:'MS PGothic';"&gt; 個人的には、一番ストライクゾーンに近かったセッション。ここ1年ほど興味を持って調べていた内容に非常に近く、自分の考えを確認しつつ新たな試みに触れることができた。もちろん、より良い整理のヒントも得ることができた。&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:'MS PGothic';"&gt;内容は全体に浅く広くだったとはいえ、モノの見方を紹介するという意味ではどんな人にとっても刺激になるセッションだったんじゃないだろうか。書籍「アーキテクトの審美眼」も発注したので、届いたら改めて深く掘り下げてみたい。&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;目次：&lt;br /&gt;&lt;a href="http://hibituredure.blogspot.com/2009/04/qcon-tokyo-2009.html"&gt;QCon Tokyo 2009に行ってきた&lt;/a&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span style="font-family:'MS PGothic';"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-6606802808605277497?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/6606802808605277497/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=6606802808605277497&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/6606802808605277497'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/6606802808605277497'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2009/04/blog-post_18.html' title='アーキテクトの審美眼'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_Sde1cTDCAXc/SeaXdVn40BI/AAAAAAAAA8Y/NLGd2e-oplc/s72-c/architecture.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-3334436773712706137</id><published>2009-04-17T20:33:00.009+09:00</published><updated>2009-04-18T03:43:58.077+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='数学'/><category scheme='http://www.blogger.com/atom/ns#' term='コンピュータ科学'/><title type='text'>Yコンビネータにトライ</title><content type='html'>via &lt;a href="http://d.hatena.ne.jp/nowokay/20090409#1239268405"&gt;おとうさん、ぼくにもYコンビネータがわかりましたよ！&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;きしだんさんすごいっす。自分も学習のために、ラムダの復習も兼ねつつJavaScriptでトライしてみる。独学で適当にやってるので間違いも多数あると思いますが、ご容赦を。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;ラムダ&lt;/span&gt;&lt;br /&gt;ラムダ式は、関数の表現形式みたいなもので、おおよそfunction式に相当する。引数が複数あるのが違うところだけど、この話は後で解決する。（非形式的な）ラムダ式ってこんなもの。&lt;br /&gt;&lt;pre class="prettyprint"&gt;λx.x*2&lt;/pre&gt;このラムダ式は、xを受け取ったら2倍して返す関数を表している。&lt;br /&gt;最初は読むのに（特にλ記号が複数になった場合に）とても苦労したんだけど、引数を「λ」と「.」で挟み込む形で表現した関数だ、と考えるとずいぶん読みやすくなった。これをJavaScriptで表すと…&lt;br /&gt;&lt;pre class="prettyprint"&gt;function(x) { return x * 2 }&lt;br /&gt;&lt;/pre&gt;こうなる。ラムダ計算の体系では、計算のすべてをラムダ式であらわす。ラムダ式は関数なので、計算のすべてを関数であらわすということだ。ということで、JavaScriptから余計なものをそぎ落としていきましょー。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;カリー化&lt;/span&gt;&lt;br /&gt;さっきも少し出てきたけど、もともとのラムダ計算体系ではすべての関数は1引数関数として扱う。一般にラムダ計算体系では…&lt;br /&gt;&lt;pre class="prettyprint"&gt;f(x, y) = f(x)(y)&lt;br /&gt;&lt;/pre&gt;が成り立つ（理屈は省略）ので、多引数の関数はすべて1引数の関数に変換できる。こうすれば、多引数のことあんま考えなくてもいいから、世界がシンプルになる。たぶん。&lt;br /&gt;で、カリー化とは、上記左辺の f(x, y) から f(x)(f) への変換のことを言う。Haskellとかで関数の部分適用の話が出てくるけど、Haskellの関数はすべてカリー化されている（1引数関数である）ので、部分適用といっても単に、順番に関数適用しているだけなんだと思う。&lt;br /&gt;&lt;br /&gt;JavaScriptの関数は引数を複数取ることができるが、上記の法則によって、必ず1引数の関数に変換できる。関数や引数が特定された形であれば、特別な機構がなくてもカリー化はできる。&lt;br /&gt;&lt;pre class="prettyprint"&gt;function func(x, y) { return x + y }&lt;br /&gt;&lt;/pre&gt;この関数を引数3でカリー化（＋部分適用）したければ…&lt;br /&gt;&lt;pre class="prettyprint"&gt;curried_func = function(x) { return func(x, 3) }&lt;br /&gt;&lt;/pre&gt;こうすればいい。&lt;br /&gt;# これをカリー化とか部分適用というかどうかは甚だ疑問だが、とりあえずイメージってことで…。&lt;br /&gt;でも、これだと関数や引数が変わるたびにガリガリコードを書かなければいけないので、嬉しくない。どんな関数や引数でもカリー化できる機構があれば楽ちんだ。&lt;br /&gt;JavaScriptには関数をカリー化する標準的な機構は用意されていないんだけど、カリー化する関数を作る事はできる。カリー化関数の実装にはいくつかバリエーションがあるんだけど、ここではわかりやすさを重視して &lt;a href="http://nanto.asablo.jp/blog/2005/12/13/176033"&gt;nanto_vi&lt;/a&gt; さんのカリー化関数を使わせていただくことにする。&lt;br /&gt;&lt;pre class="prettyprint"&gt;function curry(f) {&lt;br /&gt; if (f.length == 0) return f;&lt;br /&gt;   function iterate(args) {&lt;br /&gt;     if (args.length &gt;= f.length)&lt;br /&gt;       return f.apply(null, args);&lt;br /&gt;     return function () {&lt;br /&gt;       return iterate(args.concat(Array.prototype.slice.call(arguments)));&lt;br /&gt;     };&lt;br /&gt;   }&lt;br /&gt; return iterate([]);&lt;br /&gt;}&lt;/pre&gt;これを使えば、どんな関数でもカリー化できる。元ネタの例を拝借して、2引数の以下のような関数をカリー化してみる。&lt;br /&gt;&lt;pre class="prettyprint"&gt;function add(x, y) { return x + y }&lt;br /&gt;&lt;/pre&gt;curry関数を使って…&lt;br /&gt;&lt;pre class="prettyprint"&gt;var curried_add = curry(func(x, y))&lt;br /&gt;&lt;/pre&gt;これで、1引数関数になった。&lt;br /&gt;&lt;pre class="prettyprint"&gt;curried_add(1)(2)&lt;br /&gt;&gt; 3&lt;br /&gt;&lt;/pre&gt;OK。間にごちゃごちゃはさまるものの、関数は1引数だけ考えればよくなった。また1つ、世の中が単純になった。本当か？&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;&lt;br /&gt;ラムダで条件分岐&lt;/span&gt;&lt;br /&gt;じゃ、次は1引数関数で条件分岐ができるようにしてみる。これができれば、if文なんていう特別な構文を用意しなくても if文相当のプログラムが書けるわけで、世界は単純なまま進行する（JavaScriptで言うなら、if文を忘れ去ることができる）わけだ。よーし、じゃあif関数みたいなものを作るぞ！こんな風に動けばいいよね。&lt;br /&gt;&lt;pre class="prettyprint"&gt;myIf (b)(exp1)(exp2)&lt;br /&gt;&lt;/pre&gt;…しかしmyIfで全部やろうとすると…&lt;br /&gt;&lt;pre class="prettyprint"&gt;var myIf = curry(function (b, exp1, exp2) {&lt;br /&gt; return b ? exp1 : exp2&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;結局は内部に if文相当のもの（ここでは3項演算子だけど）が出てきてしまう。余分なものをそぎ落とすのが基本方針なので、やはりきしださんと同じアプローチを取る。&lt;br /&gt;関数はすべて1引数なので、if関数が条件として真偽値をとらなければならないなら、真偽値自体が実行する関数を選ばなくてはならない。とうわけで、真偽値を関数として定義する。ラムダ式で書くとこんな感じ。&lt;br /&gt;&lt;pre class="prettyprint"&gt;true=λx.λy.x&lt;br /&gt;false=λx.λy.y&lt;br /&gt;&lt;/pre&gt; trueは、xとyを順に適用すると、xを返す関数。falseは、xとyを順番に適用するとyを返す関数として定義している。JavaScriptで書くと、こんな風になる。&lt;br /&gt;&lt;pre class="prettyprint"&gt;var myTrue = curry(function(x, y) { return x })&lt;br /&gt;var myFalse = curry(function(x, y){ return y })&lt;br /&gt;// trueやfalseは予約語だから使えない&lt;br /&gt;&lt;/pre&gt;さて、条件分岐を書いてみよう。せっかくだから右の扉を…じゃなくて if っぽい関数を書いてみよう。全然型安全じゃないのがアレな感じだけど、とりあえず気にしない。&lt;br /&gt;&lt;pre class="prettyprint"&gt;var myIf = function(x) { return x }&lt;br /&gt;myIf(myFalse)(0)(1)&lt;br /&gt;&gt; 1&lt;br /&gt;&lt;/pre&gt;条件分岐できた。一応 (my)True も試しておく。条件分岐後に関数が実行されるようにもしてみる。&lt;br /&gt;&lt;pre class="prettyprint"&gt;myIf(myTrue)(curried_add(1, 2, 3))(10)&lt;br /&gt;&gt; 6&lt;br /&gt;&lt;/pre&gt;OK。なんかカッコだらけなんですけど…。言語はシンプルだけど、世の中はどんどん複雑になっていっている気も。&lt;br /&gt;&lt;br /&gt;さて、今のままだと、JavaScript の bool値はまったく使えない。ifを忘れ去るんだし、別になくても問題ない（というかなくしたい）んだけど、一応 JavaScript の bool と myTrue/myFalse/myIf をブリッジするための関数も用意してみる。&lt;br /&gt;&lt;pre class="prettyprint"&gt;var bool = function(b) { return b ? myTrue : myFalse }&lt;br /&gt;&lt;/pre&gt;myIf の JS boolean バージョン。&lt;br /&gt;&lt;pre class="prettyprint"&gt;myIf(bool(true))(curried_add(1, 2, 3))(10)&lt;br /&gt;&gt; 6&lt;br /&gt;&lt;/pre&gt;OK。振り返ってみると、真偽値自体を&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Trueの場合は1番目の式を評価する関数&lt;/li&gt;&lt;li&gt;Falseの場合は2番目の式を評価する関数&lt;/li&gt;&lt;/ul&gt;このように定義することで条件分岐を可能にする、というアイディアだったわけですね。たぶん。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;ラムダでループ&lt;/span&gt;&lt;br /&gt;やっと本題にきたよ！さて、世界をシンプルに保つために、今度は関数でループできるかやってみよう。関数だけでループするためには、再帰を使えば良いよね。&lt;br /&gt;フィボナッチを考えてみよう。とりあえずはプレーンなJavaScriptで。&lt;br /&gt;&lt;pre class="prettyprint"&gt;function fib(n) {&lt;br /&gt; if(n &lt; 2) { return n }&lt;br /&gt; else { return fib(n - 1) + fib(n - 2) }&lt;br /&gt;} &lt;/pre&gt;ここでは、fib関数の中で自分自身（fib）を呼び出す事で再帰を実現している。普通に関数で計算を表現するだけなら、別にこれで十分だと思う。myIfで書き直したいんだけど、自然数とか比較とか（+とかも）作ってないからとりあえずこのまま ^^;&lt;br /&gt;&lt;br /&gt;ただし、ラムダ計算の世界では自分自身を含む関数を定義することができない。せっかくなので、自分自身への呼び出しを取り除いて、ラムダ計算の体系に沿うように考えてみよう。&lt;br /&gt;&lt;br /&gt;自分自身を呼び出すように記述できないのなら、自分自身を表す関数を引数に取って、その関数を呼び出せばいいのでは？と一瞬思ったが、結局それ、自分自身を呼び出してるよな…。&lt;br /&gt;&lt;br /&gt;じゃあ、自分自身みたいだけど自分自身じゃない関数（fake_fibとでもしよう）が引数としてわたってきて、その関数を呼び出すことで間接的に自分自身が呼び出されるようにするのはどうだろう？JavaScriptで書くと、こんな感じ。&lt;br /&gt;&lt;pre class="prettyprint"&gt;function fib(fake_fib, n) {&lt;br /&gt; if (n &lt; 2) { return n }&lt;br /&gt;  else { return fake_fib(n - 1) + fake_fib(n - 2) }&lt;br /&gt;} &lt;/pre&gt;fake_fib(n - 1)呼び出しが、さらにfib(fake_fib, n - 1)を呼んでくれれば再帰が実現できることになるのでは？fibを g に、fake_fib を f にして簡潔に書きなおすと…&lt;br /&gt;&lt;pre class="prettyprint"&gt;function g(f, n) {&lt;br /&gt; if (n &lt; 2) { return n }&lt;br /&gt; else { return f(n - 1) + f(n - 2) }&lt;br /&gt;} &lt;/pre&gt;こんな感じ。で、f(n - 1) が g(f, n - 1) に（1引数の世界で言えば、f が g(f) に）展開されれば再帰が実現できるはず。というわけで、展開するとg(f)になるような f、つまり&lt;br /&gt;&lt;pre class="prettyprint"&gt;f = g(f)&lt;br /&gt;&lt;/pre&gt;となるような f を見つける、という問題に帰結する。このような条件を満たす f は一般的に「不動点」と呼ばれており、以下のようなラムダ式で表すことができることが知られている。&lt;br /&gt;&lt;pre class="prettyprint"&gt;Y = λg.(λx.g(xx))(λx.g(xx))&lt;br /&gt;&lt;/pre&gt;これがいわゆるYコンビネータってやつらしい。&lt;br /&gt;# このラムダ式がさきほどの条件を満たすことは、きしださんのところに書いてあるとおり、試してみればわかる。これをJavaScriptで書いてみると、&lt;br /&gt;&lt;pre class="prettyprint"&gt;function Y(f) {&lt;br /&gt; return function(x) {&lt;br /&gt;   return f(x(x))&lt;br /&gt; }(function (x) {&lt;br /&gt;   return f(x(x))&lt;br /&gt; });&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;# ナンダコレハ…。&lt;br /&gt;こうなる。これを使う形で、あらためてフィボナッチをJavaScriptでちゃんと書くと、こんな感じになる。&lt;br /&gt;&lt;pre class="prettyprint"&gt;var fib2 = curry(function(f, n){&lt;br /&gt; if(n &lt; 2) {return n }&lt;br /&gt; else {return f(n - 1) + f(n - 2)}&lt;br /&gt;}) &lt;/pre&gt;実際に呼び出すには、Yを使ってこんな感じで呼べばいい。&lt;br /&gt;&lt;pre class="prettyprint"&gt;Y(fib2)(10)&lt;br /&gt;&gt; InternalError: too much recursion&lt;br /&gt;&lt;/pre&gt;しかし、こちらも同じく再帰エラー。まねっこしてZコンビネータを作ってみよう。&lt;br /&gt;&lt;pre class="prettyprint"&gt;function Z(f) {&lt;br /&gt; return function(x) {&lt;br /&gt;   return function(m) {&lt;br /&gt;     return f(x(x))(m)&lt;br /&gt;   }&lt;br /&gt; }(function(x) {&lt;br /&gt;   return function(m) {&lt;br /&gt;     return f(x(x))(m)&lt;br /&gt;   }&lt;br /&gt; })&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;…なんかもう慣れてきた。呼び出し。&lt;br /&gt;&lt;pre class="prettyprint"&gt;Z(fib2)(10)&lt;br /&gt;&gt; 55&lt;br /&gt;&lt;/pre&gt;えええ！動いちゃったよ！そりゃ動くように作ったけどさ！&lt;br /&gt;&lt;br /&gt;で、これで何ができるかっていうと…自分自身を参照しなくても、再帰が書ける。だから、無名関数でも再帰が書ける。他にどんな良いことがあるかというと、相変わらずよくわからない ^^; ラムダ計算の体系に沿って計算を組み立てておくことで、何か良いことがあるのだろうか。&lt;br /&gt;&lt;br /&gt;チャーチ数とかもやってみようと思ったけど、力尽きた。続く…かもしれない。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-3334436773712706137?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/3334436773712706137/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=3334436773712706137&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/3334436773712706137'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/3334436773712706137'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2009/04/y.html' title='Yコンビネータにトライ'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-837041999223294274</id><published>2009-04-16T21:32:00.013+09:00</published><updated>2009-04-17T02:18:41.537+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='調べてみた'/><category scheme='http://www.blogger.com/atom/ns#' term='report'/><title type='text'>Google App Engineの料金体系が面白い</title><content type='html'>社内でGoogle App Engineのミニ勉強会をやることになったので、技術者らしくAPIとかBigTableまわりとかやろうかなーと思って色々ドキュメントをあさっていたところ、思いがけず非常に面白いものを見つけてしまった。&lt;br /&gt;&lt;br /&gt;それは、&lt;a href="http://code.google.com/intl/ja/appengine/docs/quotas.html"&gt;料金体系&lt;/a&gt;。たいていのGAE紹介サイトには、〜まで無料、以降〜みたいな形でさらっと書いてあるんだけど、思った以上に奥が深い。DoCoMoやソフトバンクモバイルより奥が深い。しかも、この料金体系によってアプリケーションの作り方にまで影響が出てくる可能性がある。こうなってくると、JPAとかJDOとか開発環境とか紹介するのなんて馬鹿馬鹿しくなってしまった。Google App Engine勉強会、って名目で人呼んどきながら、ずーっと料金の話ってありだろうか？なしだろうなぁ。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;基本的な概念、リソースとクォータ&lt;/span&gt;&lt;br /&gt;さて、Google App Engineには利用可能な資源、&lt;span style="font-weight: bold;"&gt;リソース&lt;/span&gt;が定義されており、リソースには&lt;span style="font-weight: bold;"&gt;クォータ&lt;/span&gt;（割当）が設定されている。逆に言えば、クォータが設定されているものがリソースであるとも言える。リソースには2種類存在し、固定的に割り当てられていて基本的にはクォータの上限が変更できないもの（&lt;span style="font-weight: bold;"&gt;Fixed&lt;/span&gt;）と、支払いによって上限を増やせるもの（&lt;span style="font-weight: bold;"&gt;Billable&lt;/span&gt;）がある。&lt;br /&gt;ややこしいことに、Fixedのリソースのクォータは、Account保持者が支払い可能状態になると上限が増える（一方Billableなリソースのクォータは、実際に上限を増やすように設定しないと増えない）。&lt;br /&gt;&lt;br /&gt;また、クォータにも2種類あり、日ごとの上限値と、分ごとの上限値が設定できる。分ごとの上限値は、日ごとに割り当てられたリソースが急速に消費されつくし、日のうち大部分が稼働不可能になる...といった状況を避けるために設定できるようになっている。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;リソースの枯渇と補充&lt;/span&gt;&lt;br /&gt;リソースは、クォータの上限値から消費されていき、Pacific Timeの0時にリセットされてクォータの最大値まで補充される。&lt;br /&gt;リソースが枯渇した状態で枯渇したリソースにアクセスしようとした際には、例外が発生する。リソース枯渇に適切に対応しようとする場合、適切にこの例外をハンドリングしなければならない。たとえば、ユーザーにそのサービスが利用不可能であることを通知したり、管理者にメールで通知する等の事後処理が考えられるだろう。これが、アプリケーション設計に影響を与える要素の1つである。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;リソースの種類&lt;/span&gt;&lt;br /&gt;以下でリソースを紹介するが、支払いによって上限を増やせるものは、オリジナルのドキュメントに従って[B(illable)]と表記する。また、参考のために、無料かつ支払い可能でない状態での日ごとの上限値を並記する。&lt;br /&gt;&lt;br /&gt;■ リクエスト系&lt;br /&gt;&lt;ul&gt;&lt;li&gt;リクエスト数（HTTPSを含む）: 1,300,000 requests&lt;br /&gt;&lt;/li&gt;&lt;li&gt;出力帯域総数[B]（HTTPSを含む）: 10 gigabytes&lt;br /&gt;&lt;/li&gt;&lt;li&gt;入力帯域総数[B]（HTTPSを含む）: 10 gigabytes&lt;br /&gt;&lt;/li&gt;&lt;li&gt;CPU時間[B] : 46 CPU-hours&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt; CPU時間はデータストアで使った時間も含む。外部サービス呼び出し等による待機時間は含まない。また、CPU消費時間の目安として、以下のようなものがあげられている。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;データストアへの書き込みは、読み込みに比べておよそ5倍のCPU時間を使う&lt;/li&gt;&lt;li&gt;インデックス更新が必要な書き込みは、そうでないものよりCPU時間を使う&lt;/li&gt;&lt;li&gt;Entityのプロパティが多いほど、読み込みでも書き込みでもCPU時間を使う&lt;/li&gt;&lt;li&gt;Queryは常にIndexを使うため、Queryはほとんどの場合に同じくらいのCPUしか使わない&lt;/li&gt;&lt;li&gt;ただし、フェッチが必要な場合は追加のCPU時間が必要になる&lt;/li&gt;&lt;/ul&gt;リクエスト系のリソースの特筆すべき点は、これらのリソースが不足した場合にはリクエストのハンドリングを開始すらできないため、ユーザーにはHTTP Status403が返されてしまう、という点だ。&lt;br /&gt;&lt;br /&gt;■ データストア系&lt;br /&gt;&lt;ul&gt;&lt;li&gt;データストアAPI呼び出し回数 : 10,000,000 calls&lt;br /&gt;&lt;/li&gt;&lt;li&gt;格納データおよび関連インデックスのサイズ[B] : 1 gigabyte&lt;br /&gt;&lt;/li&gt;&lt;li&gt;APIに送信されたデータのサイズ : 12 gigabytes&lt;br /&gt;&lt;/li&gt;&lt;li&gt;APIから取得したデータのサイズ : 115 gigabytes&lt;br /&gt;&lt;/li&gt;&lt;li&gt;データストアに使ったCPU時間 : 60 CPU-hours&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;■ メール系&lt;br /&gt;&lt;ul&gt;&lt;li&gt;メールAPI呼び出し回数 : 7,000 calls&lt;br /&gt;&lt;/li&gt;&lt;li&gt;メール送信先アドレスの総数[B] : 2,000 recipients&lt;br /&gt;&lt;/li&gt;&lt;li&gt;送信メール総数 : 5,000 mails&lt;br /&gt;&lt;/li&gt;&lt;li&gt;メッセージボディのデータサイズ総数 : 60 megabytes&lt;br /&gt;&lt;/li&gt;&lt;li&gt;送信添付ファイル総数 : 2,000 attachments&lt;br /&gt;&lt;/li&gt;&lt;li&gt;送信添付ファイルデータサイズ総数 : 100 megabytes&lt;/li&gt;&lt;/ul&gt;■ URLフェッチ系&lt;br /&gt;&lt;ul&gt;&lt;li&gt;URLフェッチAPI呼び出し回数 : 657,000 calls&lt;br /&gt;&lt;/li&gt;&lt;li&gt;URLフェッチデータ送信サイズ総数 : 4 gigabytes&lt;br /&gt;&lt;/li&gt;&lt;li&gt;URLフェッチデータ受信サイズ総数 : 4 gigabytes&lt;/li&gt;&lt;/ul&gt;■ Image操作系&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Image操作API呼び出し回数 : 864,000 calls&lt;br /&gt;&lt;/li&gt;&lt;li&gt;APIへのデータ送信サイズ総数 : 1 gigabytes&lt;br /&gt;&lt;/li&gt;&lt;li&gt;APIからのデータ受信サイズ総数 : 5 gigabytes&lt;br /&gt;&lt;/li&gt;&lt;li&gt;変換実行回数 : 2,5000,000 transforms&lt;/li&gt;&lt;/ul&gt;■ Memcache系&lt;br /&gt;&lt;ul&gt;&lt;li&gt;MemcacheAPI呼び出し回数 : 8,600,000 calls&lt;br /&gt;&lt;/li&gt;&lt;li&gt;APIへのデータ送信サイズ総数 : 10 gigabytes&lt;br /&gt;&lt;/li&gt;&lt;li&gt;APIからのデータ受信サイズ総数 : 50 gigabytes&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;■ デプロイ&lt;br /&gt;&lt;ul&gt;&lt;li&gt;デプロイ回数 : 未定義&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;リソース[B]の単位あたりコスト&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;出力帯域総数：1 gigabytes あたり 約12円&lt;/li&gt;&lt;li&gt;入力帯域総数：1 gigabytes あたり 約10円&lt;/li&gt;&lt;li&gt;CPU時間：1 CPU時間 あたり 約10円&lt;/li&gt;&lt;li&gt;格納データサイズ：1ヶ月あたり1 gigabytesで約15円&lt;/li&gt;&lt;li&gt;メール送信先アドレスの総数：1アドレスあたり約0.01円&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;安…！いよね？&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;アプリケーション開発への影響&lt;/span&gt;&lt;br /&gt;こんな感じで、明確に上限回数やリソース追加のコストが明示されたら、アプリケーション開発にはどんな影響があるだろう？まず、テストが変わるんじゃないだろうか。従来も行われてきたであろう、リソースの上限を突破しないか、という観点での試験に加えて、費用対効果を考慮した試験がより厳密に行われるようになる可能性がある。なにせ、無駄にCPUリソースを消費した処理を作ると、明確に費用として跳ね返ってくるようになるのだ。そうなると、富豪プログラミングにかわり、効率の良いアルゴリズムが再び脚光を浴びるようになるかもしれない。つまり、（今後の料金変動や景気、規模にもよりそうだが）今よりも省エネな設計が求められるようになる可能性があるんじゃなかろーか。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;その他雑感&lt;/span&gt;&lt;br /&gt;こうして、使用リソースに応じた料金表を見ていると、携帯電話料金表や電気料金表を見ながら最安のプランを考えているときと同じ感覚をおぼえて「あぁ、本当にユーティリティコンピューティングの時代が来たんだなぁ」と思いがけず実感してしまう。&lt;br /&gt;と同時に、CPU消費時間で費用が変わるような世界は、よくよく考えると、本や口伝えでしか見聞きしたことがないような、コンピューターリソースが貴重だった時代に似ているような気もしてくる。マシン使用時間に応じて料金がかかっていたらしい、自分の知らない時代。&lt;br /&gt;トレンドは螺旋を描いて戻ってくるとはよく言ったものだ。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-837041999223294274?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/837041999223294274/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=837041999223294274&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/837041999223294274'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/837041999223294274'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2009/04/google-app-engine.html' title='Google App Engineの料金体系が面白い'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-9222955641444318881</id><published>2009-04-15T00:12:00.007+09:00</published><updated>2009-04-17T02:18:41.538+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='調べてみた'/><title type='text'>GAE/Jにいまいち惹かれない</title><content type='html'>QConでの&lt;a href="http://hibituredure.blogspot.com/2009/04/programming-cloud-internet-as-platform.html"&gt;Gregorのセッション&lt;/a&gt;を受けて、Google App Engine熱が再度高まってきた。ってわけでGAE for Javaをさわってみたのだが、イマイチぐっと来ない。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Webインフラが素のServletまで退行。&lt;/li&gt;&lt;li&gt;Webフレームワークが手探り状態。もう少ししたら一通りそろってくると思うけど。&lt;/li&gt;&lt;li&gt;久しぶりにさわったJavaが、予想以上に柔軟性がなくて萎えた。&lt;/li&gt;&lt;li&gt;現状AOPも使えないんじゃあ、のっぺり感満載…。Moduleとかtraitとかないんすか。&lt;br /&gt;&lt;/li&gt;&lt;li&gt;GAE/Jの永続化メカニズム（JDO/JPA）がどっちもいまいち好きになれない。&lt;/li&gt;&lt;li&gt;Scala使おうかと思ったけど、JDO/JPAのエンハンスとか考えると開発環境を快適にするのがめんどくさそうで萎えた。Actorは当然使えない。&lt;/li&gt;&lt;li&gt;JDO/JPAみたいな形だと、BigTableの柔軟性（行ごとに違うデータ項目を持っていてもOK）が生きてこない気がした。&lt;/li&gt;&lt;/ul&gt;てな感じ。これなら、（少なくともしばらくは）Python版でよくないか？てかPython版のがよくないか？お下がりとして頂いた「初めてのPython（第2版）」をぱらぱら読んでると、関数系が結構充実してる（lambda式とかリスト内包表記とかジェネレータとか）みたいで、使ってて面白そうだし。でも、なんか世の中に取り残されているみたいで寂しい。もしかしてSIer社員失格か？&lt;br /&gt;&lt;br /&gt;しばらくはPythonでGAE使っていこうかな。世の中が落ち着いてきたらJavaも使ってみればいいし。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-9222955641444318881?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/9222955641444318881/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=9222955641444318881&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/9222955641444318881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/9222955641444318881'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2009/04/gaej.html' title='GAE/Jにいまいち惹かれない'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-6779017911646913088</id><published>2009-04-14T23:20:00.003+09:00</published><updated>2009-04-17T00:28:29.859+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><title type='text'>JavaScript: The Good Parts</title><content type='html'>今更だけど見てみた。&lt;br /&gt;&lt;br /&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/hQVTIJBZook&amp;amp;hl=en&amp;amp;fs=1"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/hQVTIJBZook&amp;amp;hl=en&amp;amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="344" width="425"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;1時間以上あるのに軽く引くが、本当に重要なのは30分程度。残りはこの人の経験談や、JavaScript界隈の近況、質疑応答。&lt;br /&gt;この人のプレゼンは、皮肉がきいていて面白い。とりあえず、わかった範囲でメモっておく。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;JavaScriptの現状&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;いまだに最も誤解された言語&lt;/li&gt;&lt;li&gt;誤用しては怒っている人多し&lt;/li&gt;&lt;li&gt;最もすばらしいアイデアから、もっともひどいアイデアまで含まれている&lt;/li&gt;&lt;li&gt;こんなに幅の広い言語はほかにない&lt;/li&gt;&lt;li&gt;コンピュータ科学者からカット＆ペースト厨まで、どの言語よりも幅広いスキルの人が使っている&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;JavaScriptへの不満&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;ブラウザプログラミングはひどいもんだ。 =&gt; まったくその通り&lt;br /&gt;&lt;/li&gt;&lt;li&gt;十分な速度が出ない。 =&gt; 現在ではすでにJSではなくDOMの問題。今はランタイムは十分速い。&lt;/li&gt;&lt;li&gt;失敗の積み重ねだ。 =&gt; Javaが完全に失敗した環境でうまくやりつづけているだろ？&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;影響を受けた言語&lt;/span&gt;&lt;br /&gt;Self：&lt;br /&gt;&lt;ul&gt;&lt;li&gt;prototypal inheritance&lt;/li&gt;&lt;li&gt;dynamic objects&lt;/li&gt;&lt;/ul&gt;Java：&lt;br /&gt;&lt;ul&gt;&lt;li&gt;syntax&lt;/li&gt;&lt;li&gt;conventions&lt;/li&gt;&lt;/ul&gt;Scheme：&lt;br /&gt;&lt;ul&gt;&lt;li&gt;lambda&lt;/li&gt;&lt;li&gt;loose typing&lt;/li&gt;&lt;/ul&gt;Perl：&lt;br /&gt;&lt;ul&gt;&lt;li&gt;regular expressions&lt;/li&gt;&lt;/ul&gt;Schemeさんパネェッス。&lt;br /&gt;loose typingを問題視する人もいるが、テストすればよい。テストは他の言語でも必要　型チェックだけじゃわからないことは多い。Javaのシンタックスはあんまよくないね。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Bad Parts&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;グローバル変数。&lt;/li&gt;&lt;li&gt;+ をaddと結合に使う。Javaもやってるが、Javaは強い型つけを持ってるから問題ない。&lt;/li&gt;&lt;li&gt;セミコロン。初心者向けにCのシンタックスを導入したが、予期しないエラーがおきたりする。後述。&lt;/li&gt;&lt;li&gt;typeof。役に立たない。なんでもObjectになってしまう。&lt;/li&gt;&lt;li&gt;with と eval。evalは一番誤用されている。evalを使ってるときは、なんかまずいことをやってる。&lt;/li&gt;&lt;li&gt;まがいものの配列。本来はメモリを区切ってすばやくアクセスできるが、JSのはこういうのじゃない。実際はハッシュテーブル。&lt;/li&gt;&lt;li&gt;== と !=。Cから受け継いだ問題の多いシンタックス。&lt;/li&gt;&lt;li&gt;false, null, undefined, NaN。たくさんありすぎ。&lt;/li&gt;&lt;/ul&gt;どうなるかわかるだろうか？&lt;br /&gt;&lt;pre class="prettyprint"&gt;'' == '0' // false&lt;br /&gt;0 == '' // true&lt;br /&gt;0 == '0' // true&lt;br /&gt;false == 'false' // false&lt;br /&gt;false == '0' // true&lt;br /&gt;false == undefined // false&lt;br /&gt;false == null // false&lt;br /&gt;null == undefined // true&lt;br /&gt;"¥t¥r¥n" == 0 // true&lt;br /&gt;&lt;/pre&gt;常に ===を使うべき。==は（暗黙の型変換がカオスすぎるので）使ってはいけない。本当は間違いだけど、偶然うまくいくケースもある。&lt;br /&gt;&lt;pre class="prettyprint"&gt;// 間違い&lt;br /&gt;var obj = myObject[name]&lt;br /&gt;if (obj == null) {&lt;br /&gt;....&lt;br /&gt;&lt;br /&gt;// 正解&lt;br /&gt;var obj = myObject[name]&lt;br /&gt;if (obj == undefined) {&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;単独では良い機能が、関連するとがうまく動かないケース&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Objectは他のオブジェクトを継承できる&lt;/li&gt;&lt;li&gt;関数はオブジェクトのメンバになれる&lt;/li&gt;&lt;li&gt;for..in文は、継承した関数とデータメンバを区別しない&lt;/li&gt;&lt;/ul&gt;=&gt; 全然嬉しくない挙動&lt;br /&gt;&lt;br /&gt;実際、for .. in は問題が多い&lt;br /&gt;// 浅いとか深いとか、よくわかんなかった&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Bad Heritage&lt;/span&gt;&lt;br /&gt;ブロックのないステートメント：&lt;br /&gt;&lt;pre class="prettyprint"&gt;if (foo)&lt;br /&gt;bar();&lt;br /&gt;&lt;/pre&gt;expression statement：&lt;br /&gt;&lt;pre class="prettyprint"&gt;  foo;&lt;br /&gt;&lt;/pre&gt;Floating point arithmetic：&lt;br /&gt;&lt;pre class="prettyprint"&gt;  0.1 + 0.2 !== 0.3&lt;br /&gt;// JSの問題というわけではないんだが&lt;br /&gt;&lt;/pre&gt;++ and --：&lt;br /&gt;バッファオーバーランとか色々問題があるらしい。コードもトリッキーになる。&lt;br /&gt;&lt;br /&gt;switch：&lt;br /&gt;Javaと同じ問題。falling through&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Good Parts&lt;/span&gt;&lt;br /&gt;Lambda：&lt;br /&gt;パワフルで安全&lt;br /&gt;&lt;br /&gt;Dynamic Objects：&lt;br /&gt;非常にパワフルで使いやすい&lt;br /&gt;&lt;br /&gt;Loose Typing：&lt;br /&gt;良い。クラスとかいらない。&lt;br /&gt;&lt;br /&gt;Object Literals：&lt;br /&gt;とてもよい。JSONとか。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Inheritance&lt;/span&gt;&lt;br /&gt;コードの再利用。クラスベースとプロトタイプベースがある。&lt;br /&gt;よく理解されていないが、プロトタイプベースはとてもパワフル。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Prototype Inheritance&lt;/span&gt;&lt;br /&gt;Classは不要、オブジェクトから継承。&lt;br /&gt;他のオブジェクトへのリンクを持ち、委譲する方法がある。&lt;br /&gt;&lt;pre class="prettyprint"&gt;var newObject = Object.create(oldObject);&lt;br /&gt;&lt;br /&gt;if (typeof Object.create !== 'function') {&lt;br /&gt; Object.create = function(o) {&lt;br /&gt;   function F() {}&lt;br /&gt;   F.prototype = o;&lt;br /&gt;   return new F();&lt;br /&gt; };&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;new はクラスベースっぽい記法を提供しているが、あまりよろしくない。コンストラクタ関数を呼ぶときにはnewが必要だが、忘れるとグローバルオブジェクトが変更されてしまう。そして、その際にはまったく警告が出ない。私は危険だから使わない。&lt;br /&gt;&lt;br /&gt;Global変数いくない&lt;br /&gt;&lt;pre class="prettyprint"&gt;var names = ['one', 'two'....]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;functionでスコープ制限したらどうだろう？&lt;br /&gt;&lt;pre class="prettyprint"&gt;function hoge(n) {&lt;br /&gt; var names = ['one', 'two'...]&lt;br /&gt; return names[n]&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;=&gt; 遅い。呼び出しごとに配列が初期化されてしまう。&lt;br /&gt;&lt;br /&gt;クロージャを使おう！&lt;br /&gt;&lt;pre class="prettyprint"&gt;var digit_name = function() {&lt;br /&gt; var names = [...]&lt;br /&gt;&lt;br /&gt; return function(n) {&lt;br /&gt;   return names[n]&lt;br /&gt; };&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;=&gt; 無名関数のスコープ内で一度だけ初期化される。遅くない。これは、コンストラクタパターンとして一般化できる。といいつつ、次のスライドがModule Patternなのはなぜだ。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Module Pattern&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;var singleton = function() {&lt;br /&gt; // 無名functionのスコープにとじこめられる&lt;br /&gt; var privateVariable;&lt;br /&gt; function privateFunction(x) {&lt;br /&gt;   ..privateVariable...&lt;br /&gt; }&lt;br /&gt; // Objectリテラルで無名関数のスコープを使うように定義&lt;br /&gt; return {&lt;br /&gt;   firstMethod: function (a, b) {&lt;br /&gt;     ...privateVariable...&lt;br /&gt;   },&lt;br /&gt;   secondMethod: function(c) {&lt;br /&gt;     ...privateFunction()....&lt;br /&gt;   }&lt;br /&gt; };&lt;br /&gt;}();&lt;br /&gt;&lt;/pre&gt;これは、（ようやく）コンストラクタに応用できる。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Power Constructor&lt;/span&gt;&lt;br /&gt;1. Make an object.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;  Object literal&lt;/li&gt;&lt;li&gt;  new&lt;/li&gt;&lt;li&gt;  Object.create&lt;/li&gt;&lt;li&gt;  call another power constructor&lt;/li&gt;&lt;/ul&gt;2. Define some variables and functions&lt;br /&gt;これがプライベートメンバになる&lt;br /&gt;3. 特権メソッドでobjectを複製する&lt;br /&gt;4. 作ったobjectをかえす&lt;br /&gt;&lt;br /&gt;コードで見てみると...&lt;br /&gt;&lt;pre class="prettyprint"&gt;function myPowerConstructor(x) {&lt;br /&gt; var that = otherMaker(x);&lt;br /&gt; var secret = f(x);&lt;br /&gt; that.priv = function() {&lt;br /&gt;   .... secret x that ....&lt;br /&gt; };&lt;br /&gt; return that;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;コーディングスタイル&lt;/span&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;return {&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;と&lt;br /&gt;&lt;pre class="prettyprint"&gt;return&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;どちらがいいか？これは、感情的な宗教論争ではない。少なくともJSに関しては。&lt;br /&gt;&lt;pre class="prettyprint"&gt;return&lt;br /&gt;{&lt;br /&gt; ok: false&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;このように書いた場合、何も返らない。これは、returnの後ろに暗黙的にセミコロンが挿入されるから。&lt;br /&gt;&lt;pre class="prettyprint"&gt;return;&lt;br /&gt;{&lt;br /&gt; ok: false&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;JavaScriptにはブロックスコープない。&lt;br /&gt;&lt;pre class="prettyprint"&gt;ok: false&lt;br /&gt;&lt;/pre&gt;はラベルだとみなされる。&lt;br /&gt;&lt;pre class="prettyprint"&gt;return;&lt;br /&gt;{&lt;br /&gt; ok: false;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;こうなるということ。どのみち、return以降は到達しない文。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;ビューティフルコード&lt;/span&gt;&lt;br /&gt;JSLint使いなさい。Bad Partsを避けるように強制してくれる。注意しておくが、これを最初に使うと凹むことは請け合い。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;他の良い点&lt;/span&gt;&lt;br /&gt;安定してるぜ！1999からデザインがかわってないのだ。&lt;br /&gt;&lt;br /&gt;標準化動向とか質疑応答とか省略。あー…うん。1度Youtubeの動画を貼ってみたかっただけなんだ…。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-6779017911646913088?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/6779017911646913088/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=6779017911646913088&amp;isPopup=true' title='5 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/6779017911646913088'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/6779017911646913088'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2009/04/javascript-good-parts_14.html' title='JavaScript: The Good Parts'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-8304986303323641324</id><published>2009-04-13T14:07:00.011+09:00</published><updated>2009-04-13T16:53:39.973+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='セミナー/勉強会'/><category scheme='http://www.blogger.com/atom/ns#' term='report'/><title type='text'>大規模ウェブサイトのベストプラクティス －eBayでの事例－</title><content type='html'>&lt;div&gt;分量がめちゃめちゃ多かったので、あまりメモってない ^^;&lt;/div&gt;&lt;div&gt;ほとんど「大規模サイト構築のノウハウ全部見せます！－全部で20以上あるよ！－」みたいなノリだったので、とても全部メモることはできなかった。プレゼン資料欲しいです。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;eBayシステムのプロファイル概略&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;トランザクションデータは2ペタバイト&lt;/li&gt;&lt;li&gt;DWH用データは50ペタバイト&lt;/li&gt;&lt;li&gt;1日あたり48億回のSQL実行&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;ペタバイトとか、もう多いか少ないかもわからん。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;大規模システムの原則&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;ということで、eBayのシステム構築の原則。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Partition Everything&lt;/li&gt;&lt;li&gt;Asynchrony Everywhere&lt;/li&gt;&lt;li&gt;Automate Everything&lt;/li&gt;&lt;li&gt;Remember Everything Fails&lt;/li&gt;&lt;li&gt;Embrace Inconsistency&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;なんだか清々しいです。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Partition Everything&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;分割方法は、データ、負荷、使用方法の特徴など、色々なものがあげられる。分割の動機としては…&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Scalability&lt;/li&gt;&lt;li&gt;Availability&lt;/li&gt;&lt;li&gt;Manageability&lt;/li&gt;&lt;li&gt;Cost&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;このような感じ。PartitionとAvailabilityとは、Partitionによって故障箇所を局所化することでAvailabilityを向上できる、という点で関連する。PartitionとCostとは、Partitionによって問題を細分化することで、price/performance比がベストの点を選択できるようになる、という点で関連する。特に、Availabilityを重視している印象を受けた。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;eBayでは、いくつかの方法でシステムを分割している。&lt;/div&gt;&lt;div&gt;■機能による分割（処理）&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Selling&lt;/li&gt;&lt;li&gt;Search&lt;/li&gt;&lt;li&gt;ViewItem&lt;/li&gt;&lt;li&gt;Bidding&lt;/li&gt;&lt;li&gt;Checkout&lt;/li&gt;&lt;li&gt;Feedback&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;■機能による分割（データ）&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;User&lt;/li&gt;&lt;li&gt;Item&lt;/li&gt;&lt;li&gt;Transaction&lt;/li&gt;&lt;li&gt;Product&lt;/li&gt;&lt;li&gt;Account&lt;/li&gt;&lt;li&gt;Feedback&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;■水平的な分割&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;ノード分割＋ロードバランシング&lt;/li&gt;&lt;li&gt;データをアクセスパスにしたがって分割（RDBのパーティションのことだと思う）&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;また、Partitionのため、セッションステートはアプリケーションティアに保持しないようにしている。CookieやURL、DBに持っているらしい。この辺は王道。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Asynchrony Everything&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;非同期化のメリットは…&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;ピークロード（最大負荷）ではなくアベレージロード（平均負荷）をターゲットにリソースを配分することができる点&lt;br /&gt;&lt;/li&gt;&lt;li&gt;ユーザーが許容可能な時間を越えて、リクエストを処理することができる点&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;# 他にもいくつかメリットがあったけど、個人的に重要だと思ったのだけなんとかメモ ^^;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;非同期化の方法には、キューイングやマルチキャストメッセージがある。&lt;/div&gt;&lt;div&gt;eBayで採用しているキューでは順序性は保証していないが、メッセージ自体にはデータは入れず、イベント通知を受けた側がその時点で正しいデータを読みに行く（Read Back）ことで整合性の取れた処理を行えるようにしているらしい。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;マルチキャストメッセージは、商品情報などのデータがアップデートされた際に、サーチエンジンのインデックス更新を通知する場合などに使われている。Feed Daemonというプロセスが定期的にデータ更新をポーリングしており、更新があった場合（eBayの場合、ほぼ確実にあると思うが）に各サーチエンジンにマルチキャストメッセージを送信する、という形を取っている。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Automate Everything&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;興味深い例として、ユーザーの振る舞い（サイト上でどのように行動したか）情報を収集し、それに応じてシステムを最適化する、という一連のアクティビティを自動化している例が紹介された。&lt;/div&gt;&lt;div&gt;収集したデータをもとにメタデータを更新し、システムがその振る舞いを変えるところまで自動化されているのが面白い。データ収集や、分析のネタ作りの自動化くらいまでは結構やってると思うんだけど、ここまでやっているのは珍しい。いいアイデアのヒントをもらった。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Remember Everyghint Fails&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;システム上のすべての変更は、すべてもとに戻せるようにしているらしい。これは、データだけではなく、システム機能に対する変更にもあてはまるようで、すべての機能はコンフィグでON/OFFが切り替えられるそうだ。データ更新に対するロールバックをどう扱っているかに興味があるが、それは次の「Embrace Inconsistency」で扱われるトピックなのだろう。&lt;/div&gt;&lt;div&gt;また、Graceful Degrationも可能らしい。まぁ、このレベルだとある意味当たり前と言える。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Embrace Inconsistency&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;ここで、満を持して（？）&lt;a href="http://hibituredure.blogspot.com/2009/04/cap-theorem.html"&gt;CAP Theorem&lt;/a&gt;が登場。このセミナーで3回目。はじめて、CAPの正確な定義がスライド上に登場する。が、はやすぎてメモれず ;-(&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;C : all clients see the same data even if system ...&lt;/li&gt;&lt;li&gt;A : all clients will get a response even if system failure exist...&lt;/li&gt;&lt;li&gt;P : 時間切れ ;-(&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;# おそらく、&lt;a href="http://camelcase.blogspot.com/2007/08/cap-theorem.html"&gt;AmazonのCAPの定義&lt;/a&gt;と大差ないはず。でも、誰か知ってたら教えてください… ;-(&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;さて、ここでの基本的な主張は、もうおなじみ「Consistencyは"あり"か"なし"かの2者択一ではなく、Immediate ConsistencyとNo Consistencyの間に多数のConsistencyレベルがスペクトラムのように存在する」というもの。&lt;/div&gt;&lt;div&gt;-----------------------------------------------------------&lt;/div&gt;&lt;div&gt;   Immediate &lt;------- Eventually -------&gt; No Consistency&lt;/div&gt;&lt;div&gt; Bids/Purchase         Search Engine/            Preferences&lt;/div&gt;&lt;div&gt;                              Billing System&lt;/div&gt;&lt;div&gt;-----------------------------------------------------------&lt;br /&gt;&lt;/div&gt;&lt;div&gt;金融システムにおいてすら、必ずしもImmediate Consistencyが必要とは限らない。ちなみに、eBayでは分散トランザクションはまったく使っていない（これが噂の&lt;a href="http://martinfowler.com/bliki/Transactionless.html"&gt;Transactionless&lt;/a&gt;か）。そのかわり、DB操作の順序を厳密に決定することで、システム全体の整合性を高めている。&lt;/div&gt;&lt;div&gt;# ステートマシンを使っている、という発言もあったけど、分析に使っているんだろうか？&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;最後にもう一度、重要なことを繰り返す。&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Partition Everything&lt;/li&gt;&lt;li&gt;Asynchrony Everywhere&lt;/li&gt;&lt;li&gt;Automate Everything&lt;/li&gt;&lt;li&gt;Remember Everything Fails&lt;/li&gt;&lt;li&gt;Embrace Inconsistency&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;清々しいですね。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;雑感&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;このセミナーで一番中身が濃かったのではないだろうか。大規模システム構築のパターンとして、本が一冊出せそうなくらいの内容だった。それだけにメモも難しく、セミナー資料の公開が待たれるところだ。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;目次：&lt;br /&gt;&lt;a href="http://hibituredure.blogspot.com/2009/04/qcon-tokyo-2009.html"&gt;QCon Tokyo 2009に行ってきた&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-8304986303323641324?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/8304986303323641324/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=8304986303323641324&amp;isPopup=true' title='2 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/8304986303323641324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/8304986303323641324'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2009/04/ebay.html' title='大規模ウェブサイトのベストプラクティス －eBayでの事例－'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-614763974575255839</id><published>2009-04-13T13:20:00.007+09:00</published><updated>2009-04-13T15:43:47.698+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='セミナー/勉強会'/><category scheme='http://www.blogger.com/atom/ns#' term='report'/><title type='text'>ビューティフルコード</title><content type='html'>Matzのビューティフルコード。講演内容は、少し前に開催された「まつもとゆきひろが語る『ビューティフルコード』×『プログラマ35歳定年説』」と同じだと思われる。&lt;div&gt;というわけで、包括的な内容は以下を見ればとてもよく書いてあるとオモイマス。&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://d.hatena.ne.jp/LukeSilvia/20090207"&gt;まつもとゆきひろが語る「ビューティフルコード」セミナーにいってきた&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://d.hatena.ne.jp/siroi_mogutan/20090207"&gt;まつもとゆきひろが語る「ビューティフルコード」×「プログラマ35歳定年説」&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://d.hatena.ne.jp/TrinityT/20090207/1233997847"&gt;まつもとゆきひろが語る「ビューティフルコード」×「プログラマ35歳定年説」聴講記&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;雑感&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;全体的には、教科書的な内容を集めた話になっているなぁ、という印象。以下のような話はなかなか興味深かった。&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Brooksの生産性不変の法則（どんな言語でも、プログラマが生産できる単位時間あたりLOCは変わらない）から考えても、表現力の高い言語が求められている、ということ。&lt;/li&gt;&lt;li&gt;コードはアート、プログラマはアーティストとしての自覚を持つべき。アーティストの条件とは、自覚、自発である。&lt;/li&gt;&lt;li&gt;アートはビジネスとして成立しないという意見があるが、デザイナなど、アートとビジネスを両立させている職業はいくらでもある。&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;一方、疑問点も多数。&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;ソフトウェアは一品モノだし、プログラミングは設計なので、ソフトウェア工場というアイデアは間違っている、という話があったが、ソフトウェアの性質は一品モノか大量生産かの2択ではなく、この間の多様な中間点も取りうるはず。自分の経験上、大量生産に比較的近いようなソフトウェア開発も確かに存在するし、プログラミングが設計（＝コードが設計書）だとしても、設計書同士が似通っている場合にはより効率的なアプローチがあり得るだろう。設計書同士の類似点が大きければ大きいほど、工場のメタファが有効になるかもしれない。ソフトウェアの種類を限定せずにこのような主張を行うのは、ポジショントークにしてもやりすぎであるように思える。&lt;/li&gt;&lt;li&gt;プログラミング言語は水鳥のようであるべきで、現実の複雑さは言語が引き受ければいい、という話があったが、現実の複雑さの多くは汎用言語では引き受けられないのではないか？複雑な現実を分類し、それぞれの分類に特化した言語を作ることで複雑さに対応する、というアプローチ（つまりDSL）が主流になりつつある。個人的には、現実の複雑さに対応するために汎用言語が目指す方向は、言語が複雑さを引き受ける方向ではなく、言語の表現力を増す（＝複雑な現実を表現できる可能性を増やす）方向が良いのではないかと思う。まんま内部DSLのホスト言語のイメージだけど ^^;&lt;/li&gt;&lt;li&gt;Rubyは（動的型付けやクロージャ、オープンクラスやメタクラス、Mix-Inなどによって）かなり表現力が高い。これが、内部DSLのホストとして好まれる大きな理由の1つじゃないかと思う。&lt;/li&gt;&lt;li&gt;アルゴリズム記述用擬似言語みたいなものを目指す、と言っていたけど、それはアルゴリズムに特化しているだけで、アルゴリズムは書きやすくなるかもしれないけど他の部分に影響が出る可能性があるのでは？&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;自分のような言語のシロウトがMatzに疑問を持つのもアレなんですが、このあたりの疑問は解消されないまま今に至る。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;目次：&lt;br /&gt;&lt;a href="http://hibituredure.blogspot.com/2009/04/qcon-tokyo-2009.html"&gt;QCon Tokyo 2009に行ってきた&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-614763974575255839?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/614763974575255839/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=614763974575255839&amp;isPopup=true' title='3 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/614763974575255839'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/614763974575255839'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2009/04/blog-post_13.html' title='ビューティフルコード'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-2906380051782635306</id><published>2009-04-13T01:20:00.008+09:00</published><updated>2009-04-13T15:43:47.698+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='セミナー/勉強会'/><category scheme='http://www.blogger.com/atom/ns#' term='report'/><title type='text'>Programming the Cloud -the Internet as Platform-</title><content type='html'>イケメンGregor Horhpeによるクラウドセッション。この人は、Martin Fowler SignitureのEnterprise Integration Patternsの著者の一人でもある。今回はEIPではなく、BASE〜CAP Theorem〜Google App Engineといったあたりのお話。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;"&gt;クラウドの良い点、悪い点&lt;/span&gt;&lt;br /&gt;アーキテクト（の関心事）にとっては、夢を実現するコンセプト。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;疎結合&lt;/li&gt;&lt;li&gt;拡張性&lt;/li&gt;&lt;li&gt;標準への準拠&lt;/li&gt;&lt;li&gt;耐障害性&lt;/li&gt;&lt;li&gt;無制限のコンピューティングパワー&lt;/li&gt;&lt;li&gt;ユビキタス&lt;/li&gt;&lt;/ul&gt;しかし、開発者にとっては悪夢の発現。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;No Call Stack&lt;/li&gt;&lt;li&gt;No Transaction&lt;/li&gt;&lt;li&gt;No Promises&lt;/li&gt;&lt;li&gt;No Certainty&lt;/li&gt;&lt;li&gt;No Ordering Constraint&lt;/li&gt;&lt;/ul&gt;# No Certaintyがよくわからず、訳せなかったので全部英語 ^^;&lt;br /&gt;&lt;br /&gt;[メモ]&lt;br /&gt;このあたりは、パネルディスカッションでGregorが話していた、ランタイムを考慮したテストの重要性が増すだろう、という話と対応しているようだ。&lt;br /&gt;（ACID）Transactionがない点は、システム特性や方針レベルでは（CAP TheoremやBASEモデルとして）わりと整理されてきているんだろうけど、アプリケーションレベルでの対応方法は別の課題として（少なくともしばらくは）残ることになりそうだ。この話は、少し後にスタバの例つきで出てくる。&lt;br /&gt;順序性の保証がない点は、同じくプログラミングモデルの変革に関わる部分。この話も最後あたりにStatelessとStatefulの分離の話と絡めて出てくる。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;"&gt;ACIDコンセプトの移り変わり&lt;/span&gt;&lt;br /&gt;以前のACID&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Atomic&lt;/li&gt;&lt;li&gt;Consistent&lt;/li&gt;&lt;li&gt;Isolated&lt;/li&gt;&lt;li&gt;Durable&lt;/li&gt;&lt;/ul&gt;以前のACIDに合うように作ってみた、今日のACID&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Associative（結合性）&lt;/li&gt;&lt;li&gt;Commutative（交換可能性）&lt;/li&gt;&lt;li&gt;Idempotent（羃等性）&lt;/li&gt;&lt;li&gt;Distributed（分散）&lt;/li&gt;&lt;/ul&gt;[メモ]&lt;br /&gt;結合性や交換可能性は、並列化をすすめる上で非常に重要になってくる。関数型パラダイムにも通じる概念（ですよね？）。分散は並列化のために必要になってくるのだが、分散をすすめるとノード故障への対応が難しくなってくる。この際に効率よく回復するために、計算の羃等性が重要になってくる。計算が羃等であれば、同じメッセージを再送信するだけで回復できるからだ。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;"&gt;分散システムにおけるトランザクション&lt;/span&gt;&lt;br /&gt;分散システムにおいて、特定のノードと通信できなかった場合、どうするか？2フェーズコミットが必要か？スターバックスを例に考えてみよう。&lt;br /&gt;&lt;br /&gt;結論から言うと、スターバックスは2PCをやっていない。つまり、注文を受けてからコーヒーを作り、清算して、これらすべてを1トランザクションに…というような仕事のやり方をしていない。スループットを出すために、注文を受け付けたら、清算前にコーヒーを作り始めたりしている。&lt;br /&gt;さて、この一連の流れで以下のようなマズいことが起きたらどうすればいいだろう？&lt;br /&gt;&lt;ul&gt;&lt;li&gt;この飲み物は嫌だと、顧客に却下/返品される&lt;/li&gt;&lt;li&gt;コーヒーメーカーが壊れる&lt;/li&gt;&lt;li&gt;顧客が支払えないことに気づく&lt;/li&gt;&lt;/ul&gt;顧客に却下された場合には、飲み物を作り直す（Retry）。コーヒーメーカーが壊れてコーヒーが提供できない場合、代金を払い戻す（Compensation）。顧客が支払えなかった場合、飲み物を捨てる（Write-off）。&lt;br /&gt;このように、最初から完全を求めるのではなく、事後的に対処することで最終的な一貫性を保つようなやり方は、スタバだけでなく銀行のようなシステムにも当てはめることができる。例えば、日銀とバンク・オブ・アメリカが決済をするような場合、エントリを互いに送信しあう際には完全性を求めず、どこかのタイミングで突き合わせをすることで、エントリ送信の誤りを修正するようなことをしている。&lt;br /&gt;# らしい。もちろん、本当かどうかは知らない。&lt;br /&gt;ちなみに、このWrite-offというオプションは、システム開発でも特に忘れられがちな事後対処のオプションなので、もっと考えてもいいんじゃないか、というようなことも言っていた。&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;"&gt;&lt;br /&gt;Googleの並列化への取り組み&lt;/span&gt;&lt;br /&gt;みたいなタイトルで、MapReduceとかGFSとかBigTableとかの話が続いた。このあたりは有名な話ばっかりだったのでメモってない。Sawzallだけ知らなかったんだけど、これらのインフラを効率よく使うためのDSLらしい。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;"&gt;並列性を高めるための方法&lt;/span&gt;&lt;br /&gt;いかにStatefulな部分をStatelessな部分から切り離すか、が重要。&lt;br /&gt;例として、ファイル読み込みのようなものを考えてみる。ファイルを先頭から順に読み、一行ずつ処理していく場合、処理は何行まで進んでいるかの情報を利用可能で、処理のたびに位置情報が更新されていく形になるため、状態を持つことになる。これは、処理が位置情報を利用できるという意味で、Listに対する処理と考えても良い。&lt;br /&gt;ここで、状態を持っている部分（ファイル読み込みの部分）をインフラ（ここではMapReduceだろうが）にまかせ、処理の部分はListではなくSet（集合は順序持っていないので）に対する処理とすることで、Statefulな部分とStatelessな部分を切り離すことができる。&lt;br /&gt;&lt;br /&gt;こうすることで、Statelessな部分は並列実行できるようになる。しかし、Statefulな部分をデータ処理と切り離したことで、できないことが増えることには自覚的になる必要があるだろう。例えば、データ処理が状態を持っていれば可能な、連続して同じデータ内容の行を読み込んだ場合に誤入力としてスキップするようなことはできなくなってしまう。&lt;span style="font-weight: bold;"&gt;どんな妥協をしたのかを自覚しておくのは非常に重要。&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;"&gt;Google App Engineのデモ&lt;/span&gt;&lt;br /&gt;&lt;a href="http://code.google.com/appengine/docs/java/overview.html"&gt;Java版の紹介&lt;/a&gt;とデモ。Hello, 東京！デモってやっぱり楽しいね。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;"&gt;雑感&lt;/span&gt;&lt;br /&gt;拍手とともに終了。Gregorさんは話すのが好きなのか、セッションも楽しかった。&lt;br /&gt;ホスト「それではいつものように、よかったと思った人は緑、まぁまぁかな、という人は黄色、いまいちかな、という人は赤を入れて...」&lt;br /&gt;Gregor「Green！」&lt;br /&gt;会場「ハハハハハ！」&lt;br /&gt;&lt;br /&gt;内容的には、丸山先生の話のGoogle版といった感じかな。スタバの例がすごくわかりやすかった。自分が見たセッションで、唯一デモがあったセッションでもある。緑入れときました。&lt;br /&gt;&lt;br /&gt;目次：&lt;br /&gt;&lt;a href="http://hibituredure.blogspot.com/2009/04/qcon-tokyo-2009.html"&gt;QCon Tokyo 2009に行ってきた&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-2906380051782635306?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/2906380051782635306/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=2906380051782635306&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/2906380051782635306'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/2906380051782635306'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2009/04/programming-cloud-internet-as-platform.html' title='Programming the Cloud -the Internet as Platform-'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-3847011819371427998</id><published>2009-04-12T23:41:00.006+09:00</published><updated>2009-04-14T08:26:54.557+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='セミナー/勉強会'/><category scheme='http://www.blogger.com/atom/ns#' term='report'/><title type='text'>Spring in a Changing World</title><content type='html'>Rod Johnsonのセッション。なんかマーケ色がわりと強かったので、あまりメモっていない。メモった範囲で。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;ビジネス、技術の両面で変わる世界&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;JavaEEの失敗&lt;/li&gt;&lt;li&gt;よりシンプルな技術への指向&lt;/li&gt;&lt;li&gt;世界的な景気後退&lt;/li&gt;&lt;/ul&gt;今は、リーンなソフトウェア（目的にフィットしており、シンプル）が求められている。&lt;br /&gt;&lt;br /&gt;技術の変化がとてもはやいため、マネージャは開発者に頼らざるを得なくなっている。開発者は今、かつてない力を持っている。&lt;br /&gt;&lt;br /&gt;今まではSilicon Valleyがすべてのルールを決めていたが、これからは世界中に主導権が分散する。言語の問題はあるが、徐々に解決していく。&lt;br /&gt;&lt;br /&gt;OSSはシンプルであり、リーンな開発につながる。今後のソフトウェアはこうなる。&lt;br /&gt;巨大ベンダー =&gt; OSSコミュニティ&lt;br /&gt;パワーポイント上でうまく動くソフトウェア =&gt; 開発者に支持されたソフトウェア&lt;br /&gt;&lt;br /&gt;JavaEEは、単独ですべてを解決しようとしているが、これはリーンではない。&lt;br /&gt;&lt;br /&gt;日本でのSpringの利用率は、他国と比べて高くないが、これはSeasarというプロダクトがあるからだと聞いている。しかし、長期のトレンドで見れば、他国と同じようになっていくだろう。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Next Spring&lt;/span&gt;&lt;br /&gt;未だに残る、JavaEEの複雑性を取り除く。例えば、プロジェクトの開始時にプロダクトを選択し、動作可能なまでに整えるのはいまだに面倒。&lt;br /&gt;新たな挑戦者（RoR, Django, Zend...）もいる。&lt;br /&gt;.NETも色々やっている。.NETの利点は、MSが全体像を考えてドライブしている点。Javaにはそのような役割を果たすものがかけている。Sunは、EnterpriseJavaの方向性を示すのに失敗している。ただ、MSは独占企業なのが問題。&lt;br /&gt;Spring Sourceがその役割を果たす。MSとは違い、オープンなアプローチで、統合された、アプリケーションのライフサイクル全体をカバーするものを提供する。&lt;br /&gt;&lt;br /&gt;具体的には...&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Tomcatへの支援を継続する&lt;/li&gt;&lt;li&gt;ツールスイートを作る&lt;/li&gt;&lt;li&gt;クラウド製品を提供する&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;雑感&lt;/span&gt;&lt;br /&gt;開発者のエンパワーメント、という流れはいいなぁ、と感じたが、それとSpring Sourceの取り組みの結びつきがあまりぐっとこなかったな。個人的には、インフラや言語コミュニティの話より、アプリケーションやアプリケーションモデルの話がききたかった。&lt;br /&gt;&lt;br /&gt;「技術の変化が早いから、マネージャは開発者に頼らざるを得ない」という下りは、必ずしもそうはなってない面があるように思う。技術の変化が早いことに、古い技術に固執することで対応しようとしたり、完全に無視することで対応する人は結構いる気がするんだなぁ。&lt;br /&gt;&lt;br /&gt;目次：&lt;br /&gt;&lt;a href="http://hibituredure.blogspot.com/2009/04/qcon-tokyo-2009.html"&gt;QCon Tokyo 2009に行ってきた&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-3847011819371427998?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/3847011819371427998/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=3847011819371427998&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/3847011819371427998'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/3847011819371427998'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2009/04/spring-in-changing-world.html' title='Spring in a Changing World'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-6490983093783931421</id><published>2009-04-12T15:29:00.007+09:00</published><updated>2009-04-13T15:43:47.699+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='セミナー/勉強会'/><category scheme='http://www.blogger.com/atom/ns#' term='report'/><title type='text'>クラウドの技術的な特徴について</title><content type='html'>丸山先生のジェネラルセッション。内容的にはEric Brewerの資料（&lt;a href="http://hibituredure.blogspot.com/2009/04/cap-theorem.html"&gt;CAP Theorem&lt;/a&gt;/Eventually Consistent）をクラウドの立場から眺める、といったもの。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;ScalabilityとAvailability&lt;/span&gt;&lt;br /&gt;Scalabilityは、Scal-outによって達成できるが、Scale-outには技術的な裏打ちが必要であり、ノウハウの蓄積が必要。&lt;br /&gt;Availabilityは、故障に対する適切な対処によって達成できるが、これには複製を作成する戦略（Replication）が基本になる。複製を作ってしまうと、同期の問題、すなわち一貫性に関する問題が発生する。&lt;br /&gt;&lt;br /&gt;[メモ]&lt;br /&gt;CAP定理で言うと、ScalabilityがおおよそPartitionに、AvailabilityがそのままAvailabilityに、一貫性がConsistencyにあたると考えてよいと思う。上記は、クラウドにおけるCAPの関係をわかりやすく説明してくれていると言える。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Partitionが必須となる背景&lt;/span&gt;&lt;br /&gt;High-endコンピュータとCommodityコンピュータの価格性能比は、約1:33。経済的な選択をすると、必然的にPartitionを選択することになる。安いハードウェアはそれなりの能力しか持たないが、&lt;span style="font-weight: bold;"&gt;障害に強いソフトウェア&lt;/span&gt;が、安いハードウェアを役に立つものに変える。&lt;br /&gt;&lt;br /&gt;[メモ]&lt;br /&gt;ただし、よくよく考えると、Partitionと、Partition度合いを容易に増減できるかどうか（=Scalability）は、違った特性のようにも思える。セミナーでも、一口にクラウドといっても、リソースを動的に増減できるもの（Hot Scalable）とできないものとできないもの（静的にのみ可能、Scalable）がある、と言っている。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;CAP定理とクラウド&lt;/span&gt;&lt;br /&gt;これは、共有データを持つシステムにおいては、Consistency, Availability, Partitionの3つのうち、最大でも2つの特性しか持つことができない、というもの。&lt;br /&gt;クラウドではPartitionは必須になるため、ConsistencyかAvailabilityのどちらかを選ばなければならない。…が、この選択はシステム全体に一律に適用しなければならないわけではない、というのが重要な点。単一のシステム内でも、カートに商品を入れる段階ではAvailabilityを優先し、注文の段階では一貫性を優先する、といったように、部分ごとに必要となる特性は変わる。&lt;br /&gt;&lt;br /&gt;また、上記でAvailabilityを「優先する」と書いたように、AとCはどちらかを取ればもう一方が完全に失われる、というものではなく、AとCの配分には中間的な選択肢が数多く存在する。特に、Consistencyにはいくつかのレベルがあり、これには名前もつけられているようだ。以下、&lt;a href="http://www.hyuki.com/yukiwiki/wiki.cgi?EventuallyConsistent"&gt;結城さんの翻訳サイト&lt;/a&gt;からの引用。&lt;br /&gt;&lt;ul&gt;&lt;li&gt; &lt;b&gt;強い整合性(Strong consistency)&lt;/b&gt;: 更新が完了したら, 続くアクセス(A, B, C いずれかによる) は更新された値を読み出す&lt;/li&gt;&lt;li&gt; &lt;b&gt;弱い整合性(Weak consistency)&lt;/b&gt;: システムは続くアクセスが更新された値を読みだすことを保証しない. 更新した値が返される前には様々な条件を満たす必要がある. 多くの場合, その条件は経過時間である. 更新された時刻から更新した値の読みだしを観測者に保証するまでの間隔を &lt;b&gt;不整合ウィンドウ(inconsistency window)&lt;/b&gt; と呼ぶ. &lt;/li&gt;&lt;li&gt; &lt;b&gt;結果整合性(Eventual consistency)&lt;/b&gt;: ストレージシステムは, オブジェクトに(不整合ウィンドウが閉じたあとも)最後まで変更が加えられなかったなら, 全てのアクセスが最後の更新値を読みだせると保証する. 結果整合性を実装する最もよく知られたシステムは DNS だ. 名前の更新は分散しており, 設定のパターンやキャッシュ制御の組合せで振舞いがかわる. クライアントは最終的に更新された値を見ることになる. &lt;/li&gt;&lt;/ul&gt;さらに結果整合性にも細かなバリエーションがあるらしい。&lt;br /&gt;&lt;ul&gt;&lt;li&gt; &lt;b&gt;因果整合性(Causal consistency)&lt;/b&gt;: プロセス A がプロセス B と通信を行い, その B がデータ要素を更新したとき, B が続けてアクセスをすると更新された値が戻る. また書込みはその前の書込みを上書することが保証される. プロセス A と因果関係をもたないプロセス C は通常の因果整合性に従う.&lt;/li&gt;&lt;li&gt; &lt;b&gt;Read-your-wrie consistency&lt;/b&gt;: このモデルは重要だ. プロセス A が書込みをしたとすると, そのあと A は常に更新された値にアクセスできる. 古い値は決して見えない. これは因果整合性の特別な場合だ. &lt;/li&gt;&lt;li&gt; &lt;b&gt;セッション整合性(Session consistency)&lt;/b&gt;: 上のモデルの実用的なバージョン. プロセスはあるセッションの下でストレージシステムにアクセスする. セッションのある間, システムは Read-your-wrie consistency を保証する. 何らかの故障シナリオでセッションが破棄された場合は新たに作りなおす必要がある. また保証はセッションをまたがない.&lt;/li&gt;&lt;li&gt; &lt;b&gt;単調読み出し整合性(Monotonic read consistency)&lt;/b&gt;： もしプロセスがオブジェクトからある値を読みだしたら, それ以降にはより古い値を読み出さない.&lt;/li&gt;&lt;li&gt; &lt;b&gt;単調書き込み整合性(Monotonic write consistency)&lt;/b&gt;: この場合はシステムが同じプロセスからの書込みが直列化されるよう保証する.このレベルの保証をもたないシステムでプログラムを書くのは難しいことで悪名高い. &lt;/li&gt;&lt;/ul&gt;クラウドの場合にConsistencyが問題になるのは、複数ノードへの書き込み（失敗）のケース。書き込み失敗時の対処としては、リトライや、失敗したノードの切り離しがあげられる。一定回数リトライし、それでもダメだった場合にはノードを削除することで、一定時間後にはシステム内は整合性が保たれた状態になる。これが、（クラウドにおいて）Eventually Consistentレベルの一貫性の実現方法の概要。&lt;br /&gt;&lt;br /&gt;このような、リトライやノード削除の機能は、従来データベース製品が担っていたのだが、これらは本来OSが担っても良い部分。現段階でこの部分をOSが担っていないのは、単に歴史的な経緯によるものだと思われる。少なくともクラウドの分野では、OSとデータベースの統合がはじまっている。&lt;br /&gt;&lt;br /&gt;このような、厳密にACIDを満たさないような新たなトランザクションモデルをBASE(Basically Available, Soft-state, Eventually-Consistent)と言う。ACIDはデータベース製品などが担当する比較的局地的なトランザクションモデルであるのに対し、BASEはもう少し広い、システムレベルのトランザクションモデルらしい。&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;&lt;br /&gt;Soft-State&lt;/span&gt;&lt;br /&gt;分散システムにおいて、状態を完全に守りきるのは不可能。丸山先生の説明はよくわからなかったので、ネットで調べてみると、&lt;a href="http://dictionary.rbbtoday.com/Details/term608.html"&gt;こんなの&lt;/a&gt;がでてきた。ステートと状態がかぶっているのが気になるが、丸山先生よりわかりやすかった。&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;ハード・ステート状態管理&lt;br /&gt;&lt;span id="intelliTXT"&gt;　データ通信を管理する方法の一種。一般に、通信中のコンピュータが通信プログラムを終了する際に、「デー タ通信の終了」を通知しないと、それが正常に終了したのかどうか相手にわかりません。このため、通信プログラムの動作には高い信頼性がもてません。これに 対して、「データ通信の終了」を相手に通知してから終了するようなプログラムであれば、そのコンピュータの動作には高い信頼性が期待できます（終了通知な しに終了すれば事故だとわかる）。したがって、このようなプログラムに対しては、通信を始めるときにだけ状態を確認しておけば、以降の動作には信頼性がも てます。&lt;br /&gt;　このように、通信の開始のときだけ相手プログラムの動作を確認するデータ通信管理手法を、ハード・ステート状態管理と言います。既存の 電話システムが、この例です。反対語は、通信中に絶えず相手の動作を確認するソフト・ステート状態管理で、インターネットがこれに当たります。&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Eventually Consistency by Example&lt;/span&gt;&lt;br /&gt;さて、ここで、2つのシステム要素（A, B）を持つ分散システム上で、システムAが自身の状態を更新し、その状態をもとにBの状態を更新するケースを考えてみる。&lt;br /&gt;極端な例として、システム要素AとBが銀河をまたいで離れているようなケースを考えると、光速度の制約があるため、Aの状態変更とBの状態変更をACIDに行おうとすると、使い物にならなくなってしまう。この場合、まずはAの状態を（ACIDに）変更し、その後でBに状態変更を通知するのが現実的になるだろう。この際、Aが通知を送ってからBに届くまでの間、システムは不整合な状態となる。Bに通知が届いた後は整合性を回復したと&lt;span style="font-weight: bold;"&gt;考えることができ&lt;/span&gt;、Eventually Consistentとなる。逆にこうした動作を前提にすると、ACIDトランザクションをコーディネートするようなTransaction Managerは不要になる。&lt;br /&gt;&lt;br /&gt;こうした状況を現実の分散システムにあてはめて考えてみると、ACIDトランザクションはBASE(Eventually Consistent)トランザクションの特殊な形態（Consistencyをほぼ完全に満たすことができるケース）とみなすことができる。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;クラウドにおける排他戦略&lt;/span&gt;&lt;br /&gt;悲観ロックより楽観ロックだよね、という話。Scalabilityのためには楽観ロック。ある意味当たり前？&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;&lt;br /&gt;クラウドと永続化&lt;/span&gt;&lt;br /&gt;クラウドのようなシステムのノードは、落ちることなく動き続ける。であれば、メモリもPersistencyを担うことができるのではないか？という発想が出てくる。となると、DBのインデックスのようなものはハッシュテーブルとして実装されることになり、自然に分散ハッシュテーブル（Distributed Hash Table）への注力へとつながっていくことになる。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;現実のEnterprise SystemへのEventually Consisitency概念の応用&lt;/span&gt;&lt;br /&gt;システム全体を単一のトランザクションモデル（特にACID/Immediate Consistency）でカバーするのではなく、ケースに応じて一貫性レベルを選択することで、PartitionやAvailability、特にPartitionを増すことができる。こうした形で応用すると良いのではないか、みたいな話だった。&lt;br /&gt;Eventually ConsistentやSoft Stateは、情報システムにおける物理的な限界点を示したものであり、基本原理となるため、考慮するのは必然、といった話もちらっと最後に出てきていた。&lt;br /&gt;&lt;br /&gt;目次：&lt;br /&gt;&lt;a href="http://hibituredure.blogspot.com/2009/04/qcon-tokyo-2009.html"&gt;QCon Tokyo 2009に行ってきた&lt;/a&gt;&lt;br /&gt;&lt;ul&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-6490983093783931421?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/6490983093783931421/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=6490983093783931421&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/6490983093783931421'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/6490983093783931421'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2009/04/blog-post_12.html' title='クラウドの技術的な特徴について'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-3195547599190018951</id><published>2009-04-11T12:41:00.015+09:00</published><updated>2009-10-02T13:56:56.119+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='セミナー/勉強会'/><category scheme='http://www.blogger.com/atom/ns#' term='system'/><title type='text'>CAP Theorem（定理）</title><content type='html'>QCon Tokyoでは色々なところで「CAP Theorem」という定理が出てきた。が、eBayの人をのぞけば（たぶん）正確な定義は提示されておらず、不明な点がいくつか残っている。これからのインフラを考える上でも、QConセッションの内容をより良く理解するためにも、このあたりをまずきちんと理解しておきたい。主な疑問点は以下のとおり。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;C, A, Pの特性の正確な定義は何なのか&lt;/li&gt;&lt;li&gt;CAP定理が前提にしているシステムのモデルはどのようなものなのか&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Theoremとなっているが、単なる経験則なのか、それとも数学的な定理なのか&lt;/li&gt;&lt;/ul&gt; 頼みの綱？のWikipediaを調べてみたが、日本語版はおろか英語版にも載っていない。概観をまとめた&lt;a href="http://www.hyuki.com/yukiwiki/wiki.cgi?EventuallyConsistent"&gt;海外の記事を結城さんが訳してくれている&lt;/a&gt;ようなので、これを読んでみる。&lt;br /&gt;&lt;br /&gt;CAP Theoremそのものは、Eric BrewerがPODCカンファレンスのキーノートで提唱したものらしい。CAP Theoremには形式的な証明があるらしいので、数学的に証明された、文字通りの定理であるようだ。証明の論文はACMの有料会員にならなければ見られないらしく、無料のWeb会員では見ることができなかった。残念。Eric Brewerの&lt;a href="http://www.cs.berkeley.edu/%7Ebrewer/cs262b-2004/PODC-keynote.pdf"&gt;資料&lt;/a&gt;はWeb上で公開されているので、これを見るのが一番良さそう。&lt;br /&gt;&lt;br /&gt;Eric Brewerのスライドでは、availabilityやgraceful degradation, performanceのためにはCとIが犠牲になるが、これは根本的なトレードオフである、という認識が出発点になっており、丸山先生も紹介している BASE（Basically Available, Soft-state, Eventural consistency）の概念の提示に続いている。さらに、ACIDとBASEはどちらかを選択しなければならないような排他的なものではなく、スペクトラム のようなものではないか、とも書かれている。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;C, A, Pの定義&lt;/span&gt;&lt;br /&gt;さて、CAP Theoremだが、CAPは以下のように紹介されている。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;C:Consistency&lt;/li&gt;&lt;li&gt;A:Availability&lt;/li&gt;&lt;li&gt;P:Tolerance to network Partition&lt;/li&gt;&lt;/ul&gt; QCon（少なくとも同時通訳で）では、Partitionについてはネットワークとの関係は言及されておらず、並列処理可能性とほぼ同等に扱われていた気がする。が、ここでは明確に、ネットワーク分断への耐性、と書かれている。&lt;br /&gt;AmazonのCTOによる、2007年&lt;a href="http://camelcase.blogspot.com/2007/08/cap-theorem.html"&gt;InfoQの発表&lt;/a&gt;では....&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;- Strong &lt;span style="font-weight: bold;"&gt;C&lt;/span&gt;onsistency: all clients see the same view, even in presence of updates&lt;br /&gt;- High &lt;span style="font-weight: bold;"&gt;A&lt;/span&gt;vailability: all clients can find some replica of the data, even in the presence of failures&lt;br /&gt;- &lt;span style="font-weight: bold;"&gt;P&lt;/span&gt;artition-tolerance: the system properties hold even when the system is partitioned&lt;/blockquote&gt;&lt;br /&gt;となっているらしい。Partition-toleranceは、システムが分割された場合でもシステムが保持する特性、と定義されている。つまり、 Partition-toleranceが低いシステムは、分割すると色々な特性が失われる、ということだろうか。この定義からすると、並列可能性というのもあながち間違った表現ではないように感じる。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;CAP定理&lt;/span&gt;&lt;br /&gt;さて、以上のように簡単な定義がなされた上で、CAP定理は以下のように定義される。&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;You can have at most two of these properties for any shared-data system&lt;/blockquote&gt;&lt;br /&gt;すなわち、「共有データを持つシステムは、CAPとして定義された特性のうち最大でも2つの特性しか持つことはできない」。以降、例をもとに説明してあるんだが、例自体があいまいなので、例の技術に詳しくない自分にはなかなかわかりづらい。想定している状況の単純なモデルを先に確認した方が話が早いと思う。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;想定するモデル&lt;/span&gt;&lt;br /&gt;2つのモジュールと、その間のインタフェースについて考える。クライアントとサーバーでも、ピアとピアでもなんでも良い。典型的には、プロシージャコール の形を取るが、この際インタフェースをはさんだどちらの側も同一のアドレス空間にいる。スレッドはこのインタフェースを超えていく。&lt;br /&gt;&lt;br /&gt;しかし、インタフェースをはさんだそれぞれの空間が同じアドレス空間ではない場合、Call by Referenceは使えず、データをコピーしなければならなくなる。こうした状況になった場合のCAPについて議論しているようだ…うーん。それでもやっぱりわかりづらいな。例を確認してみる。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;C+Aを持つケース&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;単一サイトのデータベース&lt;/li&gt;&lt;li&gt;クラスタデータベース&lt;/li&gt;&lt;li&gt;LDAP&lt;/li&gt;&lt;li&gt;xFS file System&lt;/li&gt;&lt;/ul&gt; 一貫性と可用性を持つかわりに、ネットワーク分断に対する耐性を失っている例。このようなシステムは、2フェーズコミットや、キャッシュ検証のプロトコルを持つ。&lt;br /&gt;単一サイトのデータベースを考えてみると、確かに一貫性は得られている。ネットワーク分断で失われる特性が多いというのは、何をさしているのだろうか？少なくとも、 ネットワーク分断をすすめていくと、性能が犠牲になるのは間違いなさそうだが。&lt;br /&gt;可用性が得られている、というのはさらによくわからない。2PCの例では、TMがACID特性を保証しているので、データのコピーは発生せず、常にすべてのデータが得られるため可用性が高い、ということだろうか？少なくとも、クラスタでは可用性は高そうだが。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;C+Pを持つケース&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;分散データベース&lt;/li&gt;&lt;li&gt;分散ロック&lt;/li&gt;&lt;li&gt;主要なプロトコル&lt;/li&gt;&lt;/ul&gt; 一貫性とネットワーク分断への耐性を持つが、可用性を失っている例。悲観ロックを使ったりしているらしい。&lt;br /&gt;分散データベースを考えると、ネットワーク分断への耐性はかなり高そうなのはわかる。また、システムが一部故障した際にはすべてのデータを得られなくなる だろうから、可用性が低いというのも理解できる。分散データベースの一貫性については、実はよくわかってないのだが、きちんと保証できているのだろうか？本当にきちんとできているなら、2pcとあまり変わらない気がするのだが。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;A+Pを持つケース&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Coda&lt;/li&gt;&lt;li&gt;Webキャッシュ&lt;/li&gt;&lt;li&gt;DNS&lt;/li&gt;&lt;/ul&gt; 可用性とネットワーク分断への耐性を持つが、一貫性を失っている例。リース/期限切れのアーキテクチャパターンや、競合解決、楽観的同時実行制御などを用いるようだ。&lt;br /&gt;DNSについて考えると、確かにネットワーク分散しても失われる特性は小さく、可用性も非常に高いが、一貫性を失っていると言える。&lt;br /&gt;&lt;br /&gt;この後もスライドとしては細かい話が続いていくんだけど、結局CAP定理が前提としているモデルがどのようなものであるのかは、正確にはわからないままだ。&lt;br /&gt;例えば…&lt;br /&gt;&lt;ul&gt;&lt;li&gt;ネットワーク分断というのは、どの要素とどの要素の分断のことを言っているのか（あらゆるシステム要素間の分断なのか、特定の部分の分断なのか）&lt;/li&gt;&lt;li&gt;分断によって失われる特性、失われない特性とはどのようなものなのか&lt;/li&gt;&lt;li&gt;高い可用性が意味するものは何なのか&lt;/li&gt;&lt;li&gt;などなど&lt;/li&gt;&lt;/ul&gt;これらがわからないと、きちんと理解できた気もしないし、分散システムにおけるアーキテクチャ設計で自信もって決断を下せないと思うんだけど、これらの資料から完全に理解するのは難しそうだし、どれくらい時間がかかるのかも見当がつかない。なので、一旦はここで終え、QConの個別セッションを見ていきたい。当面は、結城さん翻訳資料にある以下の説明を、例による便宜的な定義として使っていく。&lt;blockquote&gt;ネットワーク分断への耐性を捨てたシステムなら, データの整合性と可用性を実現できる.  これには普通トランザクション・プロトコルを使う.  実現のためにはクライアントとストレージ・システムが同じ環境にある必要がある.  これだとシナリオによってはシステム全体が故障してしまうし, クライアントは分断を検知できない.  重要な洞察がある: 大規模な分散システムではネットワークの分断が所与のものであり,  従って整合性と可用性は両立しない.  どちらか一方は捨てる必要がある.  整合性を妥協すればシステムは分断のある状況でも高可用性を実現できる.  整合性を優先すればシステムの使えない状況を生む.  &lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-3195547599190018951?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/3195547599190018951/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=3195547599190018951&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/3195547599190018951'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/3195547599190018951'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2009/04/cap-theorem.html' title='CAP Theorem（定理）'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-4038378019440791893</id><published>2009-04-10T23:12:00.004+09:00</published><updated>2009-04-13T15:43:47.700+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='セミナー/勉強会'/><category scheme='http://www.blogger.com/atom/ns#' term='report'/><title type='text'>パネル・ディスカッション「エンタープライズ・ソフトウェア開発の動向」</title><content type='html'>QCon Tokyo最後のセッション。以下のような豪華な参加者陣でした。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Floyd Marinescu （InfoQのエラい人）&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Dylan Schiemann（Dojoのエラい人）&lt;/li&gt;&lt;li&gt;Randy Shoup（eBayのエラい人）&lt;/li&gt;&lt;li&gt;Gregor Hohpe（Googleの中の人、EIPの共著者）&lt;/li&gt;&lt;li&gt;Henrik Kniberg（Agileなコンサルタント）&lt;/li&gt;&lt;/ul&gt;一緒に行ったメンバーとの会話で、なんとなく自分が担当になった雰囲気がしたので、わかる範囲で書き起こしつつ、自分の感想も（発言とは区別がつく形で）書いていきます。メモが中途半端なので、話をつなげるために微妙に補足してたりします。会話口調は、そのときの雰囲気から適当に作ってます。敬称はすべて省略してます。発言者とか間違えてるかもしれないので、その辺ふまえつつ適当に見てやってください。&lt;br /&gt;&lt;br /&gt;[まずは、エンタープライズソフトウェア開発の動向について全員が2分ずつ発言。]&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Henrik：&lt;/span&gt;&lt;br /&gt;プロセスにかかわる立場からの話をしたいと思う。&lt;br /&gt;北欧ではAgileの導入がかなり進んできているけど、Agile導入に際してはScrumをエントリポイントとして採用しているところが多い。こうして、特に従来よく見られていたような、技術チームと業務チームのコミュニケーション上の問題を解決することに成功してきている。&lt;br /&gt;ただし、Agileでこうした問題が解決されるにつれて、その他の問題、例えばコードの品質などの技術的な問題もあらわれてくる。このような問題を解決するために、今後はXPで採用されているようなプラクティスが重要になってくるだろう。&lt;br /&gt;# Scrumは他のAgileアプローチに比べてプロジェクト管理に強いが、技術上のプラクティスはあまり多くないことを受けての話だと思う。&lt;br /&gt;&lt;br /&gt;また、企業では、ソフトウェアの開発が終わったあとも色んなプロセスが続いていく。リーンの手法が重要になってきており、ソフトウェア開発だけでなくバリューチェーン全体を改善することが重要になってきている。&lt;br /&gt;これまで企業は、変革を口にするだけでなかなか実行に移そうとしなかった面もあったが、今回の経済危機の影響を受け、話だけではなく実際に実行にうつしつつある。&lt;br /&gt;無駄なプロセスを続ける余裕があった企業も余裕がなくなってきており、組織的な変革がはじまろうとしている。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Gregor：&lt;/span&gt;&lt;br /&gt;あんまりネタを考えてこなかった。&lt;br /&gt;立ってのパネルディスカッションってはじめてっす。&lt;br /&gt;立ち飲みみたいっす。&lt;br /&gt;残念なことに、飲み物がアルコールじゃないです。&lt;br /&gt;ってことは、これは立ち話ってうんですかね。&lt;br /&gt;ビールがあると最高だったんですけどね。&lt;br /&gt;とかジョークをいいながら、話のネタを考えていました。&lt;br /&gt;&lt;br /&gt;大きなトレンドの話としては、知っていることが何度もまわってくる、ということがある。知っていることが何度もトレンドとしてやってくるのだが、そこには新しい考えが注入されていく。&lt;br /&gt;SOAやクラウドはほんとに新しいのか、との疑問がよくあるのだが、新しいとも言えるし古いとも言える。古いコンセプトに新しい考えが注入されているのだ。こうしたトレンドのサイクルは、ファッションと似ている。色んなものはやがて戻ってくる。これは当然で、実証済みの概念というのは古くても役に立つ。&lt;br /&gt;&lt;br /&gt;さて、これは開発者にとってはどんな意味があるのだろうか？開発者はどうすればいいのか？&lt;br /&gt;まずは概念を理解することをすすめたい。サイクルする技術は、詳細はかわってしまうかもしれないが、多くの概念が転用できる。開発者は、転用できるアイディアにフォーカスすべき。重要な概念を概観できることが大事。&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;&lt;br /&gt;Henrik：&lt;/span&gt;&lt;br /&gt;[難しくて曖昧な話はわかったから、といった調子で :-)]&lt;br /&gt;結局、具体的にはどういう動向が重要になってくると思う？&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Gregor：&lt;/span&gt;&lt;br /&gt;人間は未来を予想できない、予想できなくても僕のやり方なら大丈夫なはずなんだけどね！ :-)&lt;br /&gt;あえて新しいトレンドを推定するなら、ランタイムの重要性の高まりかな。&lt;br /&gt;今までランタイムは見えないもので、みんなはモデルや言語なんかの表面的な部分に注力してきたけど、クラウドの登場などでランタイムが重要になってきている。&lt;br /&gt;ソフトウェアを書くのは全体の一部、という話がHenrikからあったけど、組織プロセスの観点だけでなく、ソフトウェア実行の観点でも同じことが言える。ソフトウェアを書き終わったからといって、全体のほんの一部しか終わったことにならない。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Randy：&lt;/span&gt;&lt;br /&gt;トレンドとしては、3つあると思う。&lt;br /&gt;&lt;br /&gt;まず1つは、大きな企業のプラクティスが小さな企業に浸透してきているということ。分散化、パーティショニングのような課題を、小さい企業も意識しはじめている。&lt;br /&gt;&lt;br /&gt;2つめは、アプリケーションの開発方法。&lt;br /&gt;たいていの企業では色んな言語やプラットフォームでシステムを作ろうとしており、ヘトロジニアスな環境が多くなってきている。多様な選択肢があるが、最適なものを見極めることが重要だ。&lt;br /&gt;&lt;br /&gt;3つ目は、デプロイメント、つまりアプリケーションの展開に関するもの。&lt;br /&gt;クラウドが一番明らかな例で、これまではコンシューマ向けにしか使われておらず、クラウドのプレーヤーも少ないが、これからは銀行や大企業、政府機関などが内部にクラウドを持つようなことも起きてくるのではないか。また、クラウドが浸透していくと、中小企業にまでその利用が広がっていくだろう。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Dylan：&lt;/span&gt;&lt;br /&gt;2つの大きな相反する動き、統合と細分化に注目したいと思う。&lt;br /&gt;例えばJavaを見ていくと、90年代から統合化がどんどん進んでいった。&lt;br /&gt;# この辺よくわからなかったっす&lt;br /&gt;# 統合化されて肥大化し、使いづらくなると、小さなプレイヤーにチャンスが来るとかそんな話をしていたと思う&lt;br /&gt;&lt;br /&gt;OSSでは細分化が進んでおり、ものすごくたくさんのプロジェクトやソフトウェアが生まれている。一方でOSS同士のアライアンスも増えてきており、統合化も同時に展開されているという興味深いことが起きている。これは非常にエキサイティングだ。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Floyd：&lt;/span&gt;&lt;br /&gt;FowlerとRod Johnsonのかわりにきました。彼らはもういなくなっちゃったからね。&lt;br /&gt;Martinは、プロジェクトに常に1つの言語を使うのではなく、目的にマッチした言語を組み合わせて使う、というようなことを言っていた。Rodは、リーンなツールが必要になってきているという話をしていた…と思う。なんかこんな感じだったよね？北京ではこんな話をしていたと思うんだけど、あってる？&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Dylan：&lt;/span&gt;&lt;br /&gt;ともあれ、すべての根底にある流れは、Webがアプリケーションのプラットフォームになってきている、ということだ。クラウドコンピューティングもRIAのようなものも、すべてこの流れから出てきたものだ。&lt;br /&gt;&lt;br /&gt;ところで、Javaのコミュニティってつまらなくなってない？あきてきた人？&lt;br /&gt;[手をあげて賛成者を探す。結構手があがる]&lt;br /&gt;&lt;br /&gt;これは、Javaを使うタスクが安定化してきたということだ。2000年頃は、色んなWebのフレームワークが出てきていた。これはつまり、Javaを使ってWebアプリを作るのが新しかったということだ。&lt;br /&gt;&lt;br /&gt;技術がかわるとまたいろいろとエキサイティングなものが出てくるだろう。クラウドもその端緒になると思う。Javaで標準かが次々進んだように、クラウドのプログラミングモデルを統一化する動きがはじまるかもしれない。みんなベンダーにロックインされたくないだろう？&lt;br /&gt;&lt;br /&gt;クラウドコンピューティングってのはすごく重要な流れだ。これによって、中小企業が効果的に色々な仕事ができるようになるだろう。Linuxやコンフィグファイルを気にしなくてもよくなるんだ。低コストで色々できるようになる。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Gregor：&lt;/span&gt;&lt;br /&gt;ここいらで、今まで出た話を統合してみたい。&lt;br /&gt;フラグメンテーションや統合の話、クラウド、開発者のエンパワーメント、これらはつながっていると思う。&lt;br /&gt;# 開発者のエンパワーメントは、Rod Johnsonがセッションの前半であげたキーワード&lt;br /&gt;開発者の力が増すという流れと、クラウドは同じ方向を向いていると思う。開発者がまたガレージで開発を始められるということだ。ここのところあがってきていたWebに対するインフラの要求レベルに、やっとおいついてきた。&lt;br /&gt;&lt;br /&gt;こういう、土俵が平らになるような時期が訪れることがあるが、こういう時にはイノベーションが次々とおこる。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Floyd：&lt;/span&gt;&lt;br /&gt;ここで、Rodが持っていた、少し違う意見を紹介したいと思う。Rodは、GrailsはJavaコミュニティにおける重要な進展だといっていて、Javaはまだまだエキサイティングだと言っている。&lt;br /&gt;SpringSourceもクラウド対応機能みたいなものをもうすぐリリースするそうだ。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Gregor：&lt;/span&gt;&lt;br /&gt;ちゃんと機能するものを作るのが生活の糧であるなら、Javaにとって安定はいいことかもしれない。安定することによって、新しいことをする余裕が出てくる。細かなバグをおいかけたりしなくてもよくなる。こういう意味で、Javaの安定にはいい面も悪い面もあるだろう。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Dylan：&lt;/span&gt;&lt;br /&gt;今や、Javaは世界のFortlanやCOBOLのようになってきているよね。&lt;br /&gt;&lt;br /&gt;[ここで質問タイム、外国の方が英語で質問]&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;質問者：&lt;/span&gt;&lt;br /&gt;Javaコミュニティというと、Webアプリ開発者ばかりが対象として語られることが多いけど、JavaコミュニティはWebだけじゃない。WebではないJavaコミュニティの人がこういう場にきていないのは残念なことだ。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Randy：&lt;/span&gt;&lt;br /&gt;eBayはフロントエンド以外はWebとは関係ない処理をたくさんやっているよ。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Gregor：&lt;/span&gt;&lt;br /&gt;自分もそう思う。実際のシステムではWebは一部のみ。Webの定義にもよるけど、HTMLを扱っているのがWebだとすると、システムの大半はHTMLとは関係ない。&lt;br /&gt;バックエンドでは、SOAや コンポーネント化、RESTのような技術を扱っているのだろうけど、これらもWebと似たような課題を持っているのではないか？Web的な考え方がシステム全体に広がってきているのではないか？&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;&lt;br /&gt;Randy：&lt;/span&gt;&lt;br /&gt;たしかに分散システムという意味では同じような特性を持っていると思う。とはいえ、銀行や政府のシステムとeBayのようなシステムでは要件はかなり異なってくる。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Floyd：&lt;/span&gt;&lt;br /&gt;Webは新しいプラットフォームなのでしょうがない面もある。デスクトップJavaはずいぶん前に死に絶えてしまったし。&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;&lt;br /&gt;質問者：&lt;/span&gt;&lt;br /&gt;確かにそうかもしれない。JavaがWebを捨ててしまえば生き残れないだろうから、仕方ないとは思う。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Dylan：&lt;/span&gt;&lt;br /&gt;ヘテロな環境が増えてきたので、最適なものを選ぶことができるようになってきた。&lt;br /&gt;# これ、なんだったか思い出せない...&lt;br /&gt;&lt;br /&gt;[次の質問。]&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;&lt;br /&gt;質問者：&lt;/span&gt;&lt;br /&gt;Scalaが好き！Scalaは分散処理などの面で面白いと思うけど、どう思う？&lt;br /&gt;# すごいはしょってます...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Randy：&lt;/span&gt;&lt;br /&gt;実際に使ったことはないが、Scalaは良いと思う。正しいツールを正しい仕事のために使う、という話で考えると、すばらしいツール。Erlangにも興味深いアプリケーションができてきているし、特定のタイプの作業に特化した言語を適切な場所に使うのが重要になってくる。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Gregor:&lt;/span&gt;&lt;br /&gt;一貫性・分散性を考慮すると、もっといい言語がほしいという気持ちはある。Javaはこの辺りを考えると、あまり適していない部分がある。&lt;br /&gt;# このあたり、C#がLINQや関数的な要素を入れていろいろやっている話をしていたが、どうつながっているのかよくわからない。&lt;br /&gt;&lt;br /&gt;僕はツールに興味があって、コンパイラとかエディタとかIDEとか、そういうものが生産性を高めてくれることを重要だと思っている。言語を切り替えるとツールも切り替えることになってしまうので、新しい言語は5倍くらいの表現力がないと、ツールの変更で損なわれるものを埋められないんじゃないかと思う。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Dylan：&lt;/span&gt;&lt;br /&gt;僕はviだから大丈夫！&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Gregor：&lt;/span&gt;&lt;br /&gt;私はNotepadだ！&lt;br /&gt;&lt;br /&gt;Language Workbenchはこういうのをうめてくれるのかもしれないが、うまく動くようになるまでにはもう少しかかりそうだ。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Randy：&lt;/span&gt;&lt;br /&gt;.NET開発者とかJava開発者とかいわなくなったのが、最近の状況を表している。1つのシステムを構築するにも、色んな言語やツールを使わなければならなくなっているということだ。Scalaについて言えば、Scalaの専門家とまではいかなくても、色々知ってるジェネラリストが必要。どの分野にどの言語を使えばいいか、判断できる人が必要だろう。そこで、より深く専門的な知識が必要になれば、言語の専門家が必要にもなってくるだろう。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Gregor：&lt;/span&gt;&lt;br /&gt;賛成でもあるし反対でもある。どういうアイデアを転用できるかを知るのが大事。デザインコンセプトを知るということ。&lt;br /&gt;ところが実際に、言語を使いこなす方法をツール・パターン・ベストプラクティスを含めて理解するまでには時間がかかる。Javaで我々は10年かかった。&lt;br /&gt;あまりに多くの言語があふれると、開発者は大変になる。現代では、最大の制約は人間の学習能力になっている。現段階で存在する大量の言語は、既に一人の人間が理解できる範囲をこえている。色々な言語やツールに触れていると、深く使いこなすことができなくなるかもしれない。これはもしかしたら問題にならないかもしれないが、考える必要はあると思う。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Dylan：&lt;/span&gt;&lt;br /&gt;ツールがやってくれるんじゃね？&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Others：&lt;/span&gt;&lt;br /&gt;ツールを選ぶためのツールがいるのか！&lt;br /&gt;そうなったらコンサルタントいらないね！&lt;br /&gt;ハハハハ！&lt;br /&gt;&lt;br /&gt;[次の質問。]&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;質問者：&lt;/span&gt;&lt;br /&gt;言語・アーキテクチャやプロセスに色んな変化がおきているが、テストについてはあまり変化がないように思える。テストの変化についてはどう考えている？また、どうなっていくべき？&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Dylan：&lt;/span&gt;&lt;br /&gt;テスト用のクラウドサービスやブラウザモックもある。社内でできないようなテストを行うサービスもできてきている。AjaxのテストにはSeleniumやWindmilもある。テストツールはいつも少し遅れて出てくるが、だいぶ追いついてきた。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Gregor：&lt;/span&gt;&lt;br /&gt;テストには2つの大きな目的がある。正しいかどうかを確認するためのテストと、開発の一環としてのテストだ。開発の一環としてのテストには、TDDやBDDなどの革新がある。&lt;br /&gt;これは、ツールの問題ではなく、使い方、使いこなし方の問題だ。JUnitが出てから8年たつが、このような新しい使い方が出てきている。&lt;br /&gt;&lt;br /&gt;もう1つ、ランタイムへのシフトがあげられる。ランタイムで設定される様々なプロパティや環境情報をテストする必要がある。&lt;br /&gt;&lt;br /&gt;職業としてのテストの輪郭はぼやけてきている。これは、アーキテクトなどのほかの職業にも言える。テスタの役割も変化してきていて、自動化できないところをやることが重要になっている。テストはかなり自動化されてきているので。実験的なテストなど、自動化できないテストをうまくできることが強みになってくるだろう。&lt;br /&gt;&lt;br /&gt;[次の質問。]&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;質問者：&lt;/span&gt;&lt;br /&gt;典型的な業務（会計とかなんとかとか）の用語がほとんど出てこなかったが、このような業務に関わる人はあまりいないのだろうか？最初の話にも少しあったが、業務側と技術側がわかれているような気がするがこれはいいことか？エンジニアであれば、どちらもできるべきじゃないのか？&lt;br /&gt;こういう問題はあると思うか？あるとしたら、どういう風に解決しているか？&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Henrik：&lt;/span&gt;&lt;br /&gt;これは、問題だと思う。しかし、リーンやScrumを使うことでビジネス側とつながってきているので、どんどん解決に向かっている。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Gregor：&lt;/span&gt;&lt;br /&gt;Fowlerはもう語り尽くしたから言わなかったんだと思うよ :-)&lt;br /&gt;問題はあると思う。これに対する解決策としては、自分はテスティングをあげるようにしている。仕様上の問題点などは、テストとして起こして、みんながそれを見ることができるようにしている。今の仕事上、業務というとHTTPヘッダとかそういうテクニカルな話になってしまうんだけど。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Randy：&lt;/span&gt;&lt;br /&gt;eBayの経験からすると、一番うまくいったプロジェクトは、ビジネスチームと技術チームがタッグを組んだもの。これらの間の乖離がひどいものは成功していない。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Dylan：&lt;/span&gt;&lt;br /&gt;私もCEOをしているのだが、ビジネス的なバックグラウンドを持つのはいいこと。なぜそういう要件が必要になるのかがわかるようになるし、自分たちのしていることがどのような収益を生むのか、なども理解できるようになる。事業側の立場にたって考えることは必要。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Gregor：&lt;/span&gt;&lt;br /&gt;極論すると、ビジネスユーザーがVBマクロを書いたときに、一番うまくいっていた。マクロのスクリプティングは強力だ。&lt;br /&gt;しかし、（例えばVBが新しいバージョンになった時などに）これらをどうやって拡張するのか、再利用するのか、といった問題は解決されていない。&lt;br /&gt;&lt;br /&gt;[このあたりで時間切れ。ありがとうございましたー。]&lt;br /&gt;&lt;br /&gt;目次：&lt;br /&gt;&lt;a href="http://hibituredure.blogspot.com/2009/04/qcon-tokyo-2009.html"&gt;QCon Tokyo 2009に行ってきた&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-4038378019440791893?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/4038378019440791893/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=4038378019440791893&amp;isPopup=true' title='6 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/4038378019440791893'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/4038378019440791893'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2009/04/blog-post.html' title='パネル・ディスカッション「エンタープライズ・ソフトウェア開発の動向」'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-3615089747120476624</id><published>2009-04-10T21:47:00.019+09:00</published><updated>2009-04-25T09:08:10.460+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='セミナー/勉強会'/><category scheme='http://www.blogger.com/atom/ns#' term='雑記'/><category scheme='http://www.blogger.com/atom/ns#' term='report'/><title type='text'>QCon Tokyo 2009に行ってきた</title><content type='html'>&lt;a href="http://qcontokyo.com/"&gt;QCon Tokyo 2009&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;QCon Tokyoは2日間開催で、それぞれの日ごとに3つのトラック（{1日目 =&gt; [Architecture, RIA, Ruby], 2日目 =&gt; [Cloud Computing/SOA, Agile, Case Study]}）が設定されていて、トラックごとにセッションが4つ設定されている。また、各トラックに属する個別セッションとは別に、日ごとに2つのジェネラルセッションが設定されていて、大御所たちが話すことになっている。&lt;br /&gt;&lt;br /&gt;QConでは、良いと思ったセッションに緑、普通と思ったセッションに黄、いまいちと思ったセッションに赤のカードを入れることになっているんだけど、これに習って自分が出席したセッションを評価すると、こんな感じになる。&lt;br /&gt;&lt;br /&gt;[緑（よかった！）]&lt;br /&gt;&lt;ul&gt;&lt;li&gt;アーキテクトの審美眼 by 萩原正義&lt;/li&gt;&lt;li&gt;General Session 1 クラウドの技術的な特徴について by 丸山不二夫&lt;/li&gt;&lt;li&gt;クラウドのプログラミング − プラットフォームとしてのインターネット by Gregor Hohpe&lt;/li&gt;&lt;li&gt;大規模ウェブサイトのベストプラクティス −eBayでの事例− by Randy Shoup&lt;/li&gt;&lt;li&gt;パネル・ディスカッション「エンタープライズ・ソフトウェア開発の動向」 by Floyd Marinescu&lt;/li&gt;&lt;/ul&gt;[黄色（ふつう）]&lt;br /&gt;&lt;ul&gt;&lt;li&gt;General Session 1 ドメイン固有言語 −その役割− by Martin Fowler&lt;/li&gt;&lt;li&gt;General Session 2 ビューティフルコード by まつもとゆきひろ&lt;/li&gt;&lt;li&gt;Open Webの進展とその今後 by Dylan Schiemann&lt;/li&gt;&lt;li&gt;実世界のRuby −3年間の経験から− by Martin Fowler&lt;/li&gt;&lt;li&gt;QCon Tokyo Conference Party&lt;/li&gt;&lt;li&gt;General Session 2 Spring Today and Tomorrow by Rod Johnson&lt;/li&gt;&lt;li&gt;アジャイル開発を始めるために −実例で得られた知見から− by Henrik Kniberg&lt;/li&gt;&lt;/ul&gt;[赤（いまいち）]&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Amazon Web Services in Action by Jeff Barr&lt;/li&gt;&lt;/ul&gt;もともとはRod JohnsonとMartin Fowler目当てで行ったようなものなんだけど、Rod Johnsonの話はちょっとマーケティング色が強すぎて微妙だったので黄色。Martin Fowlerのジェネラルセッションは、既存の資料（DSL WIPやThought Works Anthology）で知っていた話が多かった。Rubyのセッションは興味深くはあったものの、Martin Fowlerの話というより、Thought WorksでRubyに取り組んでいる人たちの話をまとめた内容になっていて、Fowler自身の言葉があまり聞けなかったのが残念。&lt;br /&gt;&lt;br /&gt;上記のセッションを聞いてみて自分が持った感想は、「世の中や技術は複雑さを増し続けていて、単一の言語・製品・モデル・パラダイムだけでは（少なくとも効率的には）対応できない」ということ。Rod Johnsonは「JavaEEのようにすべてを包含しようとするのではなく、リーンな（特定の目的のために存在し、シンプルで無駄がない）仕様や製品を、適した場所に使っていくこと」を提唱していたし、Martin Fowlerは「特定のドメインに特化した言語を使い、それを場所に応じて使い分けることで、効率的にシステムを記述/開発できる」と考えているようだ。丸山先生やeBayのRandy Shoup、GoogleのGregor HorhpeはACIDとは異なる新たなトランザクションモデル（丸山先生はBASEモデルと呼んでいる）を提示して、ACIDトランザクション一色の既存のシステム開発の再考を促している。MSの萩原さんは、まんまマルチパラダイムへの流れを強調していたしな。&lt;br /&gt;Rubyは、DSLを記述するための高い表現力を持つため、内部DSL向けのホスト言語として重要な位置を占めることになる。&lt;br /&gt;# あれ…アジャイルは？^^;&lt;br /&gt;&lt;br /&gt;個別セッションのまとめは、内容的に興味が持てたものでかつ、かけそうなものを選んでちょこちょこ書いていく予定。たぶんInfoQの方にビデオ出ると思うし。とりあえずは、パネルディスカッションあたりから起こしていく予定。&lt;br /&gt;&lt;br /&gt;レポート：&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://hibituredure.blogspot.com/2009/04/cap-theorem.html"&gt;CAP Theorem（定理）&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://hibituredure.blogspot.com/2009/04/blog-post_13.html"&gt;ビューティフルコード&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://hibituredure.blogspot.com/2009/04/blog-post_18.html"&gt;アーキテクトの審美眼&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://hibituredure.blogspot.com/2009/04/blog-post_12.html"&gt;クラウドの技術的な特徴について&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://hibituredure.blogspot.com/2009/04/spring-in-changing-world.html"&gt;Spring in a Changing World&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://hibituredure.blogspot.com/2009/04/programming-cloud-internet-as-platform.html"&gt;Programming the Cloud -the Internet as Platform-&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://hibituredure.blogspot.com/2009/04/ebay.html"&gt;大規模ウェブサイトのベストプラクティス－eBayでの事例－&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://hibituredure.blogspot.com/2009/04/blog-post.html"&gt;パネル・ディスカッション「エンタープライズ・ソフトウェア開発の動向」&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;追記：&lt;br /&gt;発表資料公開されました。&lt;br /&gt;&lt;a href="http://qcontokyo.com/tokyo-2009/schedule.html"&gt;http://qcontokyo.com/tokyo-2009/schedule.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-3615089747120476624?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/3615089747120476624/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=3615089747120476624&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/3615089747120476624'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/3615089747120476624'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2009/04/qcon-tokyo-2009.html' title='QCon Tokyo 2009に行ってきた'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-7025514191003941827</id><published>2009-03-21T13:22:00.008+09:00</published><updated>2009-04-17T20:22:51.299+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='セミナー/勉強会'/><category scheme='http://www.blogger.com/atom/ns#' term='数学'/><category scheme='http://www.blogger.com/atom/ns#' term='コンピュータ科学'/><category scheme='http://www.blogger.com/atom/ns#' term='report'/><title type='text'>技術者／プログラマのためのラムダ計算、論理、圏 第3回に行ってきた</title><content type='html'>実は第2回にも行っていたんだけど内容をまったく咀嚼できず、そのうちやろうと思っているうちに第3回が開催されてしまった ^^;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;第2回 ラムダ計算と停止性問題&lt;/span&gt;&lt;br /&gt;第2回は、主にラムダ計算について。前回の復習からはじまって、回路図のような絵を交えながらラムダ抽象化につなげていき、最後はJavaScriptのようなCのような疑似コードを使って、チューリングマシンの停止性問題を背理法で証明して終わった（と思う）。詳しくは、檜山さんのBlogに書いてあるので、そちらを見た方が良いと思う。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://d.hatena.ne.jp/m-hiyama/20090221/1235181010"&gt;セミナー資料&lt;/a&gt;&lt;br /&gt;&lt;a href="http://d.hatena.ne.jp/m-hiyama/20090225/1235521827"&gt;紙芝居：ラムダ抽象&lt;/a&gt;&lt;br /&gt;&lt;a href="http://d.hatena.ne.jp/m-hiyama/20090221/1235192629"&gt;セミナー非参加者にもわかるリアルワールド向けラムダ計算&lt;/a&gt;&lt;br /&gt;&lt;a href="http://d.hatena.ne.jp/m-hiyama/20090220/1235094341"&gt;なぜ停止性について話したのか？&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;第3回 自然演繹と型付きラムダ計算、カリー／ハワード対応&lt;/span&gt;&lt;br /&gt;第3回は、カリー・ハワード対応についての感覚的な理解がゴール。第2回とはうってかわって論理を中心に話をすすめていき、論理でやっていることが最終的にラムダ計算に対応することを感覚的に理解することで、カリー・ハワード対応を感じるのが目的、という感じ。こちらも、檜山さんのところに、他の参加者さんのまとめへのリンクを含めてきちんと色々書いてあるのでまとめは書きません、というか書けません！&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.chimaira.org/archive/slide090319.pptx"&gt;セミナ資料&lt;/a&gt;&lt;br /&gt;&lt;a href="http://d.hatena.ne.jp/m-hiyama/20090321/1237627082"&gt;カリー／ハワード（Curry-Howard）の対応を知らない子供達および大人達へ&lt;/a&gt;&lt;br /&gt;&lt;a href="http://d.hatena.ne.jp/m-hiyama-memo/20090228/1235809695"&gt;演繹系の話題と演習&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;もともと、「素数の音楽」「暗号解読」「論理学入門」あたりの書籍や、TM（T字形ER）のセミナでの疑問（数理論理学まわり）解消のためにちょこちょこ調べていたこともあって、今回の話の大半は馴染みがあった。とはいえ、雰囲気つかむことを重視してたので、導入規則や除去規則についてあまりよくわかっていなかったのだが、今回具体例をもとに理解できたのはとても良かった。&lt;br /&gt;セミナの内容の本筋としては「計算と論理は以下のように対応する」&lt;br /&gt;&lt;br /&gt;&lt;table border="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;論理&lt;/th&gt;&lt;th&gt;算術&lt;/th&gt;&lt;/tr&gt;  &lt;tr&gt;&lt;td&gt; 演繹系  &lt;/td&gt;&lt;td&gt; 算術回路キット  &lt;/td&gt;&lt;/tr&gt;  &lt;tr&gt;&lt;td&gt;  推論 &lt;/td&gt;&lt;td&gt; 基本演算  &lt;/td&gt;&lt;/tr&gt;  &lt;tr&gt;&lt;td&gt; 証明図  &lt;/td&gt;&lt;td&gt; 計算図  &lt;/td&gt;&lt;/tr&gt;  &lt;tr&gt;&lt;td&gt; 演繹系の証明図  &lt;/td&gt;&lt;td&gt; 算術回路キットの計算図  &lt;/td&gt;&lt;/tr&gt;  &lt;tr&gt;&lt;td&gt;  証明可能 &lt;/td&gt;&lt;td&gt; 計算可能  &lt;/td&gt;&lt;/tr&gt;  &lt;tr&gt;&lt;td&gt; derived rule  &lt;/td&gt;&lt;td&gt; 計算のマクロ  &lt;/td&gt;&lt;/tr&gt;  &lt;tr&gt;&lt;td&gt; 公理  &lt;/td&gt;&lt;td&gt; 最初から使える定数  &lt;/td&gt;&lt;/tr&gt;  &lt;tr&gt;&lt;td&gt; 定理  &lt;/td&gt;&lt;td&gt; 計算済み定数  &lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;でFAな感じなんですが、話の中でちらちら出てくる用語や、自分が既に知っていることとの関係がよくわからなくてもやもやしている。というか、聞けば聞くほど疑問が増えるという状態...&lt;br /&gt;&lt;ul&gt;&lt;li&gt;檜山さん的アプローチでのラムダとは少しは仲良くなった気がするが、一般的（形式的というか記号的というか）なラムダ計算についてイマイチわかっていない感&lt;/li&gt;&lt;li&gt;カリー／ハワード対応が何を意味しているのか（この理解が何につながっていくのか）&lt;/li&gt;&lt;li&gt;自然演繹以外の演繹系と、型付ラムダ計算以外の計算も対応するのか？&lt;/li&gt;&lt;li&gt;フォーマルメソッドや自動証明との関係は？&lt;/li&gt;&lt;li&gt;プロセス論理との関係は？&lt;/li&gt;&lt;li&gt;型推論との関係は？&lt;/li&gt;&lt;li&gt;結局、絵算というのは何がエキサイティングなんでしょう？&lt;/li&gt;&lt;/ul&gt;檜山さんのエントリによると、話題同士の関係についてこれからいくつかエントリをあげつつ説明してくださるようなので、それらのエントリをながめつつ、自分なりに理解を深める過程を書いていこうと思う。ううむ...文系は土台からしてしょぼいからつらいなぁ...。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;何か関係ありそうなリンク&lt;/span&gt;&lt;br /&gt;&lt;a href="http://itpro.nikkeibp.co.jp/article/COLUMN/20070909/281498/?P=1&amp;amp;ST=develop"&gt;型＝命題、プログラム＝証明&lt;/a&gt;&lt;br /&gt;　Haskellを例に、型推論との関係について説明してくれそう。&lt;br /&gt;&lt;a href="http://d.hatena.ne.jp/nobsun/20070915/p2"&gt;Curry-Howard対応を知らないこども達&lt;/a&gt;&lt;br /&gt;　サーセン（笑）&lt;br /&gt;&lt;a href="http://www.kmonos.net/wlog/61.html#_0538060508"&gt;Curry-Howard Isomorphism&lt;/a&gt;&lt;br /&gt;　ざっと読んだけど、概要を把握するにはとても良さそう。&lt;br /&gt;&lt;a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.17.7385"&gt;CiteSeer : Curry-Howard Isomorphism&lt;/a&gt;&lt;br /&gt;　カリー／ハワード同型対応についてきちんと書いてあるらしい論文。&lt;br /&gt;&lt;a href="http://ja.wikipedia.org/wiki/%E8%87%AA%E7%84%B6%E6%BC%94%E7%B9%B9"&gt;自然演繹-Wikipedia&lt;/a&gt;&lt;br /&gt;　型理論や線形論理との関係も書いてある。&lt;br /&gt;&lt;a href="http://ja.wikipedia.org/wiki/%E3%83%A9%E3%83%A0%E3%83%80%E8%A8%88%E7%AE%97"&gt;ラムダ計算-Wikipedia&lt;/a&gt;&lt;br /&gt;　ここに書いてあることが「そりゃそうだよねぇ」と言えるくらいにはなりたい。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-7025514191003941827?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/7025514191003941827/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=7025514191003941827&amp;isPopup=true' title='1 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/7025514191003941827'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/7025514191003941827'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2009/03/3.html' title='技術者／プログラマのためのラムダ計算、論理、圏 第3回に行ってきた'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-3081642254092197123</id><published>2009-03-18T23:01:00.007+09:00</published><updated>2009-04-13T02:27:51.670+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='雑記'/><category scheme='http://www.blogger.com/atom/ns#' term='book'/><title type='text'>自分のブランディングを考える inspired by 「抜擢される人の人脈力」</title><content type='html'>同僚に貸してもらって「抜擢される人の人脈力」という本を読んだ。これは、人脈をつちかっていくことで自分自身も成長し、トータルでの仕事の能力も上げ、最終的には代替不可能な人材になって自由な働き方を手に入れよう、てな本。目指すところには非常に共感した。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;人脈を広げるための5ステップ&lt;/span&gt;&lt;br /&gt;この本では、人脈を広げるためのステップを、以下の5段階で定義している。&lt;br /&gt;&lt;ol&gt;&lt;li&gt;自分にタグをつける&lt;/li&gt;&lt;li&gt;コンテンツを作る&lt;/li&gt;&lt;li&gt;仲間を広げる&lt;/li&gt;&lt;li&gt;自分情報を流通させる&lt;/li&gt;&lt;li&gt;チャンスを積極的に取りにいく&lt;/li&gt;&lt;/ol&gt;2番目以降は考えるだけではダメなのでおいおいやっていくとして、まずは自分にタグをつけるとしたらどうなるのかを現時点で整理して、ブログの紹介文にでもいれとこうかと思う。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;自分へのタグづけ&lt;/span&gt;&lt;br /&gt;さて、タグをつけるには、以下の3つの観点から考えると良い、とアドバイスされている。&lt;br /&gt;&lt;ol&gt;&lt;li&gt;将来、どんな仕事をしたいか（Will）&lt;/li&gt;&lt;li&gt;自分にできることは、何か（Skill）&lt;/li&gt;&lt;li&gt;相手にどんなメリットをもたらすか（Value）&lt;/li&gt;&lt;/ol&gt;はい、では1から。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Will/将来、どんな仕事をしたいか&lt;/span&gt;&lt;br /&gt;第二の就職活動のような内省が必要になる部分だろうと思うが、自分は日常の会話やふとした反応から、自分にいくつかの指向があるのを感じていた。まず、最も根底にあるのは...&lt;br /&gt;「&lt;span style="font-weight: bold;"&gt;すばらしい仲間と最高のシステムを作る&lt;/span&gt;」&lt;br /&gt;ということ。ここでの「すばらしい」が意味するのは、必ずしもすばらしいスキルを既にもっている、ということではない。それは、志を同じくしていて、そのシステムをより良いものにするのに真剣に心を砕き、全力を注いでくれる、という意味だ。そして、そんなシステムを作るために、日頃から鍛錬を惜しまない、という意味でもある。だから、結果として高い能力はついてきているはずだ、という期待もある。もちろん、自分がその仲間になるのであれば、自分も同じようにあらねばならないのは当然のことだ。...できてるかどうかあやしいけど...。&lt;br /&gt;&lt;br /&gt;簡潔にタグにするとすると、どうなるんだろう？「目指せドリームチーム入り」？チームメディカルドラゴンみたいな感じでしょうか。&lt;br /&gt;&lt;br /&gt;さらにもう1つ、それは...&lt;br /&gt;「&lt;span style="font-weight: bold;"&gt;アカデミックな研究成果で現場を進歩させる&lt;/span&gt;」&lt;br /&gt;ということ。自分はもともと経済学部でミクロ経済学を専門にしていたんだけど、色んな仮説をたてて市場をモデル化し、現実の経済を分析しようとしても、そのモデルがどの程度現実を反映しているのかを知ることは非常に困難であり、現実世界に寄与する方法があまり具体的にイメージできなかった。この現実世界との乖離度合いに我慢ならなかったために、企業に入社したようなものだ。&lt;br /&gt;&lt;br /&gt;元々自分はアカデミックな研究成果（というより、先人が払ってきた膨大な労力）に対して敬意を持っているのだが、往々にして現場はアカデミックな研究成果を現実的でないと馬鹿にしていたり、そもそも理解するどころか、どのような成果があるのかを確認すらしていないことが多い。&lt;br /&gt;彼ら（我ら）が我流で考えだす改善策やソリューションにも一定の意味があることは多いが、たいていは研究成果の出来の悪い焼き直しであったり、よくわからない局所最適解であることが多い。今は昔とは逆に、アカデミックな研究成果を現場に取り入れることの難しさにもがいているわけだが、大学から現場に口を出すよりも、現場から成果をひっぱってくる方が遥かに簡単だと感じている。自分は研究と現場をうまくつなぐような役割を果たしたい。&lt;br /&gt;こういうの、なんていうんだろう？「&lt;span style="font-weight: bold;"&gt;現場の学者&lt;/span&gt;」のようになりたいのだ。&lt;br /&gt;&lt;br /&gt;最後にもう1つ、それは...&lt;br /&gt;「&lt;span style="font-weight: bold;"&gt;才能を持った人材が比較的自由に仲間や仕事を選べる、職人ギルドのような組織を作り、個人の力を最大限に解放できるようにする&lt;/span&gt;」&lt;br /&gt;なんか長いな。これはもう、そのまま。特に動機になっているのは、企業内では才能を持った開発者が自己の能力を最大限生かして働くことが非常に難しい、ということ。さらに、生かせたとしても、それに対してあまり高い報酬をもらっていないケースをよく見る。逆に、大した寄与がない人間が非常に高額の報酬をもらっているのもよく見る。自由もなく報酬も少なく、評価もあまりされない。仮に自分を成長させられたとしても、居場所がなさそうな世界なんてぶっつぶしてやりたくもなるよね？これを実現するには、周囲が才能や能力を認知できる状態にしなくてはならないので、みんな一定の能力が求められることになるんだけど。&lt;br /&gt;タグづけすると...「&lt;span style="font-weight: bold;"&gt;才能を縛らない現場を作る&lt;/span&gt;」かな。&lt;br /&gt;&lt;br /&gt;Willはこんなものかな。次、2。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Skill/自分にできることは何か&lt;/span&gt;&lt;br /&gt;自分にできること...&lt;br /&gt;「小規模から超大規模まで、10近くの様々な規模の業務システムでソフトウェアアーキテクチャ設計に携わっている。そのうちの2つの中規模システムは主たる設計者として参加している。」&lt;br /&gt;「業務アプリケーションから基盤ソフトウェア、開発支援ツール類までの設計・実装をしている。」&lt;br /&gt;「業務システム開発の技術リスク監査ができる。」&lt;br /&gt;「業務モデリングもある程度できる。」&lt;br /&gt;「Domain-Driven Designをわりとよく理解している。」&lt;br /&gt;かなぁ。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Value/相手にどんなメリットをもたらすか&lt;/span&gt;&lt;br /&gt;ううむ、難しくなってくるな...&lt;br /&gt;「どんな規模のシステムでも、ソフトウェアアーキテクチャ設計できますよ」&lt;br /&gt;「インフラだけでなく業務もある程度わかるので、ソフトウェア全体の最適化の役に立てますよ」&lt;br /&gt;「業務モデリングによる業務最適化も考慮したシステム開発ができますよ」&lt;br /&gt;「DDDアプローチによる、柔軟性の高いシステム構築に対応できますよ」&lt;br /&gt;こんな感じだろうか。&lt;br /&gt;&lt;br /&gt;最後に、コンテンツを考えるうえでのヒントをメモって終わりにする。&lt;br /&gt;&lt;ul&gt;&lt;li&gt;能力&lt;/li&gt;&lt;li&gt;実績&lt;/li&gt;&lt;li&gt;意欲&lt;/li&gt;&lt;/ul&gt;以上の3つを把握する。実績を積むためには...&lt;br /&gt;&lt;ul&gt;&lt;li&gt;脳に汗をかくくらい頭を使う&lt;/li&gt;&lt;li&gt;ビジネス上の修羅場を経験する&lt;/li&gt;&lt;li&gt;自分の名前で仕事をする&lt;/li&gt;&lt;/ul&gt;以上を心がける。さって、がんばるぞー。とりあえず明日、檜山さんの主催する、「技術者／プログラマのためのラムダ計算、論理、圏」最終回にいってきまっす！&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-3081642254092197123?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/3081642254092197123/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=3081642254092197123&amp;isPopup=true' title='1 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/3081642254092197123'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/3081642254092197123'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2009/03/inspired-by.html' title='自分のブランディングを考える inspired by 「抜擢される人の人脈力」'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-6661261475493001733</id><published>2009-02-08T12:44:00.003+09:00</published><updated>2009-10-02T13:56:56.120+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='ddd'/><category scheme='http://www.blogger.com/atom/ns#' term='system'/><title type='text'>DDDのメモサイトを作ってみた</title><content type='html'>&lt;a href="http://sites.google.com/site/dddmemo/Home"&gt;DDD-memo&lt;/a&gt;&lt;br /&gt;EvansのDDD本やNilssonのドメイン駆動、DDDの公式フォーラムの内容から大事そうなものや興味のある内容を選んでメモっていくサイトとして作ってみた。&lt;br /&gt;とはいえ、本読んだりForum読みながらとりあえずレベルで殴り書きしてることが多いから、読み物としては微妙なんですが。Wikipediaみたいに、記事ごとに完結させていけたらいいんだけど、なかなか難しい。そのうち、記事ごとにそれなりに内容がまとまった状態にしていきたい。&lt;br /&gt;&lt;br /&gt;Google Siteに作ったんだけど、Google SiteってRSS出してないのね…。どうした、Google様らしくないなぁ。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-6661261475493001733?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/6661261475493001733/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=6661261475493001733&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/6661261475493001733'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/6661261475493001733'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2009/02/ddd.html' title='DDDのメモサイトを作ってみた'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-8632387888071070381</id><published>2009-01-13T11:06:00.003+09:00</published><updated>2009-04-13T02:38:28.642+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='雑記'/><title type='text'>赤坂BLITZ</title><content type='html'>&lt;div&gt;奥さんと赤坂BLITZに行ってきた。改装後ははじめてのBLITZ。ライブのパフォーマーは、ミリオンヒットを出した経験もあるものの、最近はそんなに売れていないミュージシャン。ちなみに自分はそのミュージシャンをそんなに好きではないので、行く前はいつも気がすすまないのだけど、実際行ってみるとライブというのはやっぱり良いものだと思って帰ってくる。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;このライブ、赤坂BLITZでやるにも関わらず、スタンディングではなく席が用意されていた。なので、満席にも関わらず600人弱しか入っていない。&lt;/div&gt;&lt;div&gt;チケットは一枚あたり6300円なので、チケット売り上げはせいぜい400万円。企画立てて、ハコ押さえて、ミュージシャン集めて、リハやって、当日スタッフ雇って、演出決めて、機材用意して、ステージセッティングして…などなど考えると、400万というのは非常に心もとない数字に思える。チケット業者にも何パーセントか流れてるだろうし。相場をまったく知らないんだけど、他のライブハウスの相場から推測するに、ハコ代だけで200万くらいいってそうだし。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;ライブは基本的に、チケットでは収支プラマイゼロくらいで、物販で稼ぐと聞いたことがあるけど、物販顧客の母集団が600人じゃあ売り上げもたかがしれている。客単価が2000円で300人買ったとしても60万。実際ここまで買ってるかどうか。となると、本当に収支トントンくらいなのだろうか。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;それなりに有名なミュージシャンがそれなりに有名な場所でやってるのに、動くお金の量があまりに少ないことに驚いてしまった。TVアニメのDVDの初動枚数が、ベスト10でも5000枚くらいなのを知ったときも驚いたんだけど。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;ピアプロ/ニコニコで活動しているジミーサムPことOneRoomという人がいて、最近気に入ってずっと聴いている。最近、既発表曲のiTunesでの配信（タイトルは「Resound」）がはじまり、アルバムランキングで最高3位に入っているのを知った。アルバムで買えば900円で、ピアプロにいけば無料でMP3も手に入る。彼がライブすることはないだろうし、一般に広く知られることもないだろうけど、自分は金を払って買うCDよりもこっちの方を気に入って聴いている。音質が良さそうならあらためてiTunesで買うかもしれない。iTunes plusだったし。音楽活動に直に関わっている感じもあり、とにかく距離が近いのも良い。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;とりとめがなく、まとまってもいないんだけど…若い人を中心に文字情報で起きてること、ひょっとして音楽でも起きる…のか？&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-8632387888071070381?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/8632387888071070381/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=8632387888071070381&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/8632387888071070381'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/8632387888071070381'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2009/01/blitz.html' title='赤坂BLITZ'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-1162850801292622399</id><published>2008-12-22T15:57:00.006+09:00</published><updated>2009-04-13T02:27:51.671+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='雑記'/><title type='text'>KPT2008</title><content type='html'>&lt;div&gt;DDD勉強会でもやったんだけど、口頭アドリブでグダグダになってしまったので改めて整理。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;■KEEP&lt;/div&gt;&lt;div&gt; * 英語に慣れる&lt;/div&gt;&lt;div&gt;   TOEIC 800点取れたのは上出来&lt;/div&gt;&lt;div&gt;   フィードや書籍、Podcastも英語のものが増えた&lt;/div&gt;&lt;div&gt; * 交流を増やす&lt;/div&gt;&lt;div&gt;   DDD読書会で結構知り合い増えたと思う&lt;/div&gt;&lt;div&gt;   てか今までが少なすぎ&lt;/div&gt;&lt;div&gt; * 体系的に勉強する&lt;/div&gt;&lt;div&gt;   情処資格2つとも受かったのはまぁ良かった&lt;/div&gt;&lt;div&gt;   OOとかDDDとか結構真面目に勉強できた&lt;/div&gt;&lt;div&gt;   集合を中心に、数理論理とか数学系を多少勉強できた&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;■PROBLEM&lt;/div&gt;&lt;div&gt; * 趣味が増えてない、ってか挫折&lt;/div&gt;&lt;div&gt;   + ベースどうなった&lt;/div&gt;&lt;div&gt;   + EDIROL買ったのに全然使ってない&lt;/div&gt;&lt;div&gt;   + あんまり絵がうまくなってない&lt;/div&gt;&lt;div&gt;   + 特に人物うまく描けない 模写は結構得意だけど空想で色々描けない&lt;/div&gt;&lt;div&gt; * 運動できてない&lt;/div&gt;&lt;div&gt;   + 何ができてないかも話せなくらい何もやってない&lt;/div&gt;&lt;div&gt; * 料理できてない&lt;/div&gt;&lt;div&gt;   + レパートリー増えてなさすぎ&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;■TRY&lt;/div&gt;&lt;div&gt; * 英語により慣れる&lt;/div&gt;&lt;div&gt;   + 今年はTOEIC 900点を目指したい&lt;/div&gt;&lt;div&gt;   + オリジナルが英語の情報は全部英語で読む&lt;/div&gt;&lt;div&gt; * 交流をより増やす&lt;/div&gt;&lt;div&gt;   + OSSプロジェクトに参加する or 書籍出版に関わる&lt;/div&gt;&lt;div&gt;   + 何という無理くささ&lt;/div&gt;&lt;div&gt; * 体系的な勉強&lt;/div&gt;&lt;div&gt;   + ドメイン工学系&lt;/div&gt;&lt;div&gt;     GenarativeProgramming =&gt; Multiparadigm Design&lt;/div&gt;&lt;div&gt;   + ビジネスモデリング系&lt;/div&gt;&lt;div&gt;     Ericsson-Penker =&gt; Analysis Patterns =&gt; Data Moedl Patterns&lt;/div&gt;&lt;div&gt;   + DSL系&lt;/div&gt;&lt;div&gt;     Fowler DSL Books WIP =&gt; Meta Programming System&lt;/div&gt;&lt;div&gt;   + ビジネス系&lt;/div&gt;&lt;div&gt;     会計～中小企業診断士を趣味的に&lt;/div&gt;&lt;div&gt; * 趣味&lt;/div&gt;&lt;div&gt;   + ベース楽しく弾く&lt;/div&gt;&lt;div&gt;   + できればアマ志向でバンド組んでスタジオで騒ぐ&lt;/div&gt;&lt;div&gt;   + かっくいいのかいてpixivとかに投稿してみたい&lt;/div&gt;&lt;div&gt;   + もっかい将棋はじめてもいいかなぁ&lt;/div&gt;&lt;div&gt; * 料理&lt;/div&gt;&lt;div&gt;   + とりあえずペペロンチーノで乳化あたりから&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;…こんなもんかなぁ。なんか、多すぎ？&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-1162850801292622399?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/1162850801292622399/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=1162850801292622399&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/1162850801292622399'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/1162850801292622399'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2008/12/kpt2008.html' title='KPT2008'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-7443873617436409643</id><published>2008-12-16T14:29:00.004+09:00</published><updated>2009-04-13T02:27:51.672+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='雑記'/><title type='text'>人に教えるということ</title><content type='html'>&lt;blockquote&gt;「全部俺のモンだ孤独も苦痛も不安も後悔ももったいなくってさ、テメエなんかにやれるかよ！！」－PLANETES ハチの台詞&lt;/blockquote&gt;&lt;br /&gt;昔、自分がまだ学生だった頃に、色んなことをアドバイスしてくれる大人がいた。彼らの知っていること、経験してきたこと、そしてこうすべきであるということを（迷惑にも）丁寧に教えてくれるのだ。&lt;br /&gt;自分はその人（たち）に対して、ずっと思っていた。俺が本来経験するはずだったものを取っていかないでくれ、って。&lt;br /&gt;&lt;br /&gt;だからなのか、元からそうなのかはわからないけど、自分は人に何か結果を教える気が起きない。理屈を後で教えるとしても、問題にぶちあたり、悩み、考え、到達し、評価し、羞恥し、学ぶこととは比べ物にならないと思えてしまうから。たどり着いた結果だけでなく、その過程自体に価値があると思うから。&lt;br /&gt;&lt;br /&gt;極端な意見であることはわかってるし、TPOもあると思う。一度知ってしまった後でも同じことができるのに、見くびってるのかもしれないとも思う。君みたいな人ばかりじゃないとか、やる気なさすぎとか言われてよく怒られもする ^^;&lt;br /&gt;&lt;br /&gt;でも、これが人に教えることについての基本的な自分の考えなんだよなぁ。これはずっと変わってない。これからも変わらない気がする。もちろん人によって変えはするけど、理想はいつもここに持っている。少し前に、人を教えるにはどうすればいいか飲みながら話したことを思い出して。&lt;br /&gt;&lt;br /&gt;ハチほど熱くもわがままでもないと思うけど、気持ちはよくわかるよ、うん。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-7443873617436409643?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/7443873617436409643/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=7443873617436409643&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/7443873617436409643'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/7443873617436409643'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2008/12/blog-post.html' title='人に教えるということ'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-6577232408794773477</id><published>2008-12-04T11:58:00.002+09:00</published><updated>2009-04-13T15:43:47.701+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='セミナー/勉強会'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Scala勉強会の資料</title><content type='html'>自社でScala勉強会やりました。勉強しながらなので間違ってるところもあると思いますが、とりあえず公開してしまいます。&lt;br /&gt;&lt;div&gt;勉強の過程で色々わかったから、そのうちここにまとめて書いていく…かもしれない。&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="width:425px;text-align:left" id="__ss_816135"&gt;&lt;a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/kentaro714/scala-presentation-816135?type=powerpoint" title="Scala Study Session"&gt;Scala Study Session&lt;/a&gt;&lt;object style="margin:0px" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=scalastudysession-1228360147131878-8&amp;stripped_title=scala-presentation-816135" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=scalastudysession-1228360147131878-8&amp;stripped_title=scala-presentation-816135" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;"&gt;View SlideShare &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/kentaro714/scala-presentation-816135?type=powerpoint" title="View Scala Study Session on SlideShare"&gt;presentation&lt;/a&gt; or &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/upload?type=powerpoint"&gt;Upload&lt;/a&gt; your own. (tags: &lt;a style="text-decoration:underline;" href="http://slideshare.net/tag/scala"&gt;scala&lt;/a&gt; &lt;a style="text-decoration:underline;" href="http://slideshare.net/tag/studysession"&gt;studysession&lt;/a&gt;)&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-6577232408794773477?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/6577232408794773477/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=6577232408794773477&amp;isPopup=true' title='1 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/6577232408794773477'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/6577232408794773477'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2008/12/scala.html' title='Scala勉強会の資料'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-8389624836860532095</id><published>2008-11-06T12:55:00.000+09:00</published><updated>2009-04-13T02:46:49.275+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Scalaでの可変オブジェクトの扱い</title><content type='html'>&lt;div&gt;今までは、関数は副作用を持たないものとして扱ってきた。なので、時間の概念を気にする必要もなかった。一連の処理は、どのような順番で評価しても最終的に同じ結果が得られる。これを合流性（confluence property）とかチャーチ・ロッサー性と呼び、関数型プログラミングの理論的基盤となるラムダ計算の重要な帰結らしい。知らなかった。&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;ざっとWebを流し読みしたところ、ラムダ計算の体系では、ラムダ式をベータ簡約することが計算そのものとなるようだ。ベータ簡約は関数適用による正規化のこと。で、チャーチ･ロッサー性とか合流性とかは、ベータ簡約の順序がどうであっても最終的に同じ正規化されたラムダ式が得られる、ということを言っているようだ。これはつまり、どのラムダ式から評価・計算しても同じ計算結果が得られるということになる。…簡約、つまり計算が停止さえすれば。&lt;/div&gt;&lt;div&gt;つーか、これを調べてる間にラムダ計算の迷宮に迷い込んでしまった…大学で情報の基礎教育を受けていない身にはつらい…けど、勉強になる。&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://ja.wikipedia.org/wiki/%E3%83%A9%E3%83%A0%E3%83%80%E8%A8%88%E7%AE%97"&gt;Wikipedia:ラムダ計算&lt;/a&gt;&lt;a href="http://www.kb.ecei.tohoku.ac.jp/~sumii/class/keisanki-software-kougaku-2005/lambda.pdf"&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.kb.ecei.tohoku.ac.jp/~sumii/class/keisanki-software-kougaku-2005/lambda.pdf"&gt;東北大学の講義資料&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;さて、これは不変の世界・参照透過性が保証された世界の話で、ここでの本題はScalaでの可変の世界の扱い方。ここでは、オブジェクトがhistoryによってその振る舞いを変える場合、オブジェクトは状態を持つという。このあたりは、純粋関数型とかそういうのはもう捨ててしまって、完全にオブジェクト指向の世界に入っている。いわば、Javaな人にとってはおなじみの世界。Javaとの違いといえば、変数は定義と同時に初期化しなければならない点くらいだろうか。なので途中の例は思い切って省略！つまんないし。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;同値性と変更&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;「代入」の導入により、二つの式が同じかどうか判別するには、より正確な「同値性」の定義が必要になってくる。具体的には、可変の世界では以下のようにして同一性をテストするらしい。&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;式xと式yを含む任意の一連の処理Sを実行し、結果を観測する。&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Sの処理のうち、yをxにすべて置き換えた処理S’を実行し、結果を観測する。&lt;/li&gt;&lt;li&gt;もしS’の実行結果がSの実行結果と異なっている場合、xとyは同じでない。&lt;/li&gt;&lt;li&gt;SとS’の実行結果がすべて同じであれば、xとyは同じ。&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;これは、インスタンス自体が同じかどうかみたいな話をしているようだ。Javaのequalsに慣れた身としてはなんとももどかしい定義だ。理屈としてはこれで良いとして、実際上はどうするんだろう？&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;代入と置き換えモデルの崩壊&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;今までは、値の名前を常にその値を定義する式に置き換えることができた。例えば、&lt;/div&gt;&lt;div&gt;&lt;pre class="prettyprint"&gt;val x = new BankAccount; val y = x&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;のval y = xは、val y = new BankAccountと置き換えることができた。しかし、可変の世界ではこのモデルはもはや機能しない。このように書き換えてしまうと、違う意味になってしまう。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;手続き的制御フロー&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;おなじみのwhile/do-whileがあります。なーんだ、あるじゃん！と手続きに馴染み深い自分は一安心してしまった。変数に値を代入できるから使える制御フローではあるよね、確かに。while (j &lt;&gt;&lt;div&gt;だけど結局、whileループも以下のような再帰の関数で置き換えることができる。&lt;/div&gt;&lt;pre class="prettyprint"&gt;def whileLoop(condition: =&gt; Boolean)(command: =&gt; Unit) {&lt;br /&gt; if (condition) {&lt;br /&gt;   command; whileLoop(condition)(command)&lt;br /&gt; } else ()&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;こうすれば、可変オブジェクトは不要になる。なるほど。ちなみに、whileLoopは末尾再帰なので、実際はループとしてコンパイルされる。ということで、一定のスタック領域しか消費しない。&lt;/div&gt;&lt;div&gt;後は、回路をシミュレートするサンプルが延々続いてるけどこれは省略。おなじみだし。&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;まとめ&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;状態（代入）を導入すると、プログラムは複雑になる。とりわけ、参照透過性が失われる。が、状態はこれはこれでエレガントなプログラムを作るのに役立ったりもする。どちらを選ぶかは状況によりけり。&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23864877-8389624836860532095?l=hibituredure.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hibituredure.blogspot.com/feeds/8389624836860532095/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23864877&amp;postID=8389624836860532095&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/8389624836860532095'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23864877/posts/default/8389624836860532095'/><link rel='alternate' type='text/html' href='http://hibituredure.blogspot.com/2008/10/scala_28.html' title='Scalaでの可変オブジェクトの扱い'/><author><name>kentaro714</name><uri>http://www.blogger.com/profile/09216429468346920287</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23864877.post-2150033549992441534</id><published>2008-11-04T12:02:00.007+09:00</published><updated>2009-04-13T02:46:49.275+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>ScalaのForループ</title><content type='html'>&lt;span class="Apple-style-span"  style=" ;font-family:'MS PGothic';"&gt;&lt;div style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; width: auto; font: normal normal normal 100%/normal Georgia, serif; text-align: left; "&gt;&lt;span class="Apple-style-span"  style=" ;font-family:'MS PGothic';"&gt;&lt;div style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; width: auto; font: normal normal normal 100%/normal Georgia, serif; text-align: left; "&gt;&lt;span class="Apple-style-span"  style="font-family:'MS PGothic';"&gt;&lt;div style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; width: auto; font: normal normal normal 100%/normal Georgia, serif; text-align: left; "&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;MapやFilterを使った高階操作はわかりづらい場合もあるので、Scalaでは従来の手続き型スタイルのForループに近い記法も用意されている。その記法では、&lt;/span&gt;&lt;div&gt;&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;persons filter (p =&gt; p.age &gt; 20) map (p =&gt; p.name)&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;を&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;for (p &lt;-persons if age &gt; 20) yield p.name&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;という風に書くことができる。形式的には、&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;for ( s ) yield e&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;このようなになり、sはGenerators, Definitions, Filtersの並びで構成されるらしい。&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Generatorsとは、 val x &lt;- e で、eがList値の式であるようなもの。Definitionsは通常の定義と同じで、以後の式で使うことができる。FiltersはBoolean型の式。普通は関数になるハズ。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;sはGeneratorsではじまる必要があり、Generatorが複数記述された場合はネストされたような動きになる。つまり、先行するGeneratorが1度評価されるたびに、後続のGeneratorはすべて評価される。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;for ( s )の記法ではGeneratorsとDefinitions,Filtersの間はセミコロンで区切らないといけないが、()の代わりに{}を使う記法、つまり for { s }の記法を使った場合、セミコロンは省略することができる。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold; "&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;The N-Queen Problem&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;レイトン教授でもよく出題されていた、N-Queen問題を例として、For-Comprehensionの使い方を見ていく。N-Queen問題は、N行・N列のチェス盤にQueenを置くゲームで、Queenは互いにチェック状態にならないようにする、というもの。Queenは同じ行・列・斜めの直線状のコマをチェックできるので、お互いが同じ行・列・斜め線に並ばないように配置しなければならない。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;これを解く方法としては、新たに置いたQueenが今まで置いたQueenにチェックされないかを確認しながら、1列ずつQueenを置いていく、というものが考えられる。このコードは、以下のように書ける。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;def queens(n: Int): List[List[Int]] = {&lt;/span&gt;&lt;/pre&gt;&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;  def placeQueens(k: Int): List[List[Int]] =&lt;/span&gt;&lt;/pre&gt;&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;    if (k == 0) List(List())&lt;/span&gt;&lt;/pre&gt;&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;    else for { queens &lt;- placeQueens(k - 1)&lt;/span&gt;&lt;/pre&gt;&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;      column &lt;- List.range(1, n + 1)&lt;/span&gt;&lt;/pre&gt;&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;       if isSafe(column, queens, 1) } yield column :: queens&lt;/span&gt;&lt;/pre&gt;&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;    placeQueens(n)&lt;/span&gt;&lt;/pre&gt;&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;def queens(n: Int) : List[List[Int]]は、N-Queen問題の「n」、つまりQueenを置く盤のサイズを受け取り、すべての解をListで返すというもの。&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;内部のList[Int]はそれ自体が1つの解を表すようになっており、1～nのそれぞれの行（列）でのQueenの位置（列または行）を表す。&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;実際にこの問題を解いているのはdef placeQueens(k: Int): List[List[Int]]の部分で、再帰になっている。queensはこの内部メソッドを呼んでいるだけだ。&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;では、placeQueensを見ていく。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;「k == 0」の場合は、空ListのListを返している。List(List())の部分。「k &gt;= 1」の場合にFor-Complehensionが出てきている。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;「k &gt;= 1」の場合、まずｋ－１の解のセットをすべて取得（これはplaceQueens(k - 1)で取得）し、ここから解を1つ取り出す。この1つの解ごとにList.range(1, n + 1)でIntのList（1～n、これは盤の列の数、すなわちk番目のQueenの置き場所の候補）を生成する。&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;で、k-1の解と、k列でのQueenの配置をisSafeに渡して、Safeだったらこの2つを結合してk列までの解として返す。これを解とk列の置き場所の組み合わせの数だけ実行すれば、すべての解が得られることになる。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;k-１の解とkの解の総当りを試すところは、二重ループになっている。ScalaのForの表記的は多重ループがわかりづらいので、最初見た時には混乱してしまった。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold; "&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Querying with For-Comprehensions&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;For記法は、データベースクエリ言語の基本的な部分と本質的には同じらしい。例えば、書籍データベースを以下のようにBookクラスのListとして表現したとする。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;case class Book(title: String, authors: List[String])&lt;br /&gt;&lt;br /&gt;val books: List[Book] = List(&lt;br /&gt;Book("Structure and Interpretation of Computer Programs",&lt;br /&gt;List("Abelson, Harold", "Sussman, Gerald J.")),&lt;br /&gt;Book("Principles of Compiler Design",&lt;br /&gt;List("Aho, Alfred", "Ullman, Jeffrey")),&lt;br /&gt;Book("Programming in Modula2",&lt;br /&gt;List("Wirth, Niklaus")),&lt;br /&gt;Book("Introduction to Functional Programming"),&lt;br /&gt;List("Bird, Richard")),&lt;br /&gt;Book("The Java Language Specification",&lt;br /&gt;List("Gosling, James", "Joy, Bill", "Steele, Guy", "Bracha, Gilad")))&lt;/span&gt;&lt;/pre&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;このデータベースに対して、authorが"Ullman"から始まるBookのtitleを取り出すには、こう書ける。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;for (b &lt;- books; a &lt;- b.authors if a startsWith "Ullman") yield b.title&lt;/span&gt;&lt;/pre&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;titleに"Program"が含まれるものについては、こう。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;for (b &lt;- books if (b.title indexOf "Program") &gt;= 0) yield b.title&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;少なくとも2冊の本を書いている著者の名前を取り出す場合には、こう書ける。&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;for (b1 &lt;- books; b2 &lt;- books if b1 != b2; a1 &lt;- b1.authors; a2 &lt;- b2.authors if a1 == a2) yield a1&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;これは完全ではなく、著者が二重にカウントされてしまう。重複した著者を取り除く関数は、以下のように書ける。&lt;/span&gt;&lt;/div&gt;&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;def removeDuplicates[A](xs: List[A]): List[A] =&lt;br /&gt; if (xs.isEmpty) xs&lt;br /&gt; else xs.head :: removeDuplicates(xs.tail filter (x =&gt; x != xs.head))&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;これをFor-Comprehensionで書くと、こうなる。&lt;/span&gt;&lt;/div&gt;&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;xs.head :: removeDuplicates(for (x &lt;- xs.tail if x != xs.head) yield x)&lt;/span&gt;&lt;/pre&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold; "&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;For-Comprehensionの変換&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;For-Comprehensionは、結局はmap/flatMap/filterの組み合わせに変換できる。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;for (x &lt;- e) yield e’&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;このようなFor-Comprehensionは、&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;e.map(x =&gt; e’)&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;こう変換できる。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;for (x &lt;- e if f; s) yield e’&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;これは、&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;for (x &lt;- e.filter(x =&gt; f); s) yield e’&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;こう。fはフィルタ（Boolean式）で、sはGeneratorとFilterらしい。が、ForでDefinition使った例見たことないし、if f の後のGeneratorってどうなるのかもよくわからないぞ。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;for (x &lt;- e; y &lt;- e’; s) yield e’’&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;これは、&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;e.flatMap(x =&gt; for (y &lt;- e’; s) yield e’’)&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;こうなる。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;もう少し具体的な例をあげると、&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;for { i &lt;- range(1, n) j &lt;- range(1, i) if isPrime(i+j)} yield {i, j}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;これが…&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;range(1, n)&lt;br /&gt; .flatMap(i =&gt;&lt;br /&gt;   range(1, i)&lt;br /&gt;     .filter(j =&gt; isPrime(i+j))&lt;br /&gt;       .map(j =&gt; (i, j)))&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;
