ルール9(getterを使用しない)を考える

ttomioka.hatenablog.com

先日行ったセミナーでオブジェクト指向エクササイズのルール9(getterを使用しない)が曖昧だったと感じたので、課題を仮定して考えてみました。OOエクササイズの一つの考え方としてにご覧下さい。

課題について

商品価格、数量、割引率があって総合価格(割引後価格)を計算する。
ただこれだけでは不足なので、次のルールも加える。

  • 注文は1商品のみしかできない。ただし複数量は注文できる。
  • 注文には必ず割引がある。
  • 割引額は通常価格 x 割引率。小数点以下は四捨五入。
    通常価格は商品価格 x 数量。通常価格-割引額が割引後価格。

エクササイズ

第0段階 最初の思いつき

一番初めではないがここは通りそうな道。

f:id:tmk463:20160602115044p:plain

ちなみに注文の計算するコード。
注文に必要な値を全てgetして計算している。

public int 割引後価格を計算する() {
    int 商品価格 = product.getPrice().getValue();
    int 数量 = quantity.getValue();
    BigDecimal 割引率 = discountRate.getValue();

    int 通常価格 = 商品価格 * 数量;
    int 割引 = BigDecimal.valueOf(通常価格).multiply(割引率)
                                   .setScale(0 ,RoundingMode.HALF_UP).intValue();
    int 割引後価格 = 通常価格 - 割引;
    return 割引後価格;
}

注文に計算ロジックがまとまっているが、集中しすぎている。
今後肥大化しすぎて手に負えなくなる可能性が高い。

第1段階 不足している概念を追加1

このままでは概念が不足しているので「通常価格」を導入する。
通常価格は商品価格x数量なので、商品に計算を依頼できるようにする。

f:id:tmk463:20160602115920p:plain

これで商品と商品価格のgetterを撲滅。
ただし通常価格にgetterが増えた。

第2段階 不足している概念を追加2

続いて「通常価格」と同様に「割引後価格」を導入する。
割引後価格は割引率がからむので、割引率に計算を依頼できるようにする。

f:id:tmk463:20160602120638p:plain

これで割引率のgetterを撲滅できた。

この段階の注文の計算コード。

public DiscountedPrice 割引後価格を計算する() {
    UsualPrice 通常価格 = 商品.通常価格を計算する(数量);
    DiscountedPrice 割引後価格 = 割引率.割引後価格を計算する(通常価格);
    return 割引後価格;
}

getせずに割引後価格を求められている。
また通常価格と割引後価格があるということを、コードで表現できた。

ここで終わってもいい気がするが、
まだ数量と通常価格にgetterは残っているので続行。

第3段階 最後のgetterを削除

数量と通常価格のgetterを削除したいが、ここからが難しい。
最終的に何らかの計算はしないといけないので自クラスで保持している以外の値が必要になる。
迷った結果、掛算をするメソッドを導入した。

f:id:tmk463:20160602121420p:plain

これで数量、通常価格のgetterを撲滅できたが、
ルール3(すべてのプリミティブ型文字型をラップすること)違反になった。

ただ、内部状態をさらすというカプセル化違反からは脱却できた。
何かと掛け算して使われるということも把握できる。(少なくとも自由奔放には使われない)

この他に検討した内容については次の通り。

  • intを返さずに通常価格オブジェクトを返すようにする。
    • 数量になんでもint型を渡すと通常価格を計算できるという解釈が
      生まれてしまう気がするので避けた。
  • 商品価格自体を渡してしまう。
    • 結局は数量の中でgetしてしまうので問題が解決しない。
  • getValue()ということではなくintValue()のように型を制限した形にする。
    • 内部状態をさらしていない解釈もできるのでよいのかもしれない。
      ただ用途があまり制限されないので今回は避けた。

とりあえず、getterを使わないを達成できたので終了。

振り返り

  • 第2段階まではスッとできた。
    足りないクラスやメソッドを導入することで、コードに知識が広がるしgetterの削除につながる。
  • 第3段階ではどの道に行ってもプリミティブ型を受け取ったり返したりする案しかうかばなかった。
    Valueオブジェクトとしてルール3違反はどうしようもないかもしれない。
    仕方が無いというのが現時点での結論。もっとエレガントな方法があるのだろうか。

「Java Day Tokyo 2016」へ行った

先日参加したのでまとめを書きます。

基調講演

所感

  • 特に衝撃的な話は無かった気がする。本日のセッションのカタログショー的な感じ。
  • CEOの話がレベル高すぎてついていけなかった。
  • 損保さんがCOBOL→JavaEEでリプレイス。
    巨大な会社が旧資産を刷新する美談ともとれるが、
    そこで喜んでしまうのはレベルが低い気もする(そこを自慢しに来たわけではないが…)。
    ただ巨大な会社を知っている人からすれば、やはり凄いことか。
    新技術も取り入れて、積極的にITに取り組むユーザー会社の責任者さんがいたことは
    喜ばしいこと。
  • ドローンのデモは引きつけられた。
    ソフトウェアOnlyではああいう感じのことはできない。うらやましい。
    昨年ペッパーのデモやっていて「なんだこれ」と思ったけれど、
    そこそこ売れたみたいだったからドローンも。

1-A Java SE 9 Overview

メモ

  • Java9
    • Jigsawの話。OpenJDKで確認を。
    • GCはG1がデフォルト。
    • バージョニングがJDK9.○.○。
    • JShell。インタラクティブにコマンド実行できるもの。
    • インターナルAPIを削除していく。sun.misc.など。
  • Java9以降
    • value型の導入。10or11。
    • JNIの改善版。プロジェクトパナマなど。

所感

  • Java9は来年。Jigsawがやはりメイン。
    Java8みたいに標準ライブラリが相当変わるというタイプの変更は少なめか。
  • value型はその次の中心的な話題になるのだろう。

2-A Project Jigsawではじめるモジュール開発

メモ

  • Jigsawが必要になった背景や変遷の話。
  • module,requires,exportなど具体的な使用方法。

所感

  • Jigsawの雰囲気が少しつかめた。
  • モジュールに対応したビルドはどうなるのか気になる。
    Mavenのセントラルリポジトリにmoduleが追加されるのか?

3-C Java Concurrency, A(nother) Peek Under the Hood

メモ

  • 直接並列処理を書いていなくても、多かれ少なかれ並列処理を意識する必要はある。
  • ルールとして覚えてもダメ。原理をわかった方が効率的。
  • Javaのメモリモデル。happened-beforeなど。
  • 抽象度の高いAPIから使っていく。volatileよりjava.util.concurrentを優先。

所感

  • 並列処理についてちゃんと基礎部分を聞けた貴重な体験だった。

4-E 実践して分かったJavaマイクロサービス開発

メモ

  • マイクロサービスは目指すのではなく結果論。
  • デプロイの自動化は必須。
  • 巨大なSQLがドメイン分割できない足かせ。
  • マイクロサービスありきではなく、自組織に合わせた最適化が必須。

所感

  • 現場の経験を語っていただけたことが何よりありがたい。
  • 巨大なSQL→悪ではなく、
    それを書かなくてはいけないドメイン設計やデータ設計が悪な気がする。

5-D オラクルコンサルが語るJava SE 8新機能の勘所

メモ

  • Date And Timeやラムダ式やStreamを使っても、
    基本的に大きくパフォーマンスやメモリ使用量などを損なわない。

所感

  • (当然かも知れないが)分析が丁寧でよかった。
  • streamは外部変数参照したやつも比較に加えるともっとよかった。

NS パネル・ディスカッション - Java Day Night Session with NightHacking Tour

メモ

  • 日本のJavaコミュニティの話。
  • アジアでは英語で発信できる人が少ないのでJavaチャンピオンが少ない。
  • JCPに参加をしよう。
    • Javaの仕様に不満があれば、JCPにフィードバックする。
  • MSコミュニティとの違い。
    • MSではMVPが多く、MVPを中心に勉強会が開かれる。
    • MSはMVPの選出に口を出すので、Javaチャンピオンとも違うモノ。
    • もっとJavaに興味を持っている人を活動しやすくするのが
      Javaコミュニティの一つの課題。
  • nesエミュレータの話。

所感

  • JCPといわれても英語の壁は高い。
  • ステファンさんのnesエミュレータは思った以上に考えられている。
    もっと単純に作れると思っていた。あなどれない。
  • ストリーム配信していたみたいだけれど、ソフトの権利大丈夫?

全体の所感

  • 机がほしかった。イスも何だか堅い。
  • 満席セッションも多く、トイレ混雑などキャパが合っていなかったのでは。
  • 来年も期待します。

「DDD Alliance! ドメインオブジェクトの見つけ方・作り方・育て方」へ行ってきた

先日参加したのでまとめを書きます。

メモ

  • 設計の基本
    • アジャイルとオブジェクト指向のつながりはたまたまではない。
      変更容易性を突き詰めていった結果の側面。
    • 仕様変更とプログラムの変更が一致しないのはダメなモジュール。
      モジュール性における連続性が低い。
    • 機能分割が機能クラス+データクラスなら、オブジェクト指向は抽象データ型。
    • メイヤーの本は鈍器。
    • 機能分割はモジュール評価における「わかりやすさ」や「連続性」が低いので変更が大変。
      (メイヤーによると)
    • オブジェクト指向なら変更に強いので仕様変更が怖くない。
      むしろお客さんの興味のあったことを理解できたはずなのでムダではない。
  • 見つけ方
    • 何気ない用語からドメインの学びは始まっている。
    • 利用規約はドメインそのもの。クラスやその振る舞いの要素そのもの。
    • アソビューはDDDで開発している。CEOの理解もある。
    • とりあえずひな型8点セットや業務の関心事発見パターンを参考にする。
  • 作り方
    • getして自分で判断・加工・計算するのはNG。
      これによりロジックの置き場の整理にもつながる。
    • nullを渡さない戻さない。全員が守れればチェックはいらない。
      信用できずにチェックをするとなると、それによってコードが汚れるので、
      可能であれば約束事にすべきだ。
    • ドメイン層以外は常にシンプルにしておく。
      ドメイン層以外が汚くなったらそれは怪しい箇所としてチェックできる。
    • DBや画面はデータをどう扱いたいかだけだからデータをフラットにしたがる。
      オブジェクト指向と相容れないのは仕方が無い。
    • ドメインの表現にこだわるためにフレームワークを活用する。
      ドメインが守れるなら、多少の苦労はいとわない。妥協しない。
  • 育て方
    • メソッドの抽出を頑張る。
    • 2個以上の引数は怪しい。
    • 一時変数を値オブジェクトへ。
    • 区分オブジェクト。
  • QA
    • コンテキストを超えた範囲での共通化をどうするのか。(名前、電話番号など)
      • コピーがいい。コンテキストごとでドメインが成長するので共通モジュールにしにくい。
    • ドメイン層が深いとテストしにくい。
      • 深い階層になるのはドメイン設計に問題がある。
        (増田さんは)ドメイン自体にテストは書かない派。サービスなどはテストを書く。

所感

  • メイヤー本の話が出た。
    昔オブジェクト指向を深く知りたくて読んだけれど、理解できなかったり読み飛ばしたりしたところが多かったのでもう一度トライしてみたい。
    いやDDD本の再読の方が先か。
  • 「オブジェクト指向なら変更に強いので仕様変更が怖くない。
    むしろお客さんの興味のあったことを理解できたはずなのでムダではない。」あたりは増田さんらしい。(他ではあまり聞けない)
  • nullを渡さない戻さないは挑戦しているけれど、チェックしないという発想はなかった。
    習慣でLombokの@NonNullつけていたけれど 信用できる範囲内ならいらない気がする。
    挑戦してみよう。
  • 個人的にオブジェクト指向エクササイズのルール9の考え方(getterを使わない)が
    曖昧なことに気がついた。
    例えば、商品価格、数量、割引率があって総合価格を計算するときに、どっかにまとめて計算するメソッドを作ってgetしてしまいそう。
    そこからのリファクタリングがぱっとは浮かばない。自身の中で整理が必要。
  • 今回は最終補欠が24人いた。次回以降、普通に落選して繰り上がれないことも覚悟が必要。

謝意

増田さん、DDD Allianceさん。このような会を定期的に開いていただいて感謝します。
次回も期待しています。

オブジェクト指向入門 第2版 原則・コンセプト (IT Architect’Archive クラシックモダン・コンピューティング)

オブジェクト指向入門 第2版 原則・コンセプト (IT Architect’Archive クラシックモダン・コンピューティング)

「JJUG CCC 2016 Spring」へ行ってきた

「JJUG CCC 2016 Spring」へ行ってきたので
参加報告を(初めて)書きます。

GH-1 Type Annotation for Static Program Analysis

まとめ

  • Java7までは宣言にしかアノテーションを書けなかったが、Java8以降では型の使用に対してもアノテーションを書けるようになり、振る舞いもチェックできるようになった。
  • これまでのFindBugsではパターンマッチングしているだけなので、振る舞いに対してはチェックできない。しかし、Java8以降であれば振る舞いに対してもチェックできるようになっている。
  • 例えば、CheckerFrameworkの@Nullable等。

所感

  • とっつきにくい話もわかりやすくまとめる桜庭さんのすごみを感じた。
  • アノテーションの幅が広がって何かに使えそうだけれど、それを研究する余裕が無い。いつかやる。

F-2 Thymeleaf 3 を使ってみよう!

まとめ

  • Thymeleaf3が5/8にリリースされた。
  • Full HTML5対応により、閉じタグを完璧にしなくもOKになった。
    (brの閉じタグなしは2ではエラー。)
  • テキストモードにより、タグより簡素に書ける場面が増える。
  • 大幅な内部リファクタリングによりパフォーマンス改善。
  • 5/21現在ではThymeleaf3がspring-bootに対応していないので、少々設定が必要。
  • 大きな新機能はないので特殊な機能を使っていない限り、2->3はほぼ問題ない。

所感

  • スピーカーの椎葉さんは、Thymeleafの日本語訳も書かれたかただったのは知らなかった。
    よく使っています。感謝します。
  • 3以外にもThymeleafの大まかな説明をしてもらい、なんとなく使っている部分やはき違えていた部分もあったので自信が持ててよかった。
  • 6月になったらSpring-boot1.4と共にThymeleaf3に行くしかない。

E-4 テストゼロからイチへ進むための戦略と戦術

まとめ

  • いきなり完璧にしようとせず、チームの立ち位置と着地点を確認する。
  • テストを手動でやろうが自動でやろうが綺麗に表示を確認できるデータは必要なのだから、かならず用意する。
  • テスト自動化以外でも使えるツールを使う。
  • 便利なプラグインを導入する。
  • カバレッジは7割ぐらいを目指す。ただ重要なのは増減の推移。
  • 絶対防衛ラインだけSelenumuにするなども考える。
  • テスト以前に環境構築の簡素化は必要。

所感

  • 要点を押さえて話してくださるのでとても聞きやすかった。
  • テスト自動化と開発環境の簡素化は近いところにあるという考え方が勉強になった。 テスト自動化以前に開発環境簡素化を進めておいて、テスト自動化を徐々すすめるアプローチもありかも。

GH-5 Spring Framework/Bootの最新情報とPivotalが進めるクラウドネイティブなアプローチ

まとめ

  • spring-boot1.4
    • 2016年6月予定。
    • テスト向け機能が改善。
  • Spring Framework 4.3
    • 目新しいモノよりも改善が多い。
    • @autowiredなしでのインジェクションが可能になる。
    • GetMappingや@sessionAttribute等が追加。
  • Spring5
    • JDK9対応。
    • Reactive関連が追加される予定。

所感

  • 「はじめてのSpring Boot」を書かれた槙さんの発表。pivotalに行かれたのか。
  • @autowiredがいらなくなるのは、とてもうれしい。リリースが待ち遠しい。

E-6 大規模映像配信サービスのJava8による全面リニューアルの裏側

まとめ

  • U-NEXTがPHP→Javaへリニューアルした。
  • DBFluteを中心としていった。

所感

  • SQLの個人差を嫌ってDBFluteを選んだみたいだけど、DBFluteへ強く依存している気がする。
  • DBFluteのコミッターの人が色々対応していたみたいな話をしていたが、その人が飽きたり、病気になったり、うまく次の世代へ引き継げなかったりしたらどうするのだろう。
  • そんなこと考え出すとSQLが一番長生きしていて安全なのか。しかしあの規模感のシステムでSQLを書きたくない気持ちもわかる。

AB-7 若者にJavaの好きなところ嫌いなところきいてみた

まとめ

  • 静的型付けが強力。
  • public static final など冗長なものも多い。
  • JVMとライブラリの恩恵が大きい。
  • コミュニティが多数で大規模。
  • VIMで使いにくい。
  • GCがあるのでリアルタイム処理は難しい。
  • かっこいいGUIがない。
  • 歴史が長すぎて覚えることが多いし、バージョンの積み重ねによる経緯がわからない。
  • 選択肢が多すぎるが故に決定が難しい。(フレームワークの選定など)
  • くそコードが多い。くそコードしか知らずに(それが正しいと思って)育ってしまう。

所感

  • 私は若者側ではないので参考になった。
  • 聴衆に聞くのはよいが、そんな場合はスライドを前日でもいいので公開していただけると答えやすいと思う。その場で考えをまとめて発言できる反射神経の良さもっている人は限られる。
  • その場では答えられなかったので、回答を考えてみた。
    • 「くそコードしか知らずに育ってしまう」件については、そのことに対する問題意識があれば救える可能性があるが、ない場合は救えない。
    • 問題意識がある場合は他の人のコードをたくさん見ることをお勧めする。その中でこれはいい、あちらはよくないがわかってくる。その中でいいと思った書き方を真似ればいい。「リファクタリング」や「リーダブルコード」のコードの書き方の本もお勧め。組織にくそコード改善が期待できなければ転職を考える。
    • 問題意識がない場合は気づいてもらうしかない。例えば日本が鎖国を続けて下駄しか知らないということになると、下駄で何が悪いということになる。シューズ(靴)を知って、初めて下駄が履きにくいということになる。閉じた世界ではくそコードもくそコードで何が悪いということになるので救えない。シューズの存在を知り、下駄は履きにくいと考え出すまでは救うことができない。
      くそコードを書いている組織やエンジニアは効率が悪いから淘汰されそうな気がするが、必ずしもそうはならない。結局は自ら問題意識をもって改善していくしかない。(他力を期待しても他人がやってこないこともある)

全体の感想

  • 休み時間が増えてよかった。
  • アンケートとセッション案内の紙を分けてほしい。
    セッション案内の紙を持って返りたい。
  • 時間が被らなければ参加したかったセッションは多かったので、
    ラインナップが充実していると思う。
  • ただ見られなかったものも多いので、いずれはビデオに撮って配信もしていただけると最高。

最後に発表者とスタッフの皆さんに感謝します。
ここ毎回着実にレベルアップや改善がされていると思います。
今後も期待しています。

トピック「JJUG」について