日々常々

ふつうのプログラマがあたりまえにしたいこと。

モデリングのきほん

関西Javaエンジニアの会10周年イベント、 KanJava 10th Anniversary Partyモデリングの話をしました。

話したこと

モデリングモデリングしたモデルでモデリングを説明してみました。図の書き方とか言葉の抽出とかそう言う話ではありません。「なんちゃらモデリングをうまくやる方法」みたいなのを期待された方はすみません。でも延長線上にはあると思います。

私の中のモデリングは、対象から使わない情報を削ぎ落とし、対象の特定部分を強調することです。 モデルのモデルを 26ページ で描いてみました。 この図単体では伝わり難いと思いますが、図単独で成立するモデルではなくセッションも含めてのモデルなので雰囲気で見てください。

モデリングのポイントとして 54ページ で「同じことは同じように表現する」と挙げています。「同じことは同じように表現する」は手段で、原則は「情報を維持して表現を減らす」です。 例えば楕円を使うなら、そのモデル内での楕円は同じ意味で使う。同じものを楕円にしたり長方形にしたりしない。違うもの、つまり違いをそのモデルで表現しようとしたこと同士を楕円にしない。これは言葉の揺れも同じです。

モデリングの目的は使えるモデルを作ること( 34ページ )。わざわざモデルを作る以上、何かに使うはずです。なのでモデリングを行う際は使い方に焦点を当てます。

モデルを他人に伝えるために使うとしましょう。モデルを使えば伝わりやすいというのは経験があるかと思いますが、モデルは43ページのようにそのモデルで使わない情報を削ぎ落としたものなので、削ぎ落とした部分が気になってしまうと理解しづらいかったりもします。「あのことを考えなくていいのはなんでだろう」とか。この場合はモデルを使って伝える前に、会話などで目的を説明します。このような場の整えもモデリングなんのですが、メタメタして意味がわからなくなってくるので、それっぽいところで折り合いをつけます。それっぽいところは伝える相手との関係を含めていい感じにモデリングしてください。

あと、21ページ に挙げてますが、モデルは決して図ではありません。私の中ではスライドもモデルですし、このブログの文章もモデルです( 61ページ )。 22ページ に目に見えないモデルもある、みたいなことを描いてみましたが、正直これはうまく描けていません。脳内モデルとかをプロットしたら良かったかなーと思いつつ、うまく描けなかったんだから仕方ありません。

ともかく、「モデリングができない」なんてことはないと思っています。 「使いやすいモデルが作れない」はあるかもしれませんが、「なんでもモデリングだ」と思えばいくらでも実践機会はあります。 練習ではなく実践なので、やってるうちに使いやすいモデルを作る力も付いてきますし、モデルを使う力も付いてきます。

モデリングは難しいからできない」が「モデリングやってるけど難しい」になったら、本セッションの目的は達成です。難しいものは難しい。

イベントについて

今回は Mix Leap Studyさんとの共催と言う形でさせていただきました。ありがとうございます。

orange_cloverさんが togetter まとめてくれてます。シングルトラックかつセッションごとに見出し入れてくれてるので追いやすい。ありがとうございます。

関ジャバ10周年ということで、関ジャバ運営 + 設立メンバー全員がセッションしました。特にテーマも設けず、各々が話たいことを話したらこんな感じになりました。 関ジャバっぽかったと思います。半分以上Java関係ないセッションでしたが、関ジャバはJavaエンジニアのためのコミュニティなのでJavaの話をする必要はないのです。

思い返せば関ジャバでの私の初セッションは多分 関西Javaエンジニアの会(関ジャバ) '11 9月度 で、この時もJavaに関係のない夜行バスの話とかしてました。同年7月の関ジャバカンファレンス2011でLTとかもしてたりするんですが、そっちはLTなのでノーカン。カウントしたとしてもGroovyの話だけど。

これからもぼちぼち活動すると思うので、よろしくお願いします。

MacBook Pro 16インチが届いたのでセットアップのメモ

f:id:irof:20191202194728p:plain

手が滑って購入ボタン押してしまったので仕方がない。

やったこと

  • 起動
  • Apple IDのログイン
  • macOSの設定
    • キーボードショートカットの切り替え
      • OSのデフォルトのショートカットはほとんどOFFにする
      • 入力ソースの切り替えを ⌘+スペース に変更する
    • 日本語変換の便利っぽいけど重くなるのを切る
      • ライブ変換、タイプミスを修正、推測候補表示
      • これ切るだけでだいぶもたつきがマシになった。デフォルトONなのにまだイマイチなのね……
  • iTunesのアカウント紐付け
    • 2台しか使ってないのに5台の制限超えてるって言われたので全解除……
    • 以降は音楽流しながら
  • パスワード管理ソフトをインストール
  • Chromeをインストール
    • Googleアカウントのログイン
    • いちいち拡張機能インストールしなくていいのが楽だった
  • homebrew をインストール
  • sdkman をインストール
    • sdk install java 11.0.2-open
    • sdk install gradle
    • sdk install visualvm
  • GitHubの鍵登録
  • irof/dotfilescloneして設定
  • brewでインストールしたiTerm2に切り替え
    • iTerm2のconfigファイルは手動で読み込み
  • dein をインストール
    • vimそのまま起動したらエラーって言われたんで。

だいたいインストールは終わったと思ったら

f:id:irof:20191202201505p:plain

お、おう……せやな。

しばらく セキュリティとプライバシー のウィンドウを開きっぱなしにして、brewでインストールしたアプリを起動→許可を繰り返す。

以降はアプリの個別設定

  • IntellJ IDEAインストール
    • 今まではIDEA直接インストールしてたけど今回はToolBox APP経由でインストール
    • IDEのショートカットは(IDEAに限らず)ほぼデフォルトなので特に問題ない、はず。リファクタリングメニュー開くやつくらい。
  • Slackを起動してワークスペースの追加
    • これが一番面倒だった……同じメールアドレスはいちいちログインしなくてもいいんだけど、いちいちブラウザとアプリの往復になって、即時反映されなくて、うん。
  • 以降普段使ってるdockerイメージをいろいろダウンロード……(継続)

完了

これ書きながらで1時間ちょっと。たぶん2時間はかかってない。

まだ効率化できるだろうけど2年に一度ならこんなもんかなぁ。しかし昔を思えば楽になったものですねぇ。

SpringBoot2.2でJUnit5がデフォルトになったのでbuild.gradleを書き換える

SpringBoot2.2でJUnit5がデフォルトになったー。

他の更新はリリースノート見てくださいまし。 ちなみに私に関係ありそうなのはツイートした。触れてないのは単に使ってないってだけで、重要じゃないってわけじゃないです。

build.gradle の書き換え

SpringBoot2.1以前

implementation platform('org.springframework.boot:spring-boot-dependencies:2.1.6.RELEASE')
testImplementation("org.springframework.boot:spring-boot-starter-test") {
    exclude(group: 'junit')
}

testImplementation platform("org.junit:junit-bom:5.4.2")
testImplementation("org.junit.jupiter:junit-jupiter-api")
testImplementation("org.junit.jupiter:junit-jupiter-params")
testRuntimeClasspath("org.junit.platform:junit-platform-launcher")
testRuntimeClasspath("org.junit.jupiter:junit-jupiter-engine")

まず junit の除外。 入ってても実行時の悪さはしないんだけど @Test 使うときとかにJUnit4のが補完ででてきたりすると邪魔だし、うっかり使ったりしてても困るのでやっている人は多いと思います。

で、JUnit5を使うために諸々追加。 junit-bom は使わなくても spring-boot-dependencies で定義されてるんだけど、そっちで入る 5.3.2 じゃなく 5.4.2 を使いたかったから。 あとはSpringBoot使っててもSpringBootTestを使わない場合とかもあるんで、このセットで入れることはままあります。

SpringBoot2.2以降

implementation platform('org.springframework.boot:spring-boot-dependencies:2.2.0.RELEASE')
testImplementation("org.springframework.boot:spring-boot-starter-test") {
    exclude(group: 'org.junit.vintage')
}

シンプル。 SpringBootよりも新しいJUnit5を使いたくなったらまた記述は増えるんだろうけど、そこまで最新にこだわらないのなら勝手に入るのに任せてもいいと思います。

でもJUnit4は要らないから org.junit.vintage は除外する。

おまけの話(こっちが本編)

単にバージョンだけあげると

こんな警告でてきます。

10月 27, 2019 4:06:30 午後 org.junit.platform.launcher.core.DefaultLauncher handleThrowable
警告: TestEngine with ID 'junit-vintage' failed to discover tests
java.lang.NoClassDefFoundError: junit/runner/Version
    at org.junit.vintage.engine.JUnit4VersionCheck.checkSupported(JUnit4VersionCheck.java:32)
    at org.junit.vintage.engine.VintageTestEngine.discover(VintageTestEngine.java:61)
    at org.junit.platform.launcher.core.DefaultLauncher.discoverEngineRoot(DefaultLauncher.java:177)
    at org.junit.platform.launcher.core.DefaultLauncher.discoverRoot(DefaultLauncher.java:164)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
    at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.ClassNotFoundException: junit.runner.Version
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    ... 9 more

警告がでるのはexclude(group: 'junit') を指定している場合で、junit-vintage-engine 経由で入るはずの junit:junit が入らないから。なんだ自業自得じゃん。警告なんで無視してても動きはします。

警告って難しくて、それ単体なら無理に対応しなくてもいいんだけど、出続けると警告が出てることに慣れてしまうので、逐次潰していかないと他の警告も見なくなってしまう。これは人間だから仕方ないと思います。でもきっちり対応しようって思うとそこそこかかるんですよね。悩ましい。

正しい(?)対応は以下の通り。

  • exclude(group: 'junit') を削除
  • exclude(group: 'org.junit.vintage') を追加
  • 明示的に追加してた junit-jupiter たちを削除(これは方針次第)

そこそこかかった対応

警告に出てる例外を出しているのは junit-vintage-engineJUnit4VersionCheck で、自分が動こうにもクラスパスに junit.runner.Version がない。だから例外を投げる…… junit-vintage-engine としては正しいかな。

警告ログを出しているのは junit-platform-launcherDefaultLauncher で、例外を受けてログ出して処理続行。 そうしてるのは知ってるTestEngineをループしながら「実行できる?」って聞いてってるから。 TestEngineServiceLoader でクラスパスにあるのを拾ってきたり、設定で追加されたりされるもの。どんな TestEngine 入ってくるかは実行時任せだから、一つ実行できないのがあったからって止めるのは無しなんでしょう。

状況から VintageEngineServiceLoader に拾われていることがわかった。で、使う気のない VintageEngine を追加してるのが誰かを gradle dependencies で見たら spring-boot-starter-test だった。

この辺で「あーね」となって上の対応になりました。

こう言うのを秒で対応できるようになりたい。

あと build.gradle.kts に乗り換えようとしてるんだけど、なかなか捗らない。