日頃の行い

個人的な日頃の行いをつらつら書いてます\\\\ ٩( 'ω' )و ////

Domain Driven Design Quickly Onlineを読む #2

www.infoq.com を読みます。

1章 Domain Driven Design Quickly Onlineを読む #1 - 日頃の行い

章ごとに雑なメモとして解説などではなく、思ったことを淡々と書いていくつもりです。

2章 ユビキタス言語

共通言語の必要性

前章おさらい
ソフトウェアの専門家とドメインの専門家が一緒に働き、ドメインモデルを作成することが不可欠

しかし、それぞれの専門とする分野の言葉をそれぞれが使おうとするため、コミュニケーションが難しくなる
部外者が理解できないような専門用語など
開発者やドメインの専門家が使う言葉を門外漢がわかるように例えた言葉であったとしてもドメインに関する知識を確立する作業には役立たない
ドメイン駆動設計の核となる原則:ドメインモデルに基づく言語を使う
コミュニケーションやプログラミングコードにもこのドメインモデルに基づく言葉を使う
このような言葉をユビキタス言語と呼ぶ

共通言語として使える用語を見つけるのは簡単じゃない
ドメインの定義と設計の方向を決めるような重要な要素を見つけ、これらの要素に適切な名前をつけることで、共通言語として使える用語が手に入る

ドメインの専門家は、ドメインモデルや共通言語の中で理解できないものがあった時は何らかの間違いがある
開発者は設計に紛れ込みやすい曖昧さや矛盾が現れていないかを注視しないといけない

この辺りでユビキタス言語を作っていくストーリーの具体例

普段の会話では婉曲的な会話になることや、詳細に立ち入りすぎること、概念を取り違えたりすることがよくある
そのような会話でユビキタス言語を見つけるのは難しい
なので、チームすべてのメンバでユビキタス言語を作らなければならないと自覚して重要な点に集中しつつ、
必要なときには既に作成したユビキタス言語を利用する
そして、このような作業時には独自の専門用語を極力使わないようにする

開発者はドメインモデルの主要な概念をコードへ実装するべき

ユビキタス言語はどのように表現すべきか
UMLも良い、文書を使っても良い
モデルについての認識を合わせるためのおすすめは、モデルの部分を表す小さな図を作成すること
これらの図は、幾つかのクラスを含み、それらの関係を表し、概念全体の一部を適切に含む
ドメインモデル全体を表す大きな図は作成できたとしても雑然としているはずなので、小さな図の集まりの方がよりよく理解できるはず

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

まとめ

  • 開発者だけではなくドメインの専門家も含めたそれぞれの専門用語ではない共通言語(ユビキタス言語)の作成がチームでプロジェクトを進めていく上で大事
  • ユビキタス言語は図や文章様々な表現方法で、大きく全体的というより、小さな図の集合によって表すと良い

Domain Driven Design Quickly Onlineを読む #1

DDDの本を読もうと思ったけど、先が長くて意志の強さが足りそうにないので、こちらから読んでいくことにしました。 章ごとに雑なメモとして解説などではなく、思ったことを淡々と書いていくつもりです。

www.infoq.com

1章

ドメイン駆動設計とは何か

メモ

ソフトウェアは業務の自動化や現実世界の問題などの具体的なドメインのためのもの
ソフトウェアは特定のドメインから生まれ、そのドメインと深く関わっている
優れたソフトウェアを作るにはドメインの理解が必要
例)銀行業務
Q. ドメインの理解がある人はだれか A. 銀行員
彼らは全ての細部・全ての落とし穴・全ての潜在的な問題点・全てのルールを知っている。
ここから出発しなければならない。
これがドメインから出発するということ?

ソフトウェアを導入する真の目的はそのドメインの業務をより効率的にするため。
したがって、改善対象のドメインに円滑に適用できなければならない。

ドメインの反映としてソフトウェアを作ることで、ソフトウェアをドメインに円滑に適合させることができる。
ドメインの核となる概念や要素を取り入れ、それらの関係を正確に再現する。
(再現させるために?)ソフトウェアはドメインをモデル化する必要がある。

ドメイン=この世界についての何か
ドメインは、単にキーボードでコンピュータにとり込んだり注ぎ込んだりすればコードになるというようなものではない。
ドメインの抽象的な概念(青写真)=が必要。つまりモデル化が必要。
抽象とはドメインのモデルのこと
ドメインモデルは特定の図で表わされるものではない。
そのような図が伝えようとする概念のこと。
ドメインモデルはドメインの専門家の頭のなかにある単なる知識ではない。
ドメインモデルはそういった知識を厳密に取捨選択しながら作成する抽象のこと。

ドメインモデルは対象のドメインをプロジェクトの関係者に向けて表現したもの。
ドメインはとても多くの情報を含んでいるので全てをモデルに取り込めない。
何をモデルに取り込み、何を捨てるのか。これが設計作業でありソフトウェアの作成。

モデルは他人に伝えなければならない。
私たちは一人で作業するわけではない。

勝手なまとめ

  • ソフトウェア=業務を自動化するもの・現実の問題を解決するもの
  • ドメイン=この世界についての何か
  • ドメインモデル=ドメインの抽象的な概念
  • ドメインについての専門家から必要なものを取り込み、不必要なものを排除したものがドメインモデル

ドメインの知識を構築する

例)飛行機の飛行制御システム システムの目的:飛行機同士が衝突しないようにすること ドメイン:航空監視業務 ドメインの専門家:航空管制官

を元にした具体的なやりとりだった。

sbtを使ってGoogleAppEngineにScalaのコードで書いたアプリケーションをデプロイするの巻

GoogleAppEngine for Javaはありますが、JavaではなくScalaで書きたいので、Scalaでデプロイ出来ないかなと色々探してみました。

cloud.google.com

やること

やることは簡単です。

使ったもののVersionはScala 2.11.7, sbt 0.13.11 です。

1. sbt-appengine pluginの導入

こちらを利用します。

github.com

2ファイル用意する必要があります。
0.12.xの時は違う設定になるようなので注意です。

appengine.sbt

libraryDependencies += "org.mortbay.jetty" % "jetty" % "6.1.22" % "container"

appengineSettings

/project/plugins.sbt

addSbtPlugin("com.eed3si9n" % "sbt-appengine" % "0.6.2")

2. appengine-web.xmlの準備

/src/main/webapp/WEB-INF/appengine-web.xml

<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
    <application>dark</application>
    <version>1</version>
    <threadsafe>true</threadsafe>
</appengine-web-app>

ここでのapplicationはGoogle Console上の project id を指定します。

3. Servlet用のclassとweb.xmlの準備

/src/main/scala/com/ru/waka/servlets/Main.scala

package com.ru.waka.servlets

import javax.servlet.http.{HttpServlet, HttpServletRequest, HttpServletResponse}

class Main extends HttpServlet {
  override def doGet(request: HttpServletRequest, response: HttpServletResponse) {
    response.setContentType("text/plain")
    response.getWriter.println("Hello, world")
  }
}

/src/main/webapp/WEB-INF/web.xml

<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<servlet>
    <servlet-name>Main</servlet-name>
    <servlet-class>com.ru.waka.servlets.Main</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Main</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>

4. Google App Engine SDKのダウンロードとの設定

SDKをダウンロードして、APPENGINE_SDK_HOMEという環境変数を設定する必要があります。
ダウンロードはこちらで。

Download the Google App Engine SDK - App Engine — Google Cloud Platform

APPENGINE_SDK_HOMEをunzipした↑のディレクトリのパスに設定します。

export APPENGINE_SDK_HOME=/path/to/unzipped_google_app_engine_sdk

tips

  • intellijで起動時にAPPENGINE_SDK_HOMEが見えるようにする
    • APPENGINE_SDK_HOMEをintellijに設定ができず困りました
    • APPENGINE_SDK_HOMEを設定したターミナルで open /Applications/IntelliJ\ IDEA\ 14\ CE.app/ とやると開けます。

実行

$sbt
[info] Loading project definition from /path/to/scala-on-appengine/project
[info] Set current project to scala-on-appengine (in build file:/path/to/scala-on-appengine/)
# Local Server 起動
> appengineDevServer
[info] Compiling 1 Scala source to /path/scala-on-appengine/target/scala-2.11/classes...
[info] 'compiler-interface' not yet compiled for Scala 2.11.7. Compiling...
[info]   Compilation completed in 11.87 s
[info] Packaging /path/scala-on-appengine/target/scala-2.11/scala-on-appengine_2.11-0.1-SNAPSHOT.war ...
[info] Done packaging.
[info] Starting dev server in the background ...
objc[4157]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/jre/bin/java and /Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/jre/lib/libinstrument.dylib. One of the two will be used. Which one is undefined.
[success] Total time: 21 s, completed 2016/03/26 16:13:25
Listening for transport dt_socket at address: 1044
> 3 26, 2016 4:13:29 午後 com.google.apphosting.utils.jetty.JettyLogger info
情報: Logging to JettyLogger(null) via com.google.apphosting.utils.jetty.JettyLogger
3 26, 2016 4:13:29 午後 com.google.apphosting.utils.jetty.JettyLogger info
情報: jetty-6.1.x
3 26, 2016 4:13:31 午後 com.google.apphosting.utils.jetty.JettyLogger info
情報: Started SelectChannelConnector@127.0.0.1:8080
3 26, 2016 4:13:31 午後 com.google.appengine.tools.development.AbstractModule startup
情報: Module instance default is running at http://localhost:8080/
3 26, 2016 4:13:31 午後 com.google.appengine.tools.development.AbstractModule startup
情報: The admin console is running at http://localhost:8080/_ah/admin
3 26, 2016 4:13:31 午後 com.google.appengine.tools.development.DevAppServerImpl doStart
情報: Dev App Server is now running

# Deploy
> appengineDeploy
appcfg.sh should ideally be run using Java 7 (also known as 1.7).

The java executable at /usr/bin/java reports:
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

Running a more recent version of Java can lead to apps that are apparently
correct but do not work when uploaded to App Engine.

You can download JDK 7 from:
  http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html
Please enter code:

ここまで来るとこんな画面が出るので、ログインしてみましょう。

f:id:arata3da4:20160326163422p:plain

f:id:arata3da4:20160326163440p:plain

Please enter code:のところにモザイクがかかっている値を入れると次に進みます。

Please enter code: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Reading application configuration data...

#appengine-web.xmlに記載している applicationの値(app_id) が存在していないので、
# エラーが出てデプロイされていませんが、合っていればデプロイされます。
Beginning interaction for module default...
3 26, 2016 4:31:18 午後 com.google.appengine.tools.admin.AbstractServerConnection send1
警告: Error posting to URL: https://appengine.google.com/api/appversion/getresourcelimits?app_id=dark&version=1&
403 Forbidden
You do not have permission to modify this app (app_id=u'dark').
This is try #0
3 26, 2016 4:31:18 午後 com.google.appengine.tools.admin.AbstractServerConnection send1
警告: Error posting to URL: https://appengine.google.com/api/appversion/getresourcelimits?app_id=dark&version=1&
403 Forbidden
You do not have permission to modify this app (app_id=u'dark').
This is try #1
3 26, 2016 4:31:19 午後 com.google.appengine.tools.admin.AbstractServerConnection send1
警告: Error posting to URL: https://appengine.google.com/api/appversion/getresourcelimits?app_id=dark&version=1&
403 Forbidden
You do not have permission to modify this app (app_id=u'dark').
This is try #2
3 26, 2016 4:31:19 午後 com.google.appengine.tools.admin.AbstractServerConnection send1
警告: Error posting to URL: https://appengine.google.com/api/appversion/getresourcelimits?app_id=dark&version=1&
403 Forbidden
You do not have permission to modify this app (app_id=u'dark').
This is try #3

com.google.appengine.tools.admin.HttpIoException: Error posting to URL: https://appengine.google.com/api/appversion/getresourcelimits?app_id=dark&version=1&
403 Forbidden
You do not have permission to modify this app (app_id=u'dark').

Unable to update app: Error posting to URL: https://appengine.google.com/api/appversion/getresourcelimits?app_id=dark&version=1&
403 Forbidden
You do not have permission to modify this app (app_id=u'dark').

Please see the logs [/var/folders/3x/tr8_68tx29v9skp0lv76ljvc0000gn/T/appcfg1764707419651306170.log] for further information.

というところでした。ScalaでもGoogle App Engineは使えました。 今回試したレポジトリはこちらです。 git cloneと 4. Google App Engine SDKのダウンロードとの設定 だけで動くと思います。 github.com

参考

#ScalaMatsuri 2016 に参加してきました。

2016/01/30 ~ 31で行われたScalaMatsuriに行ってきました。

scalamatsuri.org

去年からしっかりScala触るようになったので、前回よりは内容がわかるようになった気がしました。
体調悪くて1日目の午後から行きました。
見逃してしまったのは、ニコ生で見ようかなと思います。

ScalaMatsuri 2016 1日目 メイントラック - 2016/01/30 09:40開始 - ニコニコ生放送

ScalaMatsuri 2016 2日目 メイントラック(アンカンファレンス) - 2016/01/31 10:00開始 - ニコニコ生放送

全講演が公開される予定らしいので、そっちで見なおしてもいいかなと思ったんですが、
さっさと見ないと多分なかなか見ないので早めにニコ生で見ようかと思ってます。

もらったノベルティグッズたち!

Scalaパズルは買ったものです)

f:id:arata3da4:20160131194714j:plain

講演

ちょくちょく休憩してたんですが、聞いた講演のメモとかから簡単にまとめてみました。
間違っていたら指摘いただけると幸いです。

1日目

ScalaコードはJVMでどのように表現されているのか

とても読み易いclassファイル開いてみるところから始まり、
読めない人のためのコマンド javap コマンドの紹介とjavapによって出力されるJVMの命令の説明が入りました。
元々JVMの命令は200ちょい(?)で初め出てから追加されたのが少ない(1個だったっけ・・・?調べよう)らしく、
初期設計からとても優秀だったようでした。
その説明後、javacとscalacでコンパイルした結果のclassの比較をしてどう表現されるのかという話でした。
scalacの方が出力するclassファイルが多く、Scalaコンパイラは少ない記述から多くの命令を出力しているという話でした。

あなたのScalaを爆速にする7つの方法

x1.inkenkun.com

EC2インスタンス上でsbt-jmhを利用して、ある7つのケースで処理のベンチマークを取った時の結果をクイズ形式で紹介されていました。
自分のクイズ結果は4/7(´・ω・`)
理由含めて完全にわかった奴はすごく嬉しくなりましたが、外した奴は悲しくなりました・・・でも楽しかったw
あ、これSICPでやったやつだ!とかなったりしてけど、中でArrayが使われてるとか知らなくて外したりしました(言い訳
あと正規表現は正直わからんかった。

The Zen of Akka

www.slideshare.net

Akka全く仕事で使ったこと無くて、なんとなく動かしたことあるくらいだったんですが、それでも聞いていてそういう使い方をするんだなぁみたいな気持ちになれました。
あと絵が好き。Akkaの禅がわかった気がします(雑
特に心に残っているのは、 BackoffSupervisorCluster Gossip Convergence
BackoffSupervisor は例えば、Actorが利用しているDBが死んだ時にどれくらいの時間を置いてリトライをするかという責務を担うもので、
Cluster Gossip Convergence は、クラスタ内の全てのノードの状態が観測し得るときに新規のノードがクラスタ内に参加できると理解しました。
障害時にどうなるという部分が考えられていてすごいなぁと思いました(小並感

2日目

2日目はアンカンファレンスで、 1日目の時点でTwitter上や会場のホワイトボードに貼られた案を元に参加者の人が発表するみたいな形式でした。
ちなみに、ホワイトボードにはこんなのもあったりしました

(phq・・・

ScalaとSparkによる日本語テキストマイニング

入門者向けということもあって、テキストマイニングの基礎の部分からでした。
Featureとは例えばメールにはfromとtoがあるが、そのfromのこと。
Labelとは予測したいもの(?)例えばメールであれば、スパムであるかスパムでないかということ。
Modelとは学習結果のこと。
などの説明から始まり、機械学習は基本的にFeature Engineeringだという話されてました。(前処理大変ですよね
形態素解析器としてはKuromojiやMecabがあるが、Kuromojiの方がMavenレポジトリで公開されているのもあり、Java Scalaのプロジェクトであればインストール容易とのこと。
その後、自分に来るメールのテキストを元に作業依頼なのか他のタスクなのかを判定するデモ(?)をされていました。
2時間前に始めたプログラムがまだ終わらず一部結果が見せられないと聞いて大変ですよね・・・って思いました。

Scala.js コンパイルパイプライン

Scala.jsのコンパイラの話でした。
Scalaのコードからどういう過程でJavaScriptになっていくのかという話でした。
めっちゃ面白かったんですが、知識と頭がついていきませんでした・・・
資料が見つかったらまた見たいと思います。

別の発表(LT)ですが、Scala.jsといえばこちらも興味深かったです。
UIと切り離したロジック部分をScala.jsで書くという方針と懇親会の時聞いて、完全にUIが存在しない部分のjsのコードのaltJsとしてScala.jsを利用するみたいな話をして、それならまだ行けるのかもしれないと思いました。

speakerdeck.com

昔こんな記事書いてから追ってなかったので追おうかなと思いました。
Vue.jsに入門しようと思ってScala.jsでVue.jsのサンプル書いてみた。 - 日頃の行い

Scalaエンジニアの年収w

(ちなみに左端は一番上は少なくとも海外の方で、基本的には言語が書いていない無効票に記載された金額でした。

感想

  • たのしかった!
  • モナドとかよくわかってないからといって色々避けてしまった
  • なので、FP in Scalaをちゃんと読み終えたい
  • Actorモデル(というかAkka)面白そう
  • 同時通訳めちゃくちゃすごかったです!おかげで英語の発表も臆すること無く聴きに行けました。
  • おつかれJavaでした!