システム開発で思うところ

Javaで主にシステム開発をしながら思うところをツラツラを綴る。主に自分向けのメモ。EE関連の情報が少なく自分自身がそういう情報があったら良いなぁということで他の人の参考になれば幸い

JavaParser

構文解析をするときに便利そう。構文木の書き換えも出来るみたい。

CIとかaptと組み合わせると面白い事ができるかもしれない。

例えばプロジェクト独自の静的解析を走行したい場合や独自フレームワークの作法を強制させたいときとか。

ただ実行速度がどのくらいのものか分からないので開発者のコンパイルというよりもCIで実行した方が良いとは思う(つまりaptとの組み合わせはしない方が良いと思う)。

JavaParser 使い方メモ - Qiita

Java の AST を解析できる javaparser がアツい!!! - tokuhirom's blog

BeanValidationのメモ

仕様

Bean Validation specification

参考リンク

JavaEE使い方メモ(Bean Validation)

私のBeanValidationの使い方(Java EE Advent Calendar 2013) — 裏紙

BeanValidationの相関バリデーションとそもそもの話 — 裏紙

4.1. 入力チェック — TERASOLUNA Server Framework for Java (5.x) Development Guideline 5.3.0.RELEASE documentation

http://fukuchiharuki.hatenablog.jp/entry/2015/01/10/231412

Bean ValidationのGroup sequenceは単項目チェック、相関チェックの順序指定で使うのは止めた方が良さそう

Spring Bootで入力値の検証(バリデーション)の順番を制御する - かずきのBlog@hatena

BeanValidationメモ_その1 - 怠惰系エンジニアのメモ帳

Bean Validationでクライアント側のロケールに合わせたメッセージを出力する - Java EE 事始め!

BeanValidationのmessage変数を更に翻訳したい - decadence

Hibernate ValidatorでValidationMessages.properties以外のファイルを使う

Hibernate Validator を使ったメソッド引数のチェック - AspectJ による組み込み - なんとなくな Developer のメモ

Validationそのものへの考察

こんな感じのValidationどうかなぁ?「この方が好き」ってあったら知りたいです! - Mitsuyuki.Shiiba

てことでValidationの実装を書いてみた - Mitsuyuki.Shiiba

自分なりの考察

2018/3/19 追記

Validation(検証)とメッセージ出力を混在しないで考え直す

BeanValidationではメッセージ出力まで出来る仕組みまで含まれているけれど、その仕組みを使いこなすのはケースによって無理やり感がでてくるように思います。

とくにWebのエラーメッセージ表示と直結させるときに。

とはいってもBeanValidationを使う多くのケースはFormの検証で、その結果のメッセージをそのままクライアントに返却する、ということで そちらの発想に引っ張られているところが多いように思うのです。

BeanValidation自身は別にWebクライアントの表示のためだけにあるわけではありません。

ツールの用途・目的を考えると、私はValueObjectの型宣言のとして使用するのが良いのではないか?と考えています。

その上でBeanValidationの検証結果メッセージをキーワードとして、Presentation層の目的別にメッセージ変換器を別に設けるというのが「混在しない」というイメージです。

とりあえず、この考えに則って実装を検討してみて、ある程度、まとまったら更に追記をしていこうと思います。

DDDのメモ

概念

原本のエッセンス

[ 技術講座 ] Domain-Driven Designのエッセンス 第1回|オブジェクトの広場

[ 技術講座 ] Domain-Driven Designのエッセンス 第2回|オブジェクトの広場

[ 技術講座 ] Domain-Driven Designのエッセンス 第3回|オブジェクトの広場


IDDD本から理解するドメイン駆動設計連載一覧:CodeZine(コードジン)


DDD超入門(前編) - Domain-Driven Designの概要 - エンタープライズギークス (Enterprise Geeks)

DDD超入門(後編) - Domain-Driven Designの適用Step - エンタープライズギークス (Enterprise Geeks)

全般的

ドメイン駆動設計の定義についてEric Evansはなんと言っているのか[DDD] - little hands' lab

境界づけられたコンテキスト 実装編 - ドメイン駆動設計用語解説 [DDD] - little hands' lab

DDDに関する質問にバシバシお答えしました [ドメイン駆動設計] - little hands' lab

speakerdeck.com

ドメイン駆動設計+クリーンアーキテクチャ解説【DDD編】 - Qiita

ドメイン駆動設計+クリーンアーキテクチャ解説【クリーンアーキテクチャ編】 - Qiita

https://tagoto.atlassian.net/wiki/spaces/public/blog/2018/02/18/37061127/DDD+Hexagonal+Onion+Clean+CQRS

ボトムアップドメイン駆動設計 │ nrslib

https://www.slideshare.net/MasanobuNaruse/bottomup-ddd-1www.slideshare.net

https://www.slideshare.net/MasanobuNaruse/bottomup-ddd-2www.slideshare.net

www.slideshare.net

speakerdeck.com

speakerdeck.com

ドメインオブジェクトを中心としたClean Architecture のためのレイヤー構成 - Qiita

speakerdeck.com

第3回 -ドメイン駆動設計のための オブジェクト指向プログラミング ハンズオン"に参加してきた! - desi-gneer(designer_engineer)

speakerdeck.com

集約の境界と整合性問題に関する感想 - Qiita

ユースケース

ドメインモデルの根拠とドメインモデル貧血症の対策について - Chatwork Creator's Note

UMLを描こう – Vol.6 ロバストネス図からシーケンス図を描く | アシアルブログ

CQRS

www.slideshare.net

#jjug_ccc 僕がDDDを勉強したりDomain Event使ってみたいと思ったりKafkaでCQRSの素振りをしている背景と現状 - Mitsuyuki.Shiiba

www.slideshare.net

CQRSとイベントソーシングの使用法、または「CRUDに何か問題でも?」 | POSTD

Event

ドメインイベントを設計する - yoskhdia’s diary

speakerdeck.com

www.youtube.com

書籍

vermeer.hatenablog.jp

www.slideshare.net

www.slideshare.net

www.slideshare.net

持続可能な開発を目指す ~ ドメイン・ユースケース駆動(クリーンアーキテクチャ) + 単方向に制限した処理 + FRP - Qiita

ドメインオブジェクトの責務について - Qiita

トランザクションスクリプト

ユースケース(アクション)中心にオブジェクト(メソッド)を組み立てるのがトランザクションスクリプト

いまさらきけない「ドメインモデル」と「トランザクションスクリプト」 - higayasuo’s blog

むむっ、私の思考はトランザクションスクリプトの可能性大かもしれない。


実装

DDD の Java EE 実装サンプル - Cargo Tracker を読み解く - Qiita

ドメイン駆動設計: IDDDに登場するサンプルコードのModule構成をまとめてみた - Qiita

2.4. アプリケーションのレイヤ化 — TERASOLUNA Server Framework for Java (5.x) Development Guideline 5.3.0.RELEASE documentation

ドメインモデルをコードへ落とす 〜あなたのクラスは、どこから?〜 - Qiita

GitHub - system-sekkei/isolating-the-domain: architecture sample using : Spring Boot gradle, Spring MVC, Thymeleaf, and MyBatis

構成

実装サンプルの中で個人的に一番しっくりくるのはTERASOLUNA
プロジェクト分割については好みの思考。

ValueObjectは、どの層からでも呼び出して良いフラットでパブリックなものだと思っていて、そのパッケージ構成って みんなどうしているのかな?と悩んで調べてみると、以前、DDDの勉強に参考にさせていただいた かとじゅん(@j5ik2o)さんのブログが参考になりそう。

Scalaコードでわかった気になるDDD | エンジニアブログ | GREE Engineering

ドメインモデルはユビキタス言語でグルーピングする

net.gree.xxx.domain.hunter  
 Hunter, HunterName, HunterRank

net.gree.xxx.domain.monster
 Monster

net.gree.xxx.domain.item
 Item, ItemService

MVC の Model 肥大化への対処 - Qiita

実装サンプルのフォルダ構成よりも、こちらの方がしっくりする。RepositoryEntityとの兼ね合いに悩みが生まれそうだけど、それは今後、自分で実装する中で考え直そうということで保留。

DAO

インピーダンス・ミスマッチを解決する、O/Rマッピングの設計

Form

Railsアプリケーションでフォームをオブジェクトにして育てる - クックパッド開発者ブログ

decorator, presenter, exhibit という3つの実装パターンについて - pospomeのプログラミング日記


クラス

同じようなPOJOだけど色々分類がされていて、その違いを考えるのに参考になる。

【JavaBeans】BeanとDTOとEntityとVOとFormの違いって何? - プログラマのはしくれダイアリー


モデリング

http://blog.amateur-factory.jp/?eid=1444289

www.slideshare.net


  • 2018/3/22 追記

私なりに、読み替えてみました。

  1. モデルはドキュメントではない
    ドキュメントのためのドキュメントではなく実現する手段であるってこと、かな?

  2. 最初からすべては見通せない
    徐々に組み立てていくもの

  3. モデリングは軽快なプロセスであるべき

  4. 要求は変化する
    要求には柔軟に対応する

  5. 設計も変化する
    設計も柔軟に変化する

  6. ツールを使うことがモデリングではない。
    手段は目的ではない。
    例えば、UMLで記述すればモデリングしたことになわけではない。

  7. モデリングは重要不可欠

  8. ドメインモデルを開発の中心に。

  9. 開発にはモデリングスキルが必要


その他(類似・未分類)

speakerdeck.com

www.slideshare.net

オブジェクト指向が難しく、わからないときの勉強方法【分かりやすく学習を進めるコツ】 - コーギーブログ

JSF(ManagedBean)

作成単位

コンポーネント単位(呼出元となるxhtml単位)。
またはユースケース単位(呼出元となるxhtmlが複数にまたがるケース)

個人的なこだわり

少し調べて見ると「ManagedBeanは画面単位で作成します」という表現を見かけることがある。
多くの場合、画面におけるメインコンテンツが1つ(1面?)となる場合はコンポーネント=画面になるので画面単位という整理で基本的に問題ないとは思っているが、その整理だとテンプレートやコンポーネントを組み合わせて構築するJSFコンポーネント指向という仕組みとピタッと一致した感じが無いように思う。

ユースケース単位というのは「一画面で実現出来うるオペレーションだけれども、ユーザビリティを考えると複数画面に分割した方が良いケース」を意図している。 ウィザード操作のように一連の操作が単純で会話型で進められるようなものは、xhtml単位でManagedBeanを作成すると資産が増えすぎてしまう。増える事自体が悪いというつもりはないけれど操作の順序性など必要以上に発散させるのも良くないと考える。この場合は「一連の操作」の目的単位でManagedBeanを作成することで操作の見通しが良くなると考える。


遷移時の情報共有は@ConversationScoped

画面遷移時の情報共有というか受け渡しにはFlash*1という仕組みもあるけれど、それは使わない。

個人的なこだわり

同一フロー(もしくは会話)内の情報の生存期間を管理する仕組みを統一しておきたい。ちょっとした受け渡しだからFlashで、といった場合の「ちょっとした」が、本当に「ちょっとした」で終わる保証がどこにも無いから。改修があった場合、多くのケースでは既存の仕組みを残して対応をしたくなる。例えば、始めは画面1から画面2への単純な遷移、かもしれないけれど、もし画面2から画面1に戻ったり(加えて画面2の状態を画面1に反映させたり)という要件が発生した場合、結構しんどくなることが想定される。いやいや、そんな、、と思うところはあるけれどSIerの現場だと聖域を犯すべからずという感じで起こりやすい。ちゃんと仕組みも含めて会話が出来ることを永劫に保証できるというのであれば問題ないと思う。
複数画面を跨る情報は会話スコープのBeanに格納して読み出すという整理であれば、上述のケースが発生しても問題なく対応できる。

なおFlashはダメという話ではない。基底となるFWは極力「何でも出来る」が望ましいと思っている。その上で利用局面を考えて、それぞれの利用者として制約を設けて品質を担保するのが良いという話。


リンク

JSFにおけるPostback、そしてライフサイクル - 理系学生日記

会話スコープとAjax - じゃばらの手記

*1: FacesContext.getCurrentInstance().getExternalContext().getFlash()

JSF(Form)

アイディアメモ(随時更新)

ViewForm

@Label

  • 独自のアノテーション@Labelはメッセージ出力時の対象項目名として使用する
  • 表示名は表示にのみ使用するものでありドメインでは無いと考えた
  • 表示名はResourceで管理する
  • クラスパスと同じフォルダ構成でファイルを作成する
  • ファイル名はクラス名と同じにする
  • aptコンパイル時にResourceが存在しない場合は警告を標準出力する(エラーにはしない)
  • Resourceが存在しない場合は表示ラベルとしては、フィールド名をそのまま出力する
  • デフォルトは同構造のパスに格納したものを使用するが、任意の文字列の指定も可能とする*2
    任意の指定をしている場合はResourceを使用しないので警告出力はしない。

画面表示アイテム

  • 固定文字はResourceで管理する。
  • Resourceコンポーネント単位で作成するか、Resourceのキーに画面名を付与してシステムで1つにする。JSFの仕組みで入力補完対象になることを考えたら1つにする方が良い。*3

*1:JavaScriptHTML5でプリミティブ型について、ある程度対応が出来ることは分かっているが、どこで正しくデータを保証するのか?というのを考えた結論として、クライアント(ブラウザ)ではなく、あくまでサーバーサイドで きちんと保証するのが正しいと考えた

*2:Resourceの恩恵は受けられないが、使い捨てシステムの場合には この仕組みを設けておくことで開発が楽にできる。

*3:悩みどころ。移植性を考えたらコンポーネント単位で作成になるけど、細かい資産が増えすぎることと、Resourceが多い事を嫌がる人がそこそこいるような気がする

CDIのメモ

全般

JavaEE7をはじめよう(13) - インジェクション候補が複数ある場合の対処方法 - エンタープライズギークス (Enterprise Geeks)

CDI(Contexts and Dependency Injection)まとめ - A Memorandum

なるほど!ザ・Weld | Exploring CDI extensions

@n_agetsu

パーフェクトJavaEECDIパートの著者でもあります。実際に何度か勉強会で話は聞かせていただいたこともあります。とにかく分かりやすいし聞きやすいです。

www.slideshare.net

www.slideshare.net

n-agetsuma.hatenablog.com

Java EE環境におけるCDIのデフォルト化 - 見習いプログラミング日記

CDIとiBATIS2.3を組み合わせる - 見習いプログラミング日記

CDIでアプリケーション設定をインジェクション - 見習いプログラミング日記

インジェクト

コンストラクタインジェクトをつかう

DIコンテナのインジェクション方法の使い分けについて - 日々常々

パーフェクトJavaEE:P47

@xxScopedには@Typedを忘れずに

パーフェクトJavaEE:P49

依存の注入ポイントとなる型(Interface)を明言した方が良さそう。Interfaceと実装が1対1であれば必ず限定できるけど、それだと何のためにDI使っているのか、という話になってしまう。また同じく複数の型(Interfaceや抽象クラス)から具象化されるクラスが意図せず1つという状態になるのも良くない。少なくともScopeを限定している具象クラスにおいては論理的に1対1しておいた方が良い。

なおテストを考えても@Typedを使った方が良い。

CDIでコンストラクタインジェクションしたい - CLOVER🍀

もう少し詳細な情報や使い方

Java EE 7 CDIを使う際の注意点──『Java EE 7徹底入門』番外編 第2回 - page2 - builder by ZDNet Japan

CDIビーンを動的に取得する - ksino's diary

CDIビーンを動的に取得するコードの単体テスト - ksino's diary

BeanManagerでCDIコンテナにアクセスする | なるほど!ザ・Weld

Java Examples for javax.enterprise.inject.spi.CDI

Java EEのCDIで定義しておくと便利なプロデューサーとインターセプタ - きしだのはてな

Java EEアプリケーションで起動時になにかしらの処理をする方法 — 裏紙

JavaSE環境

依存ライブラリが極力少ない方が良いと思うけど、CDIは使った方が良いと思う。JavaEEだけじゃなくてJavaSEでも。

JavaSE 環境でCDI(Weld)を使う - Qiita

JPAのメモ

全般

Java EE 8がそろそろ固まってきたのでJPA 2.2のJavaDocを日本語に翻訳し始めた(2/3完了) - 水まんじゅう2

JavaEE使い方メモ(JPA その1 - 基本) - Qiita

Red Hat JBoss Web Server 1.0 Hibernate Entity Manager リファレンスガイド - Red Hat Customer Portal *1

JavaEE Code探索 その3 〜 トランザクション属性 〜 - A Memorandum

JPA2.1でエンティティからインデックスを自動生成する - 水まんじゅう2

spring-data-jpa アンチパターン - Qiita

はじめてのJPAでちょっと怖い勘違い - ビールとプリンとプログラミング。

JavaEE7をはじめよう(9) - JPA TIPS - エンタープライズギークス (Enterprise Geeks)

EntityManager

JavaEE7をはじめよう(14) - Producerの効果的な利用方法 - エンタープライズギークス (Enterprise Geeks)

複数のEntityManagerを切り替える(on CDI) - edgegram

JAX-RS(Jersey)とJPAのサンプルにCDIを使ってTomcatで動かす - Qiita

JPAとJTAをJavaSE環境で使えるようにする: すふぃあの記憶

@RequestScopedにする。

トランザクション

JavaEE使い方メモ(JTA) - Qiita

Jerseyでリソースメソッドをトランザクション境界にする — 裏紙

大量処理

JPAで少しずつデータを処理する方法を考える - 見習いプログラミング日記

メモリを逼迫させずにJPAで大量データを取得する方法 - エンタープライズギークス (Enterprise Geeks)

Native Query

JavaEE7をはじめよう(5) - JPAクエリ(その2) Native Query - エンタープライズギークス (Enterprise Geeks)

SQL文を外部ファイルに | 老いぼれSEの艱難辛苦

Builderパターン

JPA Builder パターン

トランザクション

[Spring] 宣言的トランザクションがネストした時はどうする!? REQUIRES_NEWを使ってみた | DevelopersIO

わかりやすい JPA(12)楽観的ロックと悲観的ロック

作りたい共通部品

  • Listインターフェースを良い感じにパラメータとして設定できるようにする
    (とりあえず、数値と文字列だけ)
  • Listが空の場合はnullin()にならないようにする)*2
  • SQLの参照はパッケージをフォルダにする*3
  • JPABuilderをEntityの情報からAnnotationProcessorで自動生成
  • JPAの型情報からフィールド毎のBeanValidationをAnnotationProcessorで自動生成
    全体でフィールド名が重複している場合はエンティティ名を接頭文字につける。
    同じドメインにしたい場合は、アノテーションドメイン名を指定。重複している場合は「マージ」
    必須(NotNull)は対象外(集約であるEntityにとって必須という扱いと考えるから)
  • Eneityクラスからテーブル定義的(とりあえずhtml)なものをAnnotiontionProcessorで自動生成。
    (重複しているドメインがある場合、備考にその旨を追記すると後々ありがたい機能になる気がする。)

note

  • SQLファイル読み込みの仕組みはorm.xmlがあるけど使わない(リンクはメモ)。

その他

Spring Data JDBC Preview - Qiita

*1:仕様に目を通すのは大事

*2:Domaの2waySQLを参考

*3:Doma方式を参考