無限大な夢のあと

テニスとアニメが大好きな厨二病SEのブログ

Swift実践入門 ── 直感的な文法と安全性を兼ね備えた言語 10章「型の設計指針」

会社で書籍を購入して頂けたので、気になるところを拾い読みしています。

Swift実践入門 ── 直感的な文法と安全性を兼ね備えた言語 (WEB+DB PRESS plus)

Swift実践入門 ── 直感的な文法と安全性を兼ね備えた言語 (WEB+DB PRESS plus)

簡単に自分の理解をブログにまとめたいと思います。
なお、最近iOS開発を始めて、Swiftを始めたばかりなので、ひよこレベルです。

今回は10章の「型の設計指針」がテーマです。
大きく以下の3つの章で構成されています。

  1. クラスに対する構造体の優位性
  2. クラスの継承に対するプロトコルの優位性
  3. オプショナル型の利用指針

クラスに対する構造体の優位性

「クラスに対する構造体の優位性」については、iOS開発に入る前のチュートリアルとしてDDDで掲示板を作成した際に、社内の方がコードレビューで指摘してくださり、以下のリンクを参考にすれば良いと教えていただいたのを思い出し、また記事を読んでいました。
cockscomb.hatenablog.com

この段落では以下の例が挙げられていました。

  • 参照型のクラスがもたらすバグ
  • 値型の構造体がもたらす安全性
  • クラスを利用すべき時

構造体の不要なコピーを発生させない最適化として、内部ではコピーオンライトが使われているようです。
いわゆるプロセスをフォークして子プロセスを作った時に、子プロセスが実際に使われた際に初めてメモリを確保するというのと同じ原理です。

クラスの継承に対するプロトコルの優位性

「クラスの継承に対するプロトコルの優位性」については、以下の例が挙げられていました。

  • クラスの継承がもたらす期待しない挙動
  • プロトコルによるクラスの継承の問題点と克服
  • クラスの継承を利用すべき時

クラスの継承を利用すべき時の中で、複数の型の間でストアドプロパティの実装を共有するというところでプロトコルエクステンションがよくわかっていないかったのですが、理解が深まった気がします。
また、理解が浅かったことを実感し、5章の型の構成要素も読み直しました。

オプショナル型の利用指針

「オプショナル型の利用指針」については、以下の例が挙げられていました。

  • Optional型(?)を利用すべき時
  • ImplicitlyUnwrappedOptional型(!)を利用すべき時
  • 比較検討する時

ImplicitlyUnwrappedOptional型(!)を利用すべき時の例では、サブクラスの初期化より前にスーパークラスを初期化するというところではそうだよね、納得できるなと読んでいました。
また、比較検討する時では、安全性を取るか、厳密性を取るかという点も参考になりました。

11章以降も頑張りたい。

Swift実践入門 ── 直感的な文法と安全性を兼ね備えた言語 (WEB+DB PRESS plus)

Swift実践入門 ── 直感的な文法と安全性を兼ね備えた言語 (WEB+DB PRESS plus)

【書評】Androidアプリ開発 第2版 AndroidStudio2対応( @yyamada ) 

今回もWINGSプロジェクトの書籍レビュアーに応募し、献本してもらったので、書評を書きました。
WINGSプロジェクトの皆様、著者の山田様ありがとうございます。
今回は表題の書籍を献本していただきましたので、こちらのレビューをさせていただきます。

こちらのAndroidの書籍ですが、改訂前の書籍はAndroidの一番最初の書籍でした。
ただ、私のAndroidの経験は以下で、初心者レベルです。
Javaの文法はわかる。
・サンプルも動かしたことがない。
IntelliJ自体は実プロジェクトでは使っている。

ここから書籍の書評となります。
Chapter02の「初めてのAndroidアプリ」をMac上で手で動かして、実際に動作させるところまでを確認致しました。
そこ以外に関しては、サンプルを動かして書籍を拾い読みした感じです。

感想としましては、図を丁寧に用いて辞書的に読みやすくて、リファレンスとして使えるということです。
社内のAndroidが詳しい方に書籍の章立てについて意見を伺ったところ、基礎的なところは網羅しているので良い書籍ではないかとのことでした。

ただ、一つ気になった点としては、gradle local.propertiesに作者のファイルパスが載っていて警告が出る点については気になります。
加えて、サンプル自体が細かい粒度でzipになっていて、扱いずらかったです。
Githubなどにファイルを置いてくれると尚嬉しいかなと感じました。

今回は書籍を参考に下記のブログの内容のAndroidをRustで動かすのにチャレンジして、動かすことができました。
qiita.com

自社では実務でScalaAndroidでプロダクトコードを書いているので、今後はこの書籍をリファレンス的に使っていきたいと思います。

Scalaスケーラブルプログラミング第3版

Scalaスケーラブルプログラミング第3版

速攻理解!JavaプログラマのためのScalaプログラミング

速攻理解!JavaプログラマのためのScalaプログラミング

Scala@IntelliJで、不要なauthorコメントを削除する。

社内で毎週実施している輪読会で、チームギークを読む機会がありました。
その内容の中で、不要なauthorコメントを削除すべきという記述もあり、個人的にとても共感できた内容でした。
該当箇所はP56の以下の箇所です。
2章
2.8 エンジニアリングとしてのコミュニケーション
2.8.2 ソースコードに名前を書く(別名:「Authorタグ」問題)
です。

ソースファイルに名前を入れると、あくまでも僕たちの意見だが、百害あって一利なしだ。

具体例については、チームギークの中の書籍をご参照ください。

Team Geek ―Googleのギークたちはいかにしてチームを作るのか

Team Geek ―Googleのギークたちはいかにしてチームを作るのか

今回は実際にツール作成もしない簡単な手順で、IntelliJ@Macでこのauthorコメントを削除する手順を共有したいと思います。
また、今回対象のプロジェクトはScalaで書かれているものですが、少し応用すれば、他言語でも適用できるはずです。

実施手順としては以下です。

  1. IntelliJでshift+command+Rで置き換えダイアログを出す。
  2. Generalタブで「Regular expression」にチェックを入れる。
  3. Generalタブで「Case sensitive」からチェックを外す。
  4. Contextは「in comments」を選択。

以下のパターンをそれぞれ実行。

パターン1

  1. [Text to find:]に「^.*created by.*\n」を入力。
  2. [Replace with:]に空白を入力。
  3. 置換する。

パターン2

  1. [Text to find:]に「^.*created with.*\n」を入力。
  2. [Replace with:]に空白を入力。
  3. 置換する。

パターン3

  1. [Text to find:]に「^.*User:.*\n」を入力。
  2. [Replace with:]に空白を入力。
  3. 置換する。

パターン4

  1. [Text to find:]に「^.*Date: 2.*\n」を入力。※2を入れるのは他のものが誤って消されないようにするため
  2. [Replace with:]に空白を入力。
  3. 置換する。

パターン5

  1. [Text to find:]に「^.*Time:.*\n」を入力。
  2. [Replace with:]に空白を入力。
  3. 置換する。

パターン6

  1. [Text to find:]に「^.*Timestamp:.*\n」を入力。
  2. [Replace with:]に空白を入力。
  3. 置換する。

パターン7

  1. [Text to find:]に「^.*To change this.*\n」を入力。
  2. [Replace with:]に空白を入力。
  3. 置換する。

パターン8

  1. [Text to find:]に「/\*\*[\s]*?\*/」を入力。
  2. [Replace with:]に空白を入力。
  3. 置換する。

パターン9

  1. [Text to find:]に「/\*\*[\s]*?\*[\s]*?\*/」を入力。
  2. [Replace with:]に空白を入力。
  3. 置換する。

IntelliJのバージョンによって、authorコメントの書き方が違うので、上記のような手間のかかる手順となりました。
ぜひ活用してください。

[免責]
この手順の利用は自己責任でお願いします。
この手順を利用して起こったいかなる不都合も作者は保証しません。

Scalaスケーラブルプログラミング第3版

Scalaスケーラブルプログラミング第3版

Android Studio本格活用バイブル ~効率的にコーディングするための使い方

Android Studio本格活用バイブル ~効率的にコーディングするための使い方

Rust入門 #0 Macで開発環境構築 (2017/1/4時点)

※1/9に以下の対応を追加。

  1. メソッドジャンプをする対応方法をrustyを使う方法に変更。
  2. cargo-editをインストールする方法を追記。

皆様、あけましておめでとうございます。
2017年、よろしくお願い致します。

今年の一発目のブログはRustの開発環境構築です。
Rust自体は前職の方からも名前だけは聞いていたのですが、以下のちょっとしたきっかけで入門してみようと思いました。

  1. 社内のIoTチャレンジ部で、ラズベリーパイで遊んでいた時に、省メモリでかつ関数型っぽく記述できると話題に上がったこと。
  2. 書評レビューア募集で、Android開発の書籍を頂いたけど、 そのサンプルを新しい言語で動かしてみたいなと思ってみたこと。
  3. 王様達のバイキングの11巻で、ValkyrjaというクラッカーがScalaやRustでプログラム書いていたという話が出てきたこと。(←これが一番の理由w)

王様達のヴァイキング 11 (ビッグコミックス)

王様達のヴァイキング 11 (ビッグコミックス)

matome.naver.jp

また、2017/1/2時点でIntelliJのRustプラグインを用いても、メソッドのコード補完などもできないため、コード補完プラグインが存在するatomを用いることとします。

Macのスペック

  • マシン: MacBookPro (Retina,15-inch, Mid 2015)
  • OS: OS X EI Capitan 10.11.6
  • プロセッサ: 2.2 GHz Intel Core i7
  • メモリ: 16GB 1600 MHz DDR3

atom

  • バージョン 1.12.7
  • 日本語化対応済み


  1. Rustをインストール。選択肢では、1を選択。

    curl https://sh.rustup.rs -sSf | sh
    This path will then be added to your PATH environment variable by modifying the
    profile file located at:
    
      /Users/ユーザ名/.profile
    
    You can uninstall at any time with rustup self uninstall and these changes will
    be reverted.
    
    Current installation options:
    
       default host triple: x86_64-apple-darwin
         default toolchain: stable
      modify PATH variable: yes
    
    1) Proceed with installation (default)
    2) Customize installation
    3) Cancel installation
    


  2. 今回の手順では、.bashrcにPATHの記載を追加していく。
    ただし、Mac OS Xのデフォルトでは、HOMEに.bashrcを作成してもターミナル起動時に自動で読み込むようにはなっていないようなので、自動で読み込むように.bash_profileに以下の記述を追加。

    atom ~/.bash_profile
    if [ -f ~/.bashrc ] ; then
    . ~/.bashrc
    fi

  3. RustのパッケージマネージャーであるCargoのパスを通すために、~/.bashrcファイルに設定を追加。

    atom ~/.bashrc
    #Rust 
    export PATH="$HOME/.cargo/bin:$PATH"


  4. bashrcの設定を反映する。

    source ~/.bashrc


  5. rustc、cargo、rustupがインストールされたことを確認。

    rustc --version
    rustc 1.14.0 (e8a012324 2016-12-16)
    
    cargo --version
    cargo 0.15.0-nightly (298a012 2016-12-20)
    
    rustup --version
    rustup 1.0.0 (17b6d21 2016-12-15)


  6. 補完に必要なパッケージをインストールする。

    cargo install racer


  7. cargo .tomlを操作するのに便利なパッケージをインストールする。

    cargo install cargo-edit


  8. atomにRust用のプラグインとして、下記をインストールする。
    atom自体のインストールは省略。

    apm install language-rust
    apm install racer
    apm install linter
    apm install linter-rust
    apm install atom-ctags
    apm install script


  9. racerというRustのコード補完を行うプラグインで必要なため、Rustのソースコードを落とす。

    rustup component add rust-src


  10. atomを起動し、環境設定>Packagesで、racerの設定を開く。

  11. 下記の設定項目を入力する。※フルパスでないと動作しなかった。

    Path to the Racer executable

    /Users/ユーザ名/.cargo/bin/racer

    Path to the Rust source code directory

    /Users/ユーザ名/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/src


  12. メソッドジャンプを可能にするためにrusty-tagsを使用する。
    1. ctagsをインストール。

      brew tap universal-ctags/universal-ctags
      brew install --HEAD universal-ctags


    2. rusty-tagsをインストール。

      cargo install rusty-tags



  13. パッケージ管理を容易にできるcargo-editをインストール。

    cargo install cargo-edit


  14. 動作確認として、プロジェクト作成する。

    cargo new hello_world --bin


  15. Rustのコードを実行。
    1. コマンドライン

      cd hello_world/
      cargo run #Cargo.tomlのあるディレクトリで実行


    2. atom
      atomでファイルを開いている状態で、scriptプラグインのショートカット(Command+i)で実行する。


    これでRustの開発環境構築ができて、書き始められるはず!


    今回、参考にさせて頂いた公式チュートリアル/ブログ。

    はじめる

    • atomの導入について参考にさせて頂きました。

    qiita.com

    Scalaスケーラブルプログラミング第3版

    Scalaスケーラブルプログラミング第3版

    Programming Rust: Fast, Safe Systems Development

    Programming Rust: Fast, Safe Systems Development

    Atom実践入門──進化し続けるハッカブルなエディタ (WEB+DB PRESS plus)

    Atom実践入門──進化し続けるハッカブルなエディタ (WEB+DB PRESS plus)

    テキストエディタAtom入門 (OIAX BOOKS)

    テキストエディタAtom入門 (OIAX BOOKS)

【書評】改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで( @yyamada ) 

今回もWINGSプロジェクトの書籍レビュアーに応募し、献本してもらったので、書評を書きました。
WINGSプロジェクトの皆様、著者の山田様ありがとうございます。
今回は表題の書籍を献本していただきましたので、こちらのレビューをさせていただきます。

こちらのJavaScriptの書籍ですが、改訂前の書籍はJavaScriptの一番最初の書籍でした。
ただ、私のJavaScriptの経験は以下で、初心者レベルです。
・研修としてJavaScriptで課題をこなす(文法基礎、コンストラクタとクロージャー、クライアントJavaScriptクロージャー etc)
・実案件ではデモ画面に修正を加える。
・自分のアプリを作成するにあたり、Angular2+Bootstrapで軽く画面を作成。
・転職後に、DDD研修の際にクライアントサイドをAngular.jsで作成。

ただ、転職後にクライアントサイドを触る機会が増えるということで、今回改めてこちらの書籍でしっかりと勉強し直すというところです。
そして、このタイミングで、来月から管理画面のAngularJSに新規画面の追加チケットがあるので、絶好のタイミングです。

ここから書籍の具体的な内容の紹介として、セールスポイントを大きく3つさせていただきます。


①ES2015の記法を追加された箇所にマークが付いていて、分かりやすい。

ざっと読んで、以下の部分がES2015で追加された箇所となります。
・let
・const
・テンプレート文字列
・分割代入(配列/オブジェクト)
・for of 命令
・シンボルオブジェクト
・StringやNumber、Objectオブジェクトなどに追加されたメソッド
・Mapオブジェクト
・Setオブジェクト
RegExpオブジェクトのuフラグ(Unicodeサロゲートペアを認識できる)
・アロー関数
・引数のデフォルト値
・可変長引数
・...演算子
・名前付き引数
オブジェクト指向構文(class、オブジェクトリテラル、モジュール、イテレータ、ジェネレータ、Proxyオブジェクト)
・Promiseオブジェクト
etc

TypeScriptが先取りしたこともあり、これもJavaScriptでできるようになったんだという印象でした。


②GruntやBabelなど、トレンドを押さえている。

GulpやWebPackなどフロントエンドの進化はすさまじいですが、最初の走りだった(と認識している)Gruntを押さえている。
実際に現場に入る際には、現場で使っているツールを学ぶ前にそれがそもそもなぜ必要なのか、なぜ自分の現場ではその上で違うツールを使っているのかを考える際の材料/ヒントが書いているなぁという認識でした。
私は今まさにこれを読んで勉強しているところです。
ちなみにうちの現場ではプロダクトによって、Grunt+TypeScript or ES2015(Babel)となっています。



③図がふんだんに使われていて、説明がわかりやすい

これは改訂前からですが、初めて読んだ時は以下の説明などが図やスクリーンショットが多くわかりやすかったです。
ブラウザー付属の開発者ツール
・クエリ情報をエスケープする
・スコープチェーン
クラスタイプとプロトタイプのオブジェクト指向の違い
・mouseover/mouseoutとmouseenter/mouseleaveの違い
・フォーム全般
・イベントの伝搬(キャプチャ/ターゲット/パブリング)
Ajax全般

Ajaxとか初めての実装の時に最初にわかるまで苦労したなぁ(遠い目)



JQueryのコピペからの卒業にはぴったりの1冊なので、ぜひ皆さん手にとって読んでみてください。

ちなみに私がJavaScriptを学ぶ上で他に参考にした書籍を紹介いたします。ご参考までに。

文法よりの書籍だけど、全てがオブジェクトだということが分かる書籍。

開眼!  JavaScript ―言語仕様から学ぶJavaScriptの本質

開眼! JavaScript ―言語仕様から学ぶJavaScriptの本質

JavaScript本格入門とこいつを照らし合わせて、理解を深める。もはや辞書。

パーフェクトJavaScript (PERFECT SERIES 4)

パーフェクトJavaScript (PERFECT SERIES 4)

リファレンスとして使える。ES2015版のものも出ないかなー

改訂第5版 JavaScript ポケットリファレンス

改訂第5版 JavaScript ポケットリファレンス

DDDで掲示板を作るという研修で、仕事で初めて本格的にAngularJSでアプリを作ることになった際にかなり参考になった書籍。

AngularJS アプリケーションプログラミング

AngularJS アプリケーションプログラミング


以上、簡単ではございますが書評のレビューとさせていただきます。

「エリック・エヴァンズのドメイン駆動設計」を読んで(自分用メモ) 第2部 モデル駆動設計の構成要素(前半 4章-5章)

DDD導入研修の課題として、下記の書籍「エリック・エヴァンズのドメイン駆動設計」を読むことになりました。

エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)

エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)

本文章は上記の書籍を引用させて頂きます。


ただ漠然と読んでいるだけだと、頭を通りすぎていきそうなので、自分なりに要点や響いた箇所、メモを残しながら読んでいこうと思います。
「Domain-Drive Design Quickly」は約80ページしかありませんでしたが、こちらはボリュームが大きいので、覚悟しながら読もうと思います。

Kindle書籍からだとコピーできないため、簡単にまとめていきます。

☆第2部 モデル駆動設計の構成要素

・introduction

f:id:noimpslmtbrk:20160915132551p:plain

モデル駆動設計を構成する言語のナビゲーションマップとのことです。
まだ、中身の用語の定義が曖昧なままなので、ここは読んでいく上で何度も立ち戻りたい。


・第4章 ドメインを隔離する。

レイヤ化アーキテクチャ
f:id:noimpslmtbrk:20160915152220p:plain

・ユーザインタフェース(プレゼンテーション層)
 ユーザに情報を表示して、ユーザのコマンドを解釈する責務を負う。外部アクタは人間のユーザではなく、別のコンピュータシステムのこともある。


・アプリケーション層
 ソフト雨ケアが行うことになっている仕事を定義し、表現力豊かなドメインオブジェクトが問題を解決するように導く。このレイヤが責務を負う作業は、ビジネスにとって意味があるものか、あるいは他システムのアプリケーション層と相互作用するのに必要なものである。
 このレイヤは薄く保たれる。
 ビジネスルールや知識を含まず、やるべき作業を調整するだけで、実際の処理は、ドメインオブジェクトによって直下のレイヤで実行される共同作業に移譲する。ビジネスの状況を反映する状態は持たないが、ユーザやプログラムが行う作業の進捗を反映する状態を持つことはできる。


ドメイン
 ビジネスの概念と、ビジネスが置かれた状況に関する情報、およびビジネスルールを表す責務を負う。ビジネスの状況を反映する状態はここで制御され、使用されるが、それを格納するという技術的な詳細は、インフラストラクチャに移譲される。この層がビジネスソフトウェアの核心である。


・インフラストラクチャ層
 上位のレイヤを支える一般的な技術的機能を提供する。これには、アプリケーションのためのメッセージ送信、ドメインのための永続化、ユーザインターフェースのためのウィジェット層などがある。インフラストラクチャ層は、ここで示す4層間における相互作用のパターンも、アーキテクチャフレームワークを通じてサポートすることもある。


プロジェクトによっては、ユーザインタフェースそうとアプリケーション層を厳密に区別しないこともある。また、複数のインフラストラクチャ層を持つこともある。しかし、ドメイン層を分離して初めて、モデル駆動開発が可能になるのだ。

ここは各レイヤの説明と共に残しておく。

複雑なプログラムはレイヤに分割すること。各レイヤで設計を進め、凝集度を高めて下位層にだけに依存するようにすること。
標準的なアーキテクチャーパターンに従って、上位のレイヤに対しては疎結合にすること。
ドメインモデルに関係するコード全部を1つの層に集中させ、ユーザインタフェース、アプリケーション、インフラストラクチャのコードから分離すること。
表示や格納、アプリケーションタスク管理などの責務から解放されることで、ドメインオブジェクトはドメインモデルを表現するという責務に専念できる。これによって、モデルは十分豊かで明確になるように進化し、本質的なビジネスの知識を捉えて、それを機能させることができるようにする。

ここも実際に適用する際のメモとして、残しておく。

レイヤを関係づける

レイヤ同士は疎結合であるべきで、設計の依存関係は1方向にだけ向けられる。
上位のレイヤは下位のレイヤにある要素を直接使用した入り、操作したりできる。

下位のレイヤにあるオブジェクトが上方と通信が必要な場合は、コールバックやオブザーバといったようなレイヤ同士を関係づけるためのアーキテクチャーパターンである。

ここも原理原則ではあるが、メモ。

利口なUI「アンチパターン

アプリケーション処理をドメイン層から分離したくないパターン

■利点
・ 単純なアプリケーションの場合、生産性が高く、すぐに作れる。
・ それほど有能でない開発者でも、この方法ならほとんど訓練しないで仕事ができる。
・ 要求分析が不足していても、プロトタイプをユーザに公開し、その要望を満たすように製品を変更することで、問題を克服できる。
・ アプリケーションが互いに分離しているので、小さなモジュールの納品スケジュールは比較的正確に計画できる。単純な振る舞いを付け加えるようなシステムの拡張であれば、容易に対応できるだろう、
・ 関係データベースはうまく機能し、データレベルでの統合が実現される。
・ 4GL ツールが実にうまく機能する。
・ アプリケーションが引き継がれた場合、保守プログラムは自分が理解できない部分を素早く作り変えられる。変更による影響が、それぞれ特定のユーザインタフェースに限定されるからだ。

■欠点
・ アプリケーションの統合は困難で、データベースを経由させるしかない。
・ 振る舞いが再利用されることも、ビジネスの問題が抽象化されることもない。ビジネスルールは、適用先の操作それぞれで複製されることになる。
・ 迅速なプロトタイピングやイテレーションを行おうとしても、自然と限界に行き当たる。抽象化が欠けているために、リファクタリングの選択肢が制限されるからだ。
・ 複雑さによって、すぐに覆い尽くされてしまうので、成長しようとしても、単純なアプリケーションを追加することしかできない。より豊かな振る舞いが実現できるようになるといった、優雅な道は存在しない

Viewにロジックが混ざったみたいな状況のことを指しているということみたい。
ドメイン駆動設計とは反対の思想で大規模で複雑なものには採用するべきではない。


・第5章 ソフトウェアで表現されたモデル 

あるオブジェクトは、状態が異なったり、さらに別々の実装をまたいだ入りしたとしても追跡されるような、連続性と一意性を持ったものを表現しているのか?
それとも、他の何かの状態を記述する属性なのか?
これがエンティティと値オブジェクトとの基本的な区別である。
なんらかのパターンに従うオブジェクトを定義することで、そのオブジェクトは曖昧ではなくなり、強固な設計を行うための具体的な選択に向かう道筋が整えられる。

エンティティと値オブジェクトの話は、後でも説明は出ると思うけど、ここは押さえておく。

次に、ドメインの側面によっては、オブジェクトとしてよりも、アクションや操作として表現した方が明確になるものもある。
オブジェクト指向モデリングの伝統からやや外れるが、これらについてはサービスで表現して、操作を行う責務をエンティティや値オブジェクトに押し付けない方が適切であることも多い
サービスとは、要求に応じてクライアントのために行われる何かである。ソフトウェアの技術的なレイヤーには多くのサービスがある。また、サービスはドメインにも登場する。その際にモデル化されるのは、ソフトウェアが実行すべきことに対応し、状態には対応しないような活動だ。

まだここはピンとこない。

最後に、モジュールに議論することによって、設計上のあらゆる意志決定は、ドメインについてのなんらかの洞察によって動機付けられないければならないという点を強調する。
高凝集と低結合という考え方は、しばしば技術的な指標と考えられているが、概念そのものにも適用できる。モデル駆動設計においては、モジュールはモデルの一部であり、ドメインにおける概念を反映していなければならない。

ここは一旦メモ。

■関連
関連をもっと扱いやすくするには、少なくとも3つの方法がある。
1.関連をたどる方向を強制する。
2.限定子を付加して、多重度を効果的に減らす。
3.本質的ではない関連を除去する。

ここも一旦メモ。

■エンティティ(参照オブジェクト)

オブジェクトモデリングを行うと、我々はオブジェクトの属性に集中しがちだが、エンティティの根本的な概念は抽象的な連続性である。
この連続性はエンティティのライフサイクルを通じて続き、エンティティが多様な形を取っても変わることがない。

オブジェクトの中には、主要な定義が属性によってなされないものもある。そういうオブジェクトは同一性のつながりを表現するのであり、その同一性は、時間が経っても、異なる形で表現されても変わらない。そういうオブジェクトは属性が異なっていても、他のオブジェクトと一致しなければならないことがある。
また、あるオブジェクトは、同じ属性を持っていたとしても、他のオブジェクトと区別しなければならない。同一性を取り違えるとデータの破損につながりかねない。

同一性が一つのキーワードかな。

他方、モデル中の全てのオブジェクトが、意味のある同一性を持ったエンティティであるとは限らない。この問題を複雑にしているのは、オブジェクト指向言語が、あらゆるオブジェクトに「同一性」の演算を組み込んでいるという事実である。(Javaの=演算子など)
これはメモリ中の位置の比較やその他の仕組みによって実現される。その意味で、全てのオブジェクトインスタンスは同一性を持っている。
例えば、Javaの実行環境を作成するドメインや、リモートオブジェクトをローカルでキャッシュする技術的なフレームワークドメインであれば全てのオブジェクトインスタンスがまさにエンティティになるだろう。
しかし、この同一性の仕組みはほかのアプリケーションドメインでは意味をなさない。
同一性は、エンティティの持つ巧妙な意味のある属性であり、プログラミング言語の持つ自動化された機能は引き継げないのである。

最後の1文だけ頭に残しておく。

あるオブジェクトが属性ではなく、同一性によって識別されるのであれば、モデルでこのオブジェクトを定義する際には、その同一性を第一とすること。クラスの定義をシンプルに保ち、ライフサイクルの連続性と同一性に集中すること。クラスの定義をシンプルに保ち、ライフサイクルの連続性と同一性に集中すること。形式や履歴に関係なく、各オブジェクトを識別する手段を定義すること。オブジェクト同士を突き合わせる際に、属性を用いるよう求めてくる要件には注意すること。各オブジェクトに対して結果が一意となることが保証される操作を定義すること。これは一意であることが保証された記号を添えることで、おそらく実現できる。この識別手段は外部に由来する場合もあれば、システムによってシステムのために作成される任意の識別子の場合もあるが、モデルにおける同値性の区別とは一致しなければならない。モデルは同じものであるとうことが何を意味するかを定義しなければならない。

ライフサイクルの連続性というのが頭に?が浮かんでいる。

・エンティティをモデル化する。
オブジェクトをモデル化する時に、属性について考えるのは自然なことであり、その振る舞いについて考えることにも極めて重要だ。
しかし、エンティティにとって最も基本的な責務は、振る舞いが明確で予測可能になるよう、連続性を確立することである。
これが一番うまくいくのは、余計なものがない状態が保たれている時だ。
属性や振る舞いに集中するよりは、エンティティオブジェクトの定義を最も本質的な特徴にまで削ぎ落とすこと。

連続性を確立することというのが、いまいちピンとこない。
また、同一性のための操作を設計するというのは現実の問題と照らしわせると難しい。


■値オブジェクト(VALUE OBJECTS)

多くのオブジェクトには概念的な同一性がない。そういうオブジェクトは、物事の特徴を記述する。

モデルで最も目立つオブジェクトが、通常はエンティティであり、また各エンティティの同一性を追跡することが非常に重要であることから、あらゆるドメインオブジェクトに同一性を割り当てようと考えるのは自然なことである。実際、フレームワークの中には、あらゆるオブジェクトに一意のIDを割り当てるものもある。

エンティティの同一性を追跡するのは本質的なことだが、それ以外のオブジェクトに同一性を与えてしまうと、システムの性能を損なうことにアンリ、分析作業が増え、さらに、全てのオブジェクトの見た目が同じになってしまうことでモデルが台無しになりかねない。
ソフトウェア設計は、複雑さとの恒常的な戦いである。
特別な処理が必要な場所だけで行われるように、区別しなければならない。
しかし、このオブジェクトのカテゴリを、単に同一性のないものとみなしてしまうと、我々の使えるツールや語彙は大して増えない。
実のところ、これらのオブジェクトには、独自の特徴とモデルに対する独自の意味がある。これは物事を記述するオブジェクトなのだ。

あるオブジェクトが、ドメインにおける記述的な側面を表現し、概念的な同一性を守らない場合、そういうオブジェクトは値オブジェクトと呼ばれる。
値オブジェクトがインスタンス化される際に表現しようとするのは、何であるかだけが問題と成り、誰であるか、あるいはどれであるかは問われないような設計の要素である。

本書の中に例があったので、そこで何とか理解。

値オブジェクトは、しばしば、オブジェクト間のメッセージでパラメータとして渡される。一過性のことも多く、操作のために生成されては破棄される。
また、エンティティ(および他の値オブジェクト)の属性として使用される。人は同一性のあるエンティティとして、モデル化されるかもしれないが、その人の名前は値オブジェクトである。

あるモデル要素について、その属性しか関心の対象とならないのであれば、その要素を値オブジェクトとして分類すること。値オブジェクトに、自分が伝える属性の意味を表現させ、関係した機能を与えること。値オブジェクトを不変なものとして扱うこと。
同一性を与えず、エンティティを維持するために必要となる複雑な設計を避けること。

エンティティか値オブジェクトかを決めるための説明って感じ。

値オブジェクトを可変であることを許可する方が良い場合

・値が頻繁に変化する場合
・オブジェクトの生成や削除が高くつく場合
・置き換えによって(修正ではなく)クラスタリングが妨げられる場合(前述の例で説明)
・値が共有することがあまりない場合、またはクラスタリングを改良するためや他の技術的理由からそういう共有を見合わせる場合

今後、自分で設計するにあたってのメモ。

・値オブジェクトを含む関連を設計する

値オブジェクト同士の双方向の関連は完全に取り除くように試みること

ここはメモ。

■サービス

時には、単純に「物」とはできないこともある。
場合によっては、設計をできる限り明確にしつつ、実践的に進めて行くと、概念的にどのオブジェクトにも属さないような操作が含まれることがある。
強引に決着をつけるのではなく、問題領域にひかれる自然な輪郭に従って、モデルの中に明確にサービスを含めれば良い。

サービスの冒頭の説明

ドメインから生まれる概念の中には、オブジェクトしてモデル化すると不自然なものもある。
こうしたドメインで必要な機能をエンティティや値オブジェクトの責務として押し付けると、モデルに基づくオブジェクトの定義を歪めるか、意味のない不自然なオブジェクトを追加することになる。

サービスとは、モデルにおいて独立したインターフェースとして提供される操作で、エンティティと値オブジェクトのようには状態をカプセル化しない。
サービスは技術的なフレームワークでは一般的なパターンだが、ドメイン層にも適用できる。

サービスという名前は他のオブジェクトとの関係性を強調している。
エンティティや値オブジェクトとは異なり、純粋にクライアントに対して何が実行できるかという観点から定義されるのだ。
サービスは、実体よりも活動、つまり名詞よりも動詞にちなんで命名される傾向がある。

サービスは節度を持って使用すべきで、エンティティと値オブジェクトから全ての振る舞いを奪ってはならない。
しかし、実際に、操作が重要なドメインの概念なのであれば、サービスはモデル駆動設計の自然な一部を形成する。

サービスとはモデルを持たない振る舞いを持つもので、純粋にクライアントに対して何が実行できるかという観点から定義されるもの。

優れたサービスには3つの特徴がある
1. 操作がドメインの概念に関係しており、その概念がエンティティや値オブジェクトの自然な一部ではない。
2.ドメインモデルの他の要素の観点からインターフェースが定義されている。
3.操作に状態がない。

ここで状態がないというのは、どのクライアントでも得てのサービスのインスタンスを使うにあたって、インスタンスの持つ個々の履歴を気にする必要がない。という意味である。
サービスを実行すると、グルーバルにアクセス可能な情報を使用し、そのグローバルな情報を変更することもあるかもしれません。(つまり副作用がある。)
しかし、ほとんどのドメインオブジェクトが持っているような、オブジェクトの内部にあって、自身の振る舞いに影響を与える状態は、サービスには存在しない。

ドメインにおける重要なプロセスや変換処理が、エンティティや値オブジェクトの自然な責務ではない場合、その操作はサービスとして宣言される独立したインターフェースとしてモデルに追加すること。
モデルの言語を用いて、インターフェースを定義し、操作名が必ずユビキタス言語の一部になるようにすること。
サービスには状態を持たせないこと。

うん、何となくわかってきた。

・サービスと隔離されたドメイン
このパターンは、ドメインにおいてそれ自体が重要な意味を持つサービスに焦点を絞っているが、もちろん、サービスはドメイン層だけで使用されるのではない。
ドメイン層に属するサービスを他のレイヤーから区別することと、その区別をはっきり保つように責務を分解することには、注意が必要である。

多くのドメインサービスやアプリケーションサービスは、エンティティと値オブジェクトで構成される集合体の上に構築され、ドメインに本来備わっている能力をまとめあげて、実際に何らかの処理を行うスクリプトのように振る舞う。

ドメイン層だけで使用されるものではないこともメモ。

・粒度
このパターンの議論では、概念をサービスとしてモデル化することで得られる表現力を強調しているが、このパターンはクライアントをエンティティと値オブジェクトから分離する手段としても、ドメイン層のインターフェースの粒度を制御する手段としても価値がある。

中粒度で状態を持たないサービスは、巨大なシステムで再利用しやすい。
これは、重要な機能をシンプルなインターフェースの後ろにカプセル化しているためだ。
また、細粒度のオブジェクトは、分散システムにおいては、非効率的なメッセージングにつながるかもしれない。

前述した通り、細粒度のドメインオブジェクトを用いると、ドメイン層からアプリケーション層は、ドメインオブジェクトの振る舞いが組み合わされる場所だからだ。
極めて詳細なレベルでの相互作用が複雑であるため、結局アプリケーション層で処理されることになり、ドメインの知識がアプリケーションやユーザインタフェースコードに這い出るのを許して、その知識はドメイン層から失われてしまう。
ドメインサービスを慎重に導入すれば、複数のレイヤ間で境界を鮮明に維持できる。
このパターンでは、クライアントの操作や用途の広さよりも、インタフェースの単純さが優先される。
また、このパターンより、巨大なシステムや分散システムでコンポーネントをパッケージングするのに、非常に便利な中粒度の機能が提供される。
そして、サービスが、ドメインの概念を表現するのに最も自然な方法であることもある。

中粒度で定義されるべきって感じで良いかな?
ここは何度も自分で設計して経験していかないと実感していけない。


■モジュール(パッケージ)

モジュールを選択する際には、システムに関する物語を伝え、概念の凝集した集合を含んでいるものを選ぶこと。
こうすることで、モジュール間は低結合になることが多い。

モジュールには、ユビキタス言語の一部になる名前をつけること。
モジュールとその名前はドメインに対する洞察を反映していなければならない

当たり前のことだけど、低結合、高凝集がキーワード。

大量のリファクタリングを行う開発者でも、プロジェクトの初期に考え出したモジュールで満足する傾向にある。

今後、ここを見直すというのも視野に入れていこう。

・インフラストラクチャ駆動パッケージングの落とし穴
ティア化アーキテクチャーでは、モデルオブジェクトの実装が断片化されるかもしれない。

別々のサーバにコードを分散させようという意図が実際にない限り、単一の概念オブジェクトを実装するコードは全て、同一のオブジェクトにならなくても、同一のモジュールにまとめること。

ドメイン層を他のコードから分離するためにパッケージングを使用すること。そうでなければ、ドメインの開発者にできる限り選択の余地を残し、モデルと設計上の選択をサポートするように、ドメインオブジェクトをパッケージングできるようにすること。

ティア化とは、責務が断片化された状態のこと。
中規模Web開発のためのMVC分割とレイヤアーキテクチャ - Qiita


モデリングパラダイム

オブジェクト指向が主流になっているシステムに、非オブジェクトの要素を混ぜ合わせるための経験則を4つあげよう。
・実装パラダイムと対立しないこと
  ドメインに関する別の考えは常にある。パラダイムに合うモデルの概念を見つけること。
ユビキタス言語に頼ること
ツール間に厳格なつながりがない場合でも、言語を一貫して使用すれば、設計の各部分が分かれて行ってしまうことはない。
UMLにこだわらないこと
UML図のようなツールに固執すると、容易に描けるものに合わせてモデルがゆがめられることがある。
 例えば、UMLには制約を表現する機能が確かにあるが、常にそれで十分とは限らない。
 別の作図スタイル(他のパラダイムでは一般的かもしれない)を選んだり、単純な自然言語で記述したりした方が、オブジェクトの特定の見方を示すことを意図された作図スタイルを、無理に適合させるよりは良い。
・懐疑であること
 ツールは本当に相応の働きをしているか?ルールがあるからといって、ルールエンジンを使うオーバーヘッドが必要とは限らない。
 ルールは多少わかりにくくはなるにしても、オブジェクトとして表現できるが、パラダイムを複数持つことで、事態は極めて複雑になるのだ。

ここはメモ。


脳が疲れる泣

続いて、第2部 モデル駆動設計の構成要素(後半 6章-7章) 頑張ります。

アナリシスパターン―再利用可能なオブジェクトモデル (Object Technology Series)

アナリシスパターン―再利用可能なオブジェクトモデル (Object Technology Series)

  • 作者: マーチンファウラー,Martin Fowler,堀内一,友野晶夫,児玉公信,大脇文雄
  • 出版社/メーカー: ピアソンエデュケーション
  • 発売日: 2002/04
  • メディア: 単行本
  • 購入: 7人 クリック: 89回
  • この商品を含むブログ (70件) を見る
実践ドメイン駆動設計 (Object Oriented SELECTION)

実践ドメイン駆動設計 (Object Oriented SELECTION)

ドメイン駆動 (Programmer’s SELECTION)

ドメイン駆動 (Programmer’s SELECTION)

ビジネスパターンによるモデル駆動設計

ビジネスパターンによるモデル駆動設計

「エリック・エヴァンズのドメイン駆動設計」を読んで(自分用メモ) 第1部 ドメインモデルを機能させる

DDD導入研修の課題として、下記の書籍「エリック・エヴァンズのドメイン駆動設計」を読むことになりました。

エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)

エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)

本文章は上記の書籍を引用させて頂きます。


ただ漠然と読んでいるだけだと、頭を通りすぎていきそうなので、自分なりに要点や響いた箇所、メモを残しながら読んでいこうと思います。
「Domain-Drive Design Quickly」は約80ページしかありませんでしたが、こちらはボリュームが大きいので、覚悟しながら読もうと思います。

Kindle書籍からだとコピーできないため、簡単にまとめていきます。

■第1部 ドメインモデルを機能させる

・Intordcution

ドメイン駆動設計におけるモデルの有用性
 1.モデルと設計の確信が相互に形成し合う。
 2.モデルは、チームメンバ全員が使用する言語の基盤である。
 3.モデルとは、蒸留された知識である。

ここも一応メモ。
後ろの章を読むと、より理解度が上がる気がするので。

・第1章 知識を噛み砕く

効率的なモデリングの要素
 1.モデルと実装を結びつける。
 2.モデルにもど突いて言語を洗練させる。
 3.知識豊富なモデルを開発する。
 4.モデルを蒸留する。
 5.ブレインストーミングと実験を行う。

ここの手順はメモとして残しておく。

知識豊富な設計

モデルによって捉えられる知識は「名詞を見つける」ことにとどまらない。
ビジネスの活動やルールも、ドメインに含まれるエンティティと同じように、ドメインにとって中心的なのだ。

エンティティや値を超えて、その先に行こうとする、このような動きに伴った時こそ、知識の嚙み砕きは力を発揮できる。
通常、ドメインエキスパートは、自分の頭の中で起きているプロセスがいかに複雑化を意識することなく、仕事をする中でこれのルールを全て調べて矛盾を調整し、常識で考えて隔たりを埋めている。だが、こういうことはソフトウェアにはできない。
ソフトウェアエキスパートと密接に協力する中で、知識を噛み砕くことによって初めて、ルールが明確となり、具体化されて、折り合いがつけられるか、あるいはスコープの対象外とされるのである。

「名詞を見つける」ことにとどまらないということに少しドキッとした。
ドメインエキスパートとともに知識を噛み砕いて、明確化していくということが大事。

・第2章 コミュニケーションと言語の使い方

声に出してモデリングする

モデルを改良する最適な方法の1つは、話して見ることだ。考えらえるモデルのバリエーションから生じる様々な概念を、声に出して構成してみる。荒削りな表現は聞けば、すぐわかる。

ここは例を見て、そうだなと思った。
実践してみよう。

「彼らには抽象的すぎる。」
「オブジェクトがわかっていない。」
「彼らの用語法に従って要求を集めなければならない。」

豊富な知識を持つドメインエキスパートがモデルを理解できないとしたら、モデルに何か問題があるのだ

ここは現場ではよくありそう。
解決策の一つとして、ユビキタス言語を作っていくというのはあるのか。

設計に関する本質的な詳細は、コードにおいて捉えらえる。

同意。

常に覚えていてほしいのは、モデルは図ではない。

モデルを伝える手段の一つが図であるだけ。

ドキュメントはコードや会話での表現を補わななければならない

そうあるべきだと思う。

すでにコードがうまくやっていること、ドキュメントでもやろうとするべきではない

受託開発でよく作るいわゆる詳細設計書かな。
これらは納品物ということで必要なだけで、いわゆる基本設計書相当のドキュメントがWikiなどに残っていればそれで十分。


・第3章 モデルと実装を結びつける

ソフトウェアシステムの一部を設計する際には、紐付けが明らかになるように、ドメインモデルを文字通りの意味で忠実に反映させること。
モデルについて、再検討し、より自然いソフトウェアに実装されるように修正すること。
これはドメインに対するより深い洞察を反映させようとする時にも言える。強固なユビキタス言語を支えることに加えて、ドメインと実装両方の目的に使える単一のモデルを要求すること

ここは繰り返し記述されていることだが、単一のモデルということに着目。

設計で使用する用語法と責務の基礎的な割り当てをモデルから引き出すこと。
コードはモデルの表現となるから、コードに対する変更はモデルに対する変更になるかもしれない。
その影響は、プロジェクトの他の活動全体へと適宜伝わっていかなけければならない。
実装を一分の狂いもなくモデルに結びつけるには、通常、オブジェクト指向プログラミングのようなモデリングパラダイムをサポートする、ソフトウェア開発のためのツールと言語が必要である。

モデルを元に実装も行っていきましょうという話。
実際問題、コード設計に入った時にトランザクション境界で色々考えなければいけないが、そこは設計パターンみたいな解決のアプローチがあるのかな。

第2部 モデル駆動設計の構成要素 へ続く。

実践ドメイン駆動設計 (Object Oriented SELECTION)

実践ドメイン駆動設計 (Object Oriented SELECTION)

ドメイン駆動 (Programmer’s SELECTION)

ドメイン駆動 (Programmer’s SELECTION)

ビジネスパターンによるモデル駆動設計

ビジネスパターンによるモデル駆動設計