Effective Java 新旧比較

超小ネタですが、Effective Java第2版第3版 を見出しレベルで比較してみました。細かい言い回しの変更は含んでいません。というか、はじめに と付録の 第2版に対応する項目 を見ればだいたい新しい項目は把握できると思われます。が、そこをあえて項目同士を横に並べる形で一覧化してみました。ご参考まで。

第3版を購入したけど積読中の方、とりあえず新しく追加された項目を読んでみるのはいかがでしょう。

章レベルでは第3版から『第7章 ラムダとストリーム』が追加されています。項目レベルでは下記の通りです。左列に NEW と記載があるものが新しく追加されたか、他項目に移行されたものです。

また、第2版の『項目21 戦略を表現するために関数オブジェクトを使用する』『項目73 スレッドグループを避ける』は第3版では削除されています。(項目21については第3版では Lambda に移行された模様)

太字下線 の行は章見出しです。

- # 第2版 # 第3版
1 はじめに 1 はじめに
2 オブジェクトの生成と消滅 2 オブジェクトの生成と消滅
1 コンストラクタの代わりにstaticファクトリーメソッドを検討する 1 コンストラクタの代わりにstaticファクトリーメソッドを検討する
2 数多くのコンストラクタパラメータに直面した時にはビルダーを検討する 2 多くのコンストラクタパラメータに直面した時にはビルダーを検討する
3 privateのコンストラクタかenum型でシングルトン特性を強制する 3 privateのコンストラクタかenum型でシングルトン特性を強制する
4 privateのコンストラクタでインスタンス化不可能を強制する 4 privateのコンストラクタでインスタンス化不可能を強制する
NEW 5 資源を直接結び付けるよりも依存性注入を選ぶ
5 不必要なオブジェクトの生成を避ける 6 不必要なオブジェクトの生成を避ける
6 廃れたオブジェクト参照を取り除く 7 使われなくなったオブジェクト参照を取り除く
7 ファイナライザを避ける 8 ファイナライザとクリーナを避ける
NEW 9 try-finallyよりもtry-with-resourcesを選ぶ
3 すべてのオブジェクトに共通のメソッド 3 すべてのオブジェクトに共通のメソッド
8 equalsをオーバーライドする時は一般契約に従う 10 equalsをオーバーライドする時は一般契約に従う
9 equalsをオーバーライドする時は、常にhashCodeをオーバーライドする 11 equalsをオーバーライドする時は、常にhashCodeをオーバーライドする
10 toStringを常にオーバーライドする 12 toStringを常にオーバーライドする
11 cloneを注意してオーバーライドする 13 cloneを注意してオーバーライドする
12 Comparableの実装を検討する 14 Comparableの実装を検討する
4 クラスとインタフェース 4 クラスとインタフェース
13 クラスとメンバーへのアクセス可能性を最小限にする 15 クラスとメンバーへのアクセス可能性を最小限にする
14 publicのクラスでは、publicのフィールドではなく、アクセッサーメソッドを使う 16 publicのクラスでは、publicのフィールドではなく、アクセッサーメソッドを使う
15 可変性を最小限にする 17 可変性を最小限にする
16 継承よりコンポジションを選ぶ 18 継承よりコンポジションを選ぶ
17 継承のために設計および文書化する、でなければ継承を禁止する 19 継承のために設計および文書化する、でなければ継承を禁止する
18 抽象クラスよりインタフェースを選ぶ 20 抽象クラスよりインタフェースを選ぶ
NEW 21 将来のためにインタフェースを選ぶ
19 型を定義するためだけにインタフェースを使用する 22 型を定義するためだけにインタフェースを使う
20 タグ付クラスよりクラス階層を選ぶ 23 タグ付きクラスよりもクラス階層を選ぶ
DROP 21 戦略を表現するために関数オブジェクトを使用する
22 非staticのメンバークラスよりstaticのメンバークラスを選ぶ 24 非staticのメンバークラスよりもstaticのメンバークラスを選ぶ
NEW 25 ソースファイルを単一のトップレベルのクラスに限定する
5 ジェネリック 5 ジェネリック
23 新たなコードで原型を使用しない 26 原型を使わない
24 無検査警告を取り除く 27 無検査警告を取り除く
25 配列よりリストを選ぶ 28 配列よりもリストを選ぶ
26 ジェネリック型を使用する 29 ジェネリック型を使う
27 ジェネリックメソッドを使用する 30 ジェネリックメソッドを使う
28 APIの柔軟性向上のために境界ワイルドカードを使用する 31 APIの柔軟性向上のために境界ワイルドカードを使う
NEW 32 ジェネリックスと可変長引数を注意して組み合わせる
29 型安全な異種コンテナーを検討する 33 型安全な異種コンテナを検討する
6 enumアノテーション 6 enumアノテーション
30 int定数の代わりにenumを使用する 34 int定数の代わりにenumを使う
31 序数の代わりにインスタンスフィールドを使用する 35 序数の代わりにインスタンスフィールドを使う
32 ビットフィールドの代わりにEnumSetを使用する 36 ビットフィールドの代わりにEnumSetを使う
33 序数インデックスの代わりにEnumMapを使用する 37 序数インデックスの代わりにEnumMapを使う
34 拡張可能なenumをインタフェースで模倣する 38 拡張可能なenumをインタフェースで模倣する
35 命名パターンよりアノテーションを選ぶ 39 命名パターンよりもアノテーションを選ぶ
36 常にOverrideアノテーションを使用する 40 常にOverrideアノテーションを使う
37 型を定義するためにマーカーインタフェースを使用する 41 型を定義するためにマーカーインタフェースを使う
NEW 7 ラムダとストリーム
NEW 42 無名クラスよりもラムダを選ぶ
NEW 43 ラムダよりもメソッド参照を選ぶ
NEW 44 標準の関数型インタフェースを使う
NEW 45 ストリームを注意して使う
NEW 46 ストリームで副作用のない関数を選ぶ
NEW 47 戻り値型としてStreamよりもCollectionを選ぶ
NEW 48 ストリームを並列化するときは注意を払う
7 メソッド 8 メソッド
38 パラメータの正当性を検査する 49 パラメータの正当性を検査する
39 必要な場合には、防御的にコピーする 50 必要な場合、防御的にコピーする
40 メソッドのシグニチャを注意深く設計する 51 メソッドのシグニチャを注意深く設計する
41 オーバーロードを注意して使用する 52 オーバーロードを注意して使う
42 可変長引数を注意して使用する 53 可変長引数を注意して使う
43 nullではなく、空配列か空コレクションを返す 54 nullではなく、空コレクションか空配列を返す
NEW 55 オプショナルを注意して返す
44 すべての公開API要素に対してドキュメントコメントを書く 56 すべての公開API要素に対してドキュメントコメントを書く
8 プログラミング一般 9 プログラミング一般
45 ローカル変数のスコープを最小限にする 57 ローカル変数のスコープを最小限にする
46 従来のforループよりfor-eachループを選ぶ 58 従来のforループよりfor-eachループを選ぶ
47 ライブラリーを知り、ライブラリーを使う 59 ライブラリを知り、ライブラリを使う
48 正確な答えが必要ならば、floatとdoubleを避ける 60 正確な答えが必要ならば、floatとdoubleを避ける
49 ボクシングされた基本データより基本データ型を選ぶ 61 ボクシングされた基本データよりも基本データ型を選ぶ
50 他の型が適切な場所では、文字列を避ける 62 他の型が適切な場所では、文字列を避ける
51 文字列結合のパフォーマンスに用心する 63 文字列結合のパフォーマンスに用心する
52 インタフェースでオブジェクトを参照する 64 インタフェースでオブジェクトを参照する
53 リフレクションよりインタフェースを選ぶ 65 リフレクションよりもインタフェースを選ぶ
54 ネイティブメソッドを注意して使用する 66 ネイティブメソッドを注意して使う
55 注意して最適化する 67 注意して最適化する
56 一般的に受け入れられている命名規約を守る 68 一般的に受け入れられている命名規約を守る
9 例外 10 例外
57 例外的状態にだけ例外を使用する 69 例外的状態にだけ例外を使う
58 回復可能な状態にはチェックされる例外を、プログラミングエラーには実行時例外を使用する 70 回復可能な状態にはチェックされる例外を、プログラミングエラーには実行時例外を使う
59 チェックされる例外を不必要に使用するのを避ける 71 チェックされる例外を不必要に使うのを避ける
60 標準例外を使用する 72 標準的な例外を使う
61 抽象概念に適した例外をスローする 73 抽象概念に適した例外をスローする
62 各メソッドがスローするすべての例外を文書化する 74 各メソッドがスローするすべての例外を文書化する
63 詳細メッセージにエラー記録情報を含める 75 詳細メッセージにエラー記録情報を含める
64 エラーアトミック性に努める 76 エラーアトミック性に努める
65 例外を無視しない 77 例外を無視しない
10 並行性 11 並行性
66 共有された可変データへのアクセスを同期する 78 共有された可変データへのアクセスを同期する
67 過剰な同期は避ける 79 過剰な同期は避ける
68 スレッドよりエグゼキューターとタスクを選ぶ 80 スレッドよりもエグゼキュータ、タスク、ストリームを選ぶ
69 waitとnotifyよりコンカレンシーユーティリティを選ぶ 81 waitとnotifyよりも並行処理ユーティリティを選ぶ
70 スレッド安全性を文書化する 82 スレッド安全性を文書化する
71 遅延初期化を注意して使用する 83 遅延初期化を注意して使う
72 スレッドスケジューラに依存しない 84 スレッドスケジューラに依存しない
DROP 73 スレッドグループを避ける
11 シリアライズ 12 シリアライズ
NEW 85 Javaシリアライズよりも代替手段を選ぶ
74 Serializableを注意して実装する 86 Serializableを細心の注意を払って実装する
75 カスタムシリアライズ形式の使用を検討する 87 カスタムシリアライズ形式の使用を検討する
76 防御的にreadObjectを書く 88 防御的にreadObjectメソッドを書く
77 インスタンス制御に対しては、readResolveよりenum型を選ぶ 89 インスタンス制御に対しては、readResolveよりもenum型を選ぶ
78 シリアライズされたインスタンスの代わりに、シリアライズ・プロキシを検討する 90 シリアライズされたインスタンスの代わりに、シリアライズ・プロキシを検討する

その他

長年、本書の第2版は Java の必読書としてしばしば挙げられていますが、内容が古くなっていたり、新しい機能に追従できていないところはありました。以前よりも Java のアップデートサイクルは早くなっているため、特に入門者に書籍をおすすめするときには、古い内容が含まれていないか、移行された機能がないか、十分に注意したいところです。

ところで、全体的に Optional がカタカナで書かれているのはなぜだろう...。

GraphQL を Spring Boot で試してみる 2

こちらの続き。今回は Mutation を試してみます。

GraphQL を Spring Boot で試してみる 1 - kntmr-blog

サンプルコードはこちら。

kntmr/playground - GitHub


以下、備忘録。

schema / データクラス

スキーマに Mutation の IF を定義。引数に任意の型を指定する場合は input を定義する。(命名規則が雑なのは許してください)

// ... (略)
input _ToDo {
    content: String!
    completed: Boolean!
    userId: ID!
}
type Mutation {
    add(todo: _ToDo): [ToDo]
}

尚、内部で Jackson を利用しており、データクラスは Jackson のお作法に従う必要がある模様。最初、input に対応するデータクラスにデフォルトコンストラクタがなくて、API 呼び出し時に以下のエラーが発生。

Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.example.demo.type._ToDo` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
Resolver

Mutation の場合は GraphQLMutationResolver インタフェースを実装する。

@Component
public class TodoMutationResolver implements GraphQLMutationResolver {
    private TodoDao todoDao;   
    public TodoMutationResolver(TodoDao todoDao) {
        this.todoDao = todoDao;
    }   
    public List<ToDo> add(_ToDo _todo) {
        List<ToDo> current = todoDao.findAll(); // XXX
        return todoDao.add(new ToDo(current.size(), _todo.getContent(), _todo.isCompleted(), _todo.getUserId()));
    }
}
リクエス

アプリを起動して、http://localhost:8080/graphiql にアクセスする。以下の形式でリクエストする。更新するデータと併せて、レスポンスで返して欲しいフィールドを指定する。

mutation {
  add(todo: {
    content: "New content!"
    completed: false
    userId: 1
  }) {
    id
    content
    completed
  }
}

所感

今回は Mutation を試してみました。次回は Subscription を試してみようかと。

SpringOne Tour 2018 に行ってきた #s1t

先日、SpringOne Tour 2018 に行ってきました。簡単に所感をまとめます。

Tokyo November 6 | SpringOne Tour

メモから抜粋。スライドが公開されたらリンクを貼っておきます。逐次通訳はあったのですが、理解が誤ってる箇所があるかもしれません...。

Spring Boot 2.0によるリアクティブSpring

www.slideshare.net

  • Reactive Programming
    • non-blocking, event-driven
    • 省スレッド
    • backpressure
  • Java は拡張されやすいように進歩してきたが、効率は効率はよくなかった
  • 新しいリクエスト/接続があるたびにスレッドを生成する必要がある
    • 各スレッドでIOを待つ必要があったり
  • イベントループによって少ないリソースで処理する
    • 非同期で処理する
    • ただの非同期ではなくリアクティブ
    • 非同期とリアクティブの違いは Backpressure
    • Backpressure がないと Subscriber の処理が追い付かない
    • Subscriber は Publisher に Backpressure して大量データを制御する
  • スケジューラによって比較的少ない数のスレッドで処理できる
  • リアクティブの目的はパフォーマンス向上より拡張性の向上
  • Reactive Streams: 4 interfaces ★
    • Publisher
    • Subscriber
    • Subscription
    • Processor<T,R>
    • ↑の仕様を実装したのが Project Reactor
    • Reactor が Java/Spring で使いやすくていい
  • Publisher<T>
    • 通常の Java では単一の Object か Collection を返す
    • Publisher は 0..無限 の値を返せる
    • Spring WebFlux では、0 or 1 / 0..無限の値を返す
    • WebSocket はサーバーからのイベントに対応している
  • MongoDB はリアクティブサポートあり (Reactive MongoDB)
    • Embedded MongoDB は組み込みで手軽に開発できる
    • テスト/開発で使うときは build.gradle を testimplementationimplementation に変える
  • ReactiveCrudRepository
    • repo.deleteAll() が最初に実行される保証はない ⇒ repo.deleteAll().block()ブロッキングできる
    • ただし、.block() は書くべきではない ⇒ repo.deleteAll().thenMany(...) でアップストリームの完了を待つ
    • thenMany() はチェインできる
  • Subscriber より Publisher が早いケースをシミュレート
    • onBackpressureDrop : Subscriber が処理しきれないときは捨てる
    • onBackpressureBuffer : Subscriber が処理しきれないときはバッファする (サイズ指定可能)
  • @SpringBootTest
    • Spring 全体のコンテキストをロードする
  • @WebFluxTest
  • 無限の Flux をテストするときは考慮が必要
    • StepVerifier でテストする
    • StepVerifier.withVirtualTime で時間が経過したことをシミュレートしてテストする
  • (メモ) FSR: The Full Stack Reactive (meta) repository

クラウドネイティブSpring

  • Reactive MongoDB
  • Java 11
  • Lombok
  • R2DBC
    • R2DBC では Spring Data JDBC を使う
    • Reactive MongoDB は使わない?
    • Production ではまだ使わない (GAではないので)
    • R2DBC では deleteAll は使えない?
  • RouteLocator (Spring Cloud Gateway)
  • Spring Security
    • bcrypt を使う?
    • Reactive に対応しているが、古い AuthenticationManager は動作する (Problem?)
  • 429 Too Many Requests

Spring Cloud Gateway

  • マイクロサービスが増えるとサービス間の関連が増える
  • 通常は Gateway を配置する
  • 主な目的は Routing (リクエストを適切なインスタンスに流す)
  • すべてのアプリケーションに対してセキュリティを実施
  • Canary-ing
    • 新バージョンをリリースするときに Canary Release する
    • 少量のリクエストを流してテストする
  • Monolith なアプリケーションをマイクロサービスに移行する
  • ロードバランサ
  • Netflix Zuul 1
    • Servlet, Blocking IO
    • パフォーマンスに問題があった
    • API が使いにくい
  • Spring Cloud と Zuul 1 は統合済み
  • Netflix Zuul 2
    • Netty, Non-blocking IO
  • Spring Cloud が Zuul 2 と連携すると Zuul 1 と後方互換性がなくなる
  • Spring Cloud Gateway
    • Node.js のような event-loop のアーキテクチャ
    • Request --> Event Queue --(Schedule)--> Event Loop --(Schedule)--> Network Call
    • Network Call --(Callback)--> Event Loop --(Callback)--> Event Queue --> Response
  • Handler Mapping (Spring が提供する機能)
    • Predicates
    • Pre-Filters : ダウンストリームに送る前に実行される filter
    • Global Filters : ダウンストリームにリクエストする (WebSocket などのプロトコルをサポート)
    • Post-Filters : HTTP ステータスやヘッダを変えたり、Cookie をセットしたり
  • RouteLocator
    • route に ID を付けるとデバッグのときに便利
  • Hystrix
  • WebSocket
    • クライアント/サーバー間で Gateway を通して persistent な接続を維持する
  • Embedded
    • Spring アプリに Gateway を組み込む
    • レイテンシに厳しい場合など、Cross-Origin の問題も心配なし?
  • Facade
    • クライアントとアプリの間に配置する
    • アプリに直接接続する必要がない
    • 技術(?)が違う場合でも接続できる
    • アプリが切り替わってもクライアントに影響しない
  • Cross-Cutting + App-Specific
  • Gateway で Spring Boot の Auto Configuration が使える (Spring Boot ベースなので)
  • Micrometer Support
    • SLF4J メトリック
  • Zipkin で分散トレーシング
  • (メモ) httpbin.org
  • (メモ) HTTPie

Spring Cloud Stream 2.0によるクラウドイベント駆動型アーキテクチャ

サーバーレスSpring

www.slideshare.net

  • Serverless ★
    • sacle to N, scale to zero
  • Knative & riff
  • HTTP ★
    • spring-cloud-starter-function-web
    • Function インタフェースを実装して Bean 定義する
  • Message ★
    • spring-cloud-function-context + spring-cloud-stream-binder-rabbit
  • Supplier, Function, Consumer
  • Source, Processor, Sink
  • @EnableBinding(Processor.class)
  • Exchange, Topic
  • s.c.s.function.definition にパイプで function をチェインできる
  • Spring Cloud Function Adapter ★
    • PaaS プロバイダに依存せずデプロイ/実行できる
  • Knative & riff
  • Knative は k8s ベースのプロダクト
    • build, deploy, manage
  • riff は Knative 上で動く
    • Knative を簡単に使えるようにするもの
    • polyglot
    • CLI, Function Invokers, BuildTemplates
  • Pivotal Function Service
    • riff の商用サービスとして提供予定

Pivotal Application Serviceで稼働するSpring Boot/Spring Cloudアプリケーション

  • Pivotal Application Service
    • 開発した Spring Boot アプリをどのように運用するか
  • Full Cycle Developers (by Netflix) ★
  • Atlas
    • Netflix 製の監視ツール
    • アプリを監視できるように自分でツールに設定するのは面倒
    • アプリ側からツールに自身を設定するようにした
  • MOSH
  • Spring Cloud Pipeline
    • CredHub
    • 12 Factor App
  • アップロードされたパッケージからCF側でランタイムを判断して環境を構築してくれる?
    • Buildpacks の中でできるっぽい
  • Pivotal Cloud Cache

Using Spinnakerを使用したKubernetes上の開発ワークフローの作成

  • Container をまとめたものが Pod
  • Pod をまとめたものが ReplicaSet
    • 可用性
  • ReplicaSet を拡張したものが Deployment
  • LB側でグローバルIPを持つ
  • Ingress
    • 1つのURLで複数のアプリを持てる
  • Helm
  • Helm Chart
  • Kuberapps Hub

所感など

先週の Spring Fest 2018 に続いて、2週連続の Spring イベント。とにかく登壇者が豪華でした。みなさん、ユーモアが豊富でおもしろかったです。全体的にデモやライブコーディングがあってよかった。特に、Josh Long のセッションとライブコーディングは勢いが凄まじかったです。

とはいえ、PCF や k8s などは使ったことがなくてイマイチ理解が追い付かず。特に、k8s あたりは避けては通れないと思われるので勉強しなければ。

当日、JJUG x JSUG のナイトセミナー で Josh Long のイベントがあったのですが、そっちも参加すればよかった...。もったいない。

Vue Fes Japan 2018 に行ってきた #vuefes

Vue Fes Japan に行ってきました。簡単に所感をまとめます。

vuefes.jp

今回参加したセッションは以下の通り。メモから抜粋。スライドが公開されたらリンクを貼っておきます。尚、英語セッションはリスニング力がショボすぎて理解が誤ってるかもしれません...。

キーノート

docs.google.com

  • Vue 3.0 Updates
    • 速度向上が重要
    • サイズを小さくする
    • メンテナンスしやすく
    • ネイティブ向けに

より速く:

  • 仮想 DOM の実装をフルスクラッチで作り直す
    • 最大100%の速度改善!
  • 後方互換あり、内部実装を作り変える
    • ライブラリ作者は少し調整が必要になるかも
  • JavaScript の新しい言語仕様を使うようにする
    • 3.x ではプロキシを使うように書き換えている
    • 2.x では ES5 の getter/setter を使っている
    • プロパティの追加/削除を検知できるようになる
    • ネイティブプロキシによるプロパティプロキシの高速化
      • Object.defineProperty は使わない
  • 実行中のオーバーヘッド削減のため、コンパイル時にヒントを追加
    • Render Function
    • コンパイル時にテンプレートの情報を取得する
    • これまでは実行時に解析していた
    • 必要な情報をコンパイル時に取得することで実行時の速度が向上する
  • Render 関数にあるスロット機能を最適化 (スロットの生成を最適化)
    • 2.x ではスロットは親のスコープで生成されるため、子要素は親要素を参照する必要があり、描画時に依存の階層が深くなる
    • 子要素が変更されたときは子要素のみ再描画すればよい
    • React にはこの仕組みはない
  • static tree hoisting (静的ツリーの巻き上げ)
  • static props hoisting (静的プロパティの巻き上げ)
    • ツリー全体を再描画するのではなく、中身だけ再描画する
  • inline handler hoisting (インラインハンドラの巻き上げ)
  • コンポーネントインスタンスの初期化を高速化
  • 省メモリ、パフォーマンス向上
  • Vue をアップデートするだけでパフォーマンス向上が可能

より小さく:

  • Tree-shaking への対応
  • Webpack や Rollup では Tree-shaking に対応している
  • オプション機能のコードをバンドルに含めないようにする (10KB以下も可能)

よりメンテしやすく:

  • アーキテクチャをよりクリーンなものに
  • パッケージの分離
    • リポジトリはモノリポジトリ
    • 独立した機能ごとにパッケージとして分ける
    • 実行環境に依存しない、js が動く環境であればどこでも動かせる

よりネイティブに:

  • iOS, Android
  • カスタムレンダラAPI
    • ブラウザ以外の環境向けに出力できる
    • NativeScript, Weex
    • ネイティブ向けに出力するために作った

コードの品質向上:

  • どのオプジェクトのプロパティでも監視できるようになる
  • Vuex を使わなくもよくなるかも

リアクティビティAPI:

TSX による TypeScript サポート:

  • Vue 2.x では完璧なものではなかった
  • props の型を表示できる (違う型を指定すると警告を表示してくれる)
  • コンポーネントと親コンポーネントの警告をコンソールに表示してくれる

(Experimental) Hooks API:

(Experimental) Time Slicing:

  • 描画に時間がかかるコンポーネントが複数あるとき、ブラウザが固まってしまう
  • Time Slicing を使うだけでレスポンシブになる
  • 60fps で収まるように js 関数をスロットリングする
  • イベントが連続したときに、古いイベントはスキップする

Vue.js と Web Components のこれから

  • Web Components
  • Web Components Specifications ★
    • HTML Template はもう使われなくなる?
  • Vue CLI 3 の Build Targets
    • --target wc オプションをつけてビルド
    • Vue.js コンポーネントを Web Components に変換してくれる
    • web-component-wrapper
      • Vue.js をラップしている
    • Vue.js コンポーネントを Web Components にスムーズに移行できる
  • Vue, React, Angular で共通のUIフレームワークとして使い回せる
  • Fully Scoped
    • Vue.js は Scoped っぽくなっている
    • Shadow DOM なので完全に Scoped
    • グローバルの css や js に影響しない
  • デメリット ★
  • 現時点では Vue.js でコンポーネントを作った方が機能的にいいかも
  • Micro Frontends ★
    • Web アプリを機能の集合と見なす
    • 一般的なフロントエンドはモノリシックになっている
    • 独立した機能で分割する
    • Shadow DOM は Scoped なので、変更が他のコンポーネントに影響しない
    • Web Components は Micro Frontends を実現するのに適している
  • 柔軟な Web サイトに
  • Vue.js の方が機能的に強力ではあるが、Web 標準であることの強みは将来の負債を減らす
  • Web Components は Vue.js を置き換えるものではない
    • Web Components は HTML 要素をカプセル化するもので、Web アプリを作るものではない
    • UI を相互干渉なく作るためのもの
    • Vue.js は Web アプリを作るためのもの
  • UI を Web Components に任せることで負債を減らす

Unit testing a Vuex store

slides.com

  • なぜテストをするのか
  • Three approaches ★
  • Don't
    • UT を書くのにも時間はかかる
    • E2E tests test store implicitly
  • store のパーツごとにテストする
    • Mutations
      • state と payload を渡して mutate して update されていることを assert
    • Getters
      • state を渡して getter を解決、戻り値を verify
    • Actions
      • HTTP リクエストはしない (テストがスローダウンするため)
      • jest.mock で API の戻り値をモック化する
      • mock の store を渡して、action が data を commit していることを assert
    • 粒度が細かいが、メンテが大変
  • store インスタンスをテストする
    • ブラックボックス
    • Vue.use(Vuex) はだめ
      • グローバルな Vue インスタンスに影響を与えないため
      • localVue.use(Vuex)
    • store.dispatch で action を呼び出して、state を assert
    • 必要に応じて API 呼び出しをモック化
    • 粒度は荒いが、メンテはラク
  • 複雑なテストを何度も回せるようにファクトリ関数を用意している
  • vue-test-utils はベータ
  • Vue 3 ではブラウザの DOM を使わずにレンダリングできる
    • これを使ってテストすることで高速化できるかも?
  • テストのときに本物の store を使うか、モックの store を使うか
  • コンポーネントのテスト
  • カバレッジを上げることより、何をテストするのかを見極めることが大事
    • 無駄にテストするより、新機能を開発することに注力する方がいい
  • TDD

Nuxt.js 2.0

  • レンダリングモード
  • モダンブラウザ対応のビルド
  • ブラウザと REST サーバーの間に Nuxt サーバーを置いてもいい (BFF)
  • https://hn.nuxtjs.org/
  • ブラウザ => APIサーバーだとユーザーごとにリクエストが来る?
    • SSR なら Nuxt サーバーで中継できる?
  • 静的ファイルはECサイトみたいな動的サイトに向かない
  • SPA
  • 2.3 でクライアントとサーバーのバンドルを分離できる
    • クライアントフォルダ / サーバーフォルダ
  • ES Modules 対応
  • 新規追加したコンポーネントは自動でルーティングなどに設定してくれる
  • asyncData のコンテキストはドキュメント参照
  • Vue 2.x のサポートが続くので、Nuxt 2.x のサポートも続く
  • Vue 3.x に合わせて Nuxt 3.x もリリースされる予定

note のフロントエンドを Nuxt.js で再構築した話

  • Angular.js 1.x
    • 初期表示が遅い (特に低スペックな端末)
    • SSR 未サポート
  • Nuxt.js によって規約が手に入る ★
  • パスベースで移行、Dog Fooding
    • 移行完了するまで二重メンテになるのがデメリット
    • チームを分ける
  • Lighthouse によるパフォーマンス比較
    • 指摘されているのはほとんど画像関連
  • Vuex + Atomic Design
  • mutations/actions/getters のタイプには定数を使う
    • grepability
    • エディタ補完
  • Vuex モジュール肥大化問題 (特に Actions に処理が集中しがち)
    • パーツごとにファイルを分離
    • 機能単位でモジュール分割できないか
  • Atomic Design
    • レイヤごとの責任分離が明確に
    • 名称があることでコミュニケーションが円滑に
  • コンポーネント視認性問題
    • Storybook
  • ユニバーサル JavaScript
    • クライアント/サーバーのどちらでも動作する
    • window, document は undefined
  • Polyfill.io
  • Nuxt on Lambda
    • Node.js のバージョンが固定されるため、Nuxt.js の最新に追従できない
    • ファイルサイズ上限が50MB
    • コールドスタート問題

1年間単体テストを書き続けた現場から送る Vue Component のテスト

  • 半数以上のサービスで Vue を使っている
  • 外部から見た振る舞いをテストする ★
  • Public Interface
  • Output
    • HTML/CSS, Event(Emit), Vuex/Action
  • ↑これらがテストターゲット ★
  • mount or shallow mount
    • 外部から見た振る舞い、設計の可動域の確保の観点から mount
  • router から読み込む Page Component をテストする
    • Page Component でカバーできないものは別途テスト
  • テストツールの役割を整理する ★
    • ブラウザが必要 or ブラウザが不要
  • Lifecycle Hooks ★
  • Props / Vuex State ★
    • 見た目にかかわるところ
    • Snapshot Testing ★
      • コンポーネントの DOM を比較する
      • 修正前後の DOM を比較する (差分があればチェック)
    • Visual Testing
      • Snapshot Testing の画像版 (CSS もテスト可能)
    • Storybook + reg-suit (画像の差分抽出) ★
      • Visual Testing を開発フローに乗せる
      • 以前は手元に checkout して起動したり、修正前後の画像をキャプチャしたり
      • レビューの負荷を下げることができる
  • User Interaction
    • スクロールなどの複雑な操作は難易度高い (できないことはないが諦める)
    • karma-nightmare でテスト中にスクリーンショットを取る
    • 画像は reg-suit で開発フローに乗せる
    • 重要なフォームだけでもテストする
    • 難しいところは割り切って諦める
  • テストをしっかり準備することでレビュー負荷を下げられる

所感など

登壇者が豪華で、改めて Vue.js の盛り上がりと勢いを感じます。全体的に学びと刺激が多いカンファレンスでした。キャンセル分のチケットが購入できてよかった...!

最初の KEYNOTE で 3.x の話がありましたが、特にパフォーマンスを改善する仕組みが多く取り込まれているようです。後方互換もちゃんと考慮されていて、Vue.js をアップデートするだけでパフォーマンス向上が期待できる模様。ぜひ使ってみたい。あと、個人的にはテスト関連のセッションがとても参考になりました。過去に自分が書いたテストは方向性としては決して間違ってなかったけど、足りてないところや改善できるところがまだまだたくさんあります。

Nuxt.js はまだちゃんと使ってないので、勉強中。

あと、Web Components や Micro Frontends あたりもなかなか興味深かったです。要復習。他のセッションも資料が公開されてるものがあるので、あとで読む。

というか、本当にもっと英語力を鍛えなくては...。

Spring Fest 2018 に行ってきた #jsug

Spring Fest 2018 に行ってきました。簡単に所感をまとめます。

springfest2018.springframework.jp

今回参加したセッションは以下の通り。メモから抜粋。(スライドのリンクは随時更新します)

KEYNOTE

  • Spring ユーザーの4分の3は Java 8
    • Java 7 は2割くらい
  • Spring のベースラインは LTS の Java バージョンに合わせる見通しか
    • 中間の Java リリースに対応できるように Spring もシームレスにアップデートしていく
  • GraalVM (Substrate VM)
  • Kotlin が伸びている (Android 開発によるもの)
    • メジャーな JVM 言語になる可能性あり
    • ネイティブライブラリが使える
    • さまざまなエコシステムの開発に使える
    • 記述の簡潔さ、immutable、静的型付け
  • Spring 5.1
    • 5.0 => Java 8
    • 5.1 => Java 8, 11
    • Java 9, 10 はベストエフォートでサポート
    • 5.1 を使うだけで省メモリ、高速化が可能
  • Spring Boot 2.1
    • Java 11 サポート
    • Spring Data JDBC starter
    • 起動時間短縮、パフォーマンス改善、省メモリ
  • Kotlin サポート
    • Spring 5.2 / Kotlin 1.3 ベースライン
    • Coroutines サポート
    • モバイル領域の言語なので省メモリで高パフォーマンス
  • GraalVM
    • Spring 5.1
    • ミリ秒レベルで Spring Boot アプリケーションが起動できる
  • R2JDBC ★
    • リアクティブプログラミングサポート
    • ブロッキングJDBC の代替
    • Reactive SQL SPI (experimental)
    • PostgreSQL ドライバのみ (他は今後サポート予定)
    • Spring Data R2DBC
    • 検索結果が Stream (Flux, Mono) で返る
    • Database Client で functional に書ける
  • RSocket
  • Spring Fu ★
    • incubator intended to mature experimental
    • Spring Boot 2.1 より省メモリで高パフォーマンス
    • Kofu Configuration
      • functional に configuration できる

決済システムの内製化への旅 - SpringとPCFで作るクラウドネイティブなシステム開発

www.slideshare.net

  • 支援ツールを内製化して運用作業を自動化
  • サービス監視
  • 開発支援
  • Pivotal Cloud Foundry ★
    • Pivotal Container Service (Kubernetes)
    • Pivotal Application Service
    • Pivotal Function Service
  • 抽象化レイヤが違う、サポートしているプラットフォームが違う
  • PAS を使うことでデプロイ速度向上が可能 (1min)
    • ベンダー&オンプレだと1ヶ月以上かかることも
  • 開発チームの責任分担
    • 12 Factor App に従う
    • ベンダーロックインはない
  • PAS 以外のコンポーネント(VM)は BOSH で管理
  • Dev, Prod の2環境
    • Dev で問題ないものを Prod にあげる
  • API Gateway に Spring Cloud Gateway の ProxyExchange (ユーティリティ) を使っている
  • Hystrix で Circuit Breaker
    • ある決済機関で発生した障害が API Gateway まで伝搬しないように
    • 処理がブロックされてスレッドが枯渇する
  • 非同期処理は RabbitMQ + Spring Cloud Stream
    • ある加盟店で障害が発生したときはキューに退避して再送する
    • Hystrix で Circuit Breaker
  • PCF App Autoscaler
  • 12 Factor App ★
    • ログは標準出力に出力すればプラットフォーム側で集約
    • ロストしたくないログはRDBに保存する
  • JMeter による E2E テスト
    • JMeter の HTML レポートが意外と使える
  • Java の複数バージョンでのユニットテスト
    • Docker イメージを使って各バージョンでテストする
    • アップデートの弊害を早期に検知する
    • 複数バージョン同時にテストできるCI環境
    • 簡単にデプロイできる Dev / Staging / Prod 環境
  • Observability
    • Metrics, Tracing, Logging
    • Grafana (Micrometer)
    • Kibana
    • Zipkin
      • サービス跨ぎでどこの処理に時間がかかっているか分かる
      • SQLの実行時間を確認できる

Spring ♥ GCP ー Spring と GCPの素敵な関係(アプリ実行環境としてのGCPを考える)

  • GCP を使うメリットはスケール感
  • Cloud Function は Java 未サポート
  • App Engine
    • 2番目にサポートした言語が Java
  • フレキシブルの中身はVM
    • 起動に時間がかかる
  • スタンダードはサンドボックス
    • フレキシブルより使えるライブラリに制限が多い
    • ランタイムのサポートを広げる (普段のランタイムと同じように使えるように)
    • スタンダード第二世代 (Java サポートあり)
  • App Engine にデプロイするときは war でパッケージングする
    • ランタイムが Jetty なので
  • アプリのモジュール化
  • App Engine 上でバージョニング
    • Splitting Traffic
    • 新旧バージョンでリクエストを振り分ける
  • GKE
    • zero-ops を目指す
    • master ノードは Google がメンテする
    • worker ノードはオプションを提供している (オートスケールなど)
    • アプリケーションがコンテナ化されていること (Docker)
    • Container Registry に登録されていること
    • Docker 化されたアプリは pod という単位で扱われる

Amazon Cognito使って認証したい?それならSpring Security使いましょう!

www.slideshare.net

  • Core, Web, Config
  • SecurityFilter は複数ある
    • Security Filter Chain
    • 実行される順序は決まっている
  • AccessDecisionVoter ★
    • Voter は複数持てる
    • Voter の投票結果から Manager がアクセス権を判断する
    • Manager も複数ある
  • Amazon Cognito
  • 認証成功でユーザープールトークンが返る
  • アクセストーク
    • JWT
    • 有効期限は1時間、切れたら更新トークンを使って更新する
  • アクセストークン検証
    • JWTの構造、署名、クレーム
    • 何を認証するかは Cognito のリファレンスを参照
  • テストでは MockMvc に SecurityFilter を追加する
  • メソッドセキュリティ ★
    • メソッド呼び出しのレベルでアクセス制御する
    • Post... は戻り値に対してチェックする

Pivotal認定講師が解説!基礎からのOAuth 2.0とSpring Security 5.1による実装

  • 認可サーバーがアクセストークンを発行する
  • Keycloak
    • SSO基盤
    • OAuth2, OpenID Connect をサポート
  • 認可コード
    • 認可サーバーからアクセストークンをもらうときに使う
      • アクセストークンをブラウザに保持させたくない
    • クライアントは認可コードと引き換えにアクセストークンを受け取る
      • アクセストークンを持ってリソースサーバーに問い合わせる
  • どのように認可するかは未定義
    • 開発者が自作するか、ライブラリ依存
  • クライアント > 認可サーバー への認証がある (ベーシック認証)
  • アクセストークンが本当に認可サーバーから発行されたものかチェックする必要がある
    • 認可サーバーに問い合わせてアクセストークンを検証
    • スコープをチェックしてレスポンスを返す
    • チェックの方法は OAuth2 で未定義 (何かしらの形でチェックせよとしか書いてない)
  • JWT
    • 電子署名は認可サーバーの 秘密鍵 で暗号化される (認可サーバーの 公開鍵 で復号する) ★
    • 本来の秘密鍵/公開鍵の使い方とは逆
  • JWK: 公開鍵を算出するための情報群
  • JWT を使うときはアクセストークンの有効期限を短くする ★
    • 認可サーバーに問い合わせないため、認可サーバー側では無効化することができない
    • リフレッシュトークンでリフレッシュする
  • Spring Security
    • 認可サーバーは OAuth2 未対応
    • 5.2 以降?

Spring Boot with Kotlin, functional configuration and GraalVM

  • Kotlin
  • WebFlux, Spring Data Reactive
  • Spring Fu
    • faster, lighter な Spring Boot
  • Lambda を lazy な factory bean として使う
  • Auto Configuration を functional bean として使う
  • セルフドキュメンテーション
  • Kofu, Jafu
  • functional に configuration する
  • Reactive API vs Coroutines API
  • Spring Boot & GraalVM

業務で使いたいWebFluxによるReactiveプログラミング

スライドが公開されたら要復習。

所感など

前回は Spring 5 がリリースされたあとだったので、そのあたりの話題で盛り上がりましたが、正直、今回は前回ほどの目新しい情報はないかなとか思ってました。が、いろいろと実験的な機能含めてどんどん新しい機能が追加されている/今後追加されていくようで、キャッチアップするのが大変そう...。とはいえ、今後の Spring の動向が知れてよかったです。今後の Spring において優先度の高い観点としては、簡潔さ、容易さ、省メモリ、(起動時間含めて) 高パフォーマンスあたりであると思われます。特に Spring アプリをコンテナ化したときに必要に応じてすぐに立ち上がることは大事。

いよいよ R2JDBC で DB 側がリアクティブサポートされるようです。ただ、WebFlux あたりはあまり使ったことがないので、要復習。あと、WebFlux は js フレームワークと組み合わせたときはどうなるんだろうか。要調査。

Kofu, Jafu の話はきちんと理解できず。要復習。

Google の話は聴いてよかったです。最近は AWS ばかり調べてましたが、Googleクラウドサービスもウォッチした方がよさそう。

メソッドの命名にはオーソドックスな単語を使おう

これの補足ですが、処理の内容を端的な名前で表現できないとき、必要以上に複雑さを抱えている可能性があると考えていいと思います。なので、calculate みたいなやや抽象的なメソッド名を業務ロジックの中に見つけると不安になります。あと、execute とか、バッチアプリケーションのエントリポイントとかであればいいんですが、個人的にはこれも業務ロジックの中には出てきて欲しくない名前です。

そして、だいたいそういう名前のメソッドは処理が長くて多くの責務を持っている傾向にある気がします。一般的によく使われる単語で端的に名前が付けられないときは一旦立ち止まって考え直した方がよさそうです。あと、createXxxYyyZzz みたいに目的語(?)が多いときとか。

これらは設計の見直しやリファクタリングのサインになるわけです。

その他

自分はあまり見かけることはないですが、参照系のメソッドには副作用があってはいけません。あと、処理に必要なデータが存在しない場合、デフォルト値を返すか、例外とします。安易に null を返してはいけません。

find 系のメソッドは検索を伴い、リストを返します。条件に一致するものがなければ空のリストを返します。Optional を返してもいいと思います。null を返してはいけません。

delete は完全な削除、remove はある集合から取り除く、別の領域に退避するようなイメージです。ここは意識的に使い分けたいところ。

現場からは以上です。

Java EE (Jakarta EE) 周りの名称や用語のメモ

Java EE (Jakarta EE) 周りで似たような名称や用語によく出会うので、簡単に調べてまとめてみました。個々の詳細や比較については書いてません。また、間違ってる箇所があるかもしれません。他にもいろいろあるので随時追記していこうと思います。たぶん。

Java EE / Jakarta EE

Java Platform, Enterprise Edition の略。旧称は J2EEエンタープライズアプリケーション開発で利用される機能の仕様をまとめたもの。2017年に Oracle から Eclipse Foundation に移管されて、Jakarta EE に改称。

Web ProfileJava EE の一部の仕様を抜き出した(?)もの。

EE4JJakarta EE を管理するプロジェクト。これは Java EE の頃から同じ模様。Eclipse Enterprise for Java の略。

GlassFish

Java EE アプリケーションサーバー。Java EE から Jakarta EE の改称に併せて、Eclipse GlassFish に改称。

WebLogic

Java EE アプリケーションサーバー。正式名称は Oracle WebLogic ServerGlassFish とは別のものと捉えてていいと思われる。

MicroProfile

Java EE をベースにしたクラウドやマイクロサービス向けの仕様。Java EE の一部ではなく、補完するものという位置付けの模様。現在は Eclipse Foundation で管理されている。なので、正式名称はおそらく Eclipse MicroProfile と思われる。

Payara / Payara Micro

GlassFish ベースのアプリケーションサーバー。Payara Micro は、Eclipse MicroProfile 互換で、クラウドやマイクロサービス向けのアプリケーションサーバー。

JBoss / WildFly

Java EE アプリケーションサーバー。商用版は Red Hat JBoss Enterprise Application Platform で、OSS 版は WildFly と呼ばれる。WildFly の旧称は JBoss Application Server

WildFly SwarmJava EE アプリケーションを実行可能 jar として生成できるもの。現在は Thorntail という名称らしい。

WebSphere

IBMJava EE アプリケーションサーバー。正式名称は WebSphere Application Server

WebSphere Liberty / LibertyProfile

WebSphere Application Server の一部で、アプリケーションサーバーの ランタイム

Open Liberty

WebSphere Liberty の OSS 版。

補足

Tomcat や Jetty は、JSPServlet など Java EE の一部を実装したもの。なので、Java EE アプリケーションサーバーではない。