僕がJavaのWebアプリのコードレビューをするときって何を気にしてるっけなぁ?

コードレビューをするときには、フォーマットや慣例的な書き方とか、名前ちゃんとした方が良いよとか、処理にも名前をつけようねとか、そういうことは伝えるんだけど。それよりももっと気にするのは、「ここで見つけておかなきゃいけない」ってことだなぁってふと思ったのだった。

ここで見つけておかなきゃいけないこと?

仕様に従ってるかどうかとかは、動かしてみれば分かるし、PDM(Product Manager)が受け入れテストとして見てくれたり、QAと呼ばれるテストのチームがやってくれたりもする。ので、そこまで気にしてない。

気にするのは、エンジニアがソースを読むことでしか見つけづらいバグ。かな。特定の条件が重なったときにだけ発生するようなやつとかそういうの。10msのタイミングで発生するとか、12/31の0時にだけ発生するとか、エラーが発生したときにだけ発現するとか、今は大丈夫だけど2年後ぐらいに発火する爆弾とか。

で、そういうのって、知ってるか知らないかということも多くて、知らない人がどれだけ頑張って読んでも知らないから気づけなかったりする。ので、自分が知ってることはできるだけ、伝えていった方がいいんだろうなって。思ったり。

で、具体的には?

って、ここまで書いといて、特に何も考えてないんだけど・・・。

適当に思いついた順番で

  • 文字列の比較に==使わないでね
  • オートボクシングのぬるぽに気をつけて!
  • intどうしを割り算してもintにしかならないんよ
  • 金額の計算にはfloatやdoubleじゃなくてBigDecimalを使うんよ。誤差が出るから。
  • 1つの処理の中で現在日時をその都度取得してたら、時間がずれるよ
  • このデータ量だとintが1年後にあふれるかも?
  • longでマルチスレッドあぶないんじゃないっけ?ってかマルチスレッド使うときは落ち着いて考えよう(僕が
  • guavaのTransformはその場で作られてるわけじゃないから変更するときは気をつけて
  • SimpleDateFormatはスレッドセーフじゃないからstaticで持たないでね。てかJava8のDateTimeFormatter使おう。
  • フォーマッターのyyyyをYYYYって書くと年末に死ぬから気をつけて
  • SpringのComponentのスコープはデフォルトでSingletonだから状態を持たないでね
  • DBのトランザクションの分離レベルどれにしてる?
  • とか、どこのレイヤーで開始してる?てか、開始してる?
  • コミットせずにクローズするとロールバックされる?コミットされる?
  • ログの内容が実際に発生したやつと違うよ?
  • ここで例外が発生したらログを出そうとしてるけど、メッセージ作るところでぬるぽになりそう?

とかとか。また思いついたら適当にメモっとこっと。

せんでんー

テックカンファで名古屋に行くからぜひお友達とかさそって来て下さいー!

bufferings.hatenablog.com

デザインパターンの中のObject Creationalパターンをさらっと振り返ってみた

なんとなく、振り返ってみようかなと思って、今日の気分でObject Creationalのパターンだけ。仕事では主にJavaで自社のEC系のWebサービスを開発してる。ので、Frameworkを作ったりしてないし、Desktopアプリとかスマホアプリとかは作ってない。WebAppエンジニアの視点から。

デザインパターンについての参考:

http://www.techscore.com/tech/DesignPattern/index.html/

Object Creational: Abstract Factory

目的

関連・依存するオブジェクトのファミリーを生成するためのインターフェイスを提供する。

感想

Factoryのインターフェイスを定義して入れ替え可能にするってパターンだけど、僕は使うときないなー。複数のファミリーに対応するってときがないから。んで、だから、それらの生成をまとめる必要もなくて。なので、そういうオブジェクト群を生成するようなFactoryも作るときがないような気がする。

Object Creational: Builder

目的

複雑なオブジェクトの生成と表現を分離して、同じ生成方法で違う表現を生成することができるようにする。

感想

パターンとしてはBuilderのインターフェイスを定義して、それをDirectorに渡して使うからBuilderを差し替えられるって感じよね。これもAbstract Factoryと同じ理由で、差し替えたいってときがないので、自分で作って使うことはないかなー。

ただ、Spring FrameworkのResponseEntityとかUriComponentsBuilderとかは内部で実装を入れ替えたりしてるかもなぁって思うので、知らず知らずに使ってるとは思う。

あと、もし作るならBuilderのインターフェイスを定義するより、Builderの具象クラスを作ってその内部で使ってるクラスを入れ替える、って作り方をするかもなぁ。と思った。

Builer自体は結構好き。特にDTOの生成だったらLombokの@Builderを使うことが多い。その方が、コンストラクターだけで全部受け取ったり、コンストラクターで生成したあとにsetterでセットするのより好き。

Object Creational: Factory Method

目的

オブジェクトを生成するためのインターフェイスを定義して、サブクラスがどのクラスをインスタンス化するかを决められるようにする。

感想

インターフェイスは使わないなぁ。Factoryは、staticメソッドとしてそのクラス自体に定義してしまうことが多い。生成対象が継承を使ってる場合も、僕はFrameworkを開発する側じゃなくて、その上で動くアプリを作る側なので、あんまり汎用的に作る必要がないので、親側のクラスやインターフェイスに生成用のstaticメソッドを作ってどのインスタンスを生成するかもそいつが決めてしまうことが多いかな。

Object Creational: Prototype

目的

プロトタイプインスタンスを使ってオブジェクトの種類を指定して、それをコピーすることで新しいオブジェクトを作る。

感想

使わないかなぁ。まず、cloneを使わないし。必要ならコピーするメソッドを自分で作るだろうな。だし、もし内容が最初から決まってるんだったら、それを生成するためのファクトリー的なメソッドとかファクトリー的なクラスを作るかな。それに、値オブジェクトを使う場合は、コピーする必要もないしね。

Object Creational: Singleton

目的

1つだけインスタンスが存在することを保証して、グローバルにそのインスタンスにアクセスできるようにする。

感想

使わない。テスト書きにくくなるから。Singletonオブジェクトを作るんじゃなくて、Springの@ComponentでSingletonスコープにする。

まとめ

こんな感じか

  • Abstract Factory: 使わない。
  • Builder: インターフェイスを切り替えたりするところまでは自分では作らないけど、Springが使ってそう。それを僕は利用してそう。
  • Factory Method: インターフェイスは使わない。
  • Prototype: 使わない。値オブジェクトを使う。
  • Singleton: 使わない。Singleton ScopeのComponentを使う。

気づき

あんまり使ってなかった。「インターフェイスで汎用的に」ってのを感じるけど、僕はあんまり汎用的に作る必要がないから、その部分は僕にとっては不要なんだろうなって思った。ただ、インターフェイスは作らないけど、ファクトリークラスや、ファクトリーメソッド、ビルダークラスはよく作るし好きだよ。という感じ。面白かった。

宣伝

bufferings.hatenablog.com

10/28(土) なごやか楽天テクノロジーカンファレンスと僕の悩み

なごやか楽天テクノロジーカンファレンス

10/28(土)に楽天テクノロジーカンファレンスがありますー。んで、今年は名古屋支社で初のサテライトを開催します!サテライトってのは、東京でやってるセッションの生中継を流すって形式ね。んで、僕はこれまで大阪でスタッフしてたんですけど、今年は名古屋に遊びに行かせてもらえることになったので行って楽しんできますー!

connpass.com

海外のカンファレンスみたいな

セッションは基本的に英語なので、海外のカンファレンスを見てるみたいな感じで楽しいです。今年は日本語のトラックもあるみたいね!新しい!?

タイムテーブル

タイムテーブルはこの中からどれを名古屋会場で流すかを絶賛考え中です!どれも面白そうだから悩むよね。

https://rakutentechnologyconference2017.sched.com/grid

フリーランチ・ビアバッシュ

ランチ、お菓子、ビアバッシュとかもついてて、無料ですー。

お申込みはこちらから

↓のREGISTERボタン押して「名古屋サテライト」のチケットを選んでね。

Rakuten Technology Conference 2017 Tickets, Sat, Oct 28, 2017 at 11:00 AM | Eventbrite

せっかくなのでお悩み相談室

僕、休憩室みたいなところで、お悩み相談室みたいなのをやりたいなー。僕がお客さんの悩みを聞くんじゃなくて、お客さんが僕の悩みを聞いてくれる相談室ね。なので、相談に乗ってくれる人とか、一緒になって考えてくれる人とか、同じ悩みを持ってる人とか、ちょっと興味ある人は、ぜひ来てやって下さい!サテライトセッションを見てて疲れたときとかちょっと気分転換したいときに、ふらっと!一日中僕の相談に乗ってくれてもいいのよ?

どんなこと悩んでるかなー?

  • スクラムと見積もりと納期
  • エンジニアが期待に応えようとしてるとき
  • チームが作りたいものとスキルにギャップがあるとき
  • ペアプロが自然消滅してしまうとき
  • モブプロ導入したいときってどう説明する?しない
  • TDDできる人たちはTDDやらなくても良さそう
  • どんな自動テストを残す?消す?
  • ドメインをどんな風にコードに落とし込む?
  • クリーンアーキテクチャって具体的にどんな風にコード書く?

こんなとこ?あ、あと娘の話とか!お待ちしてまーす!

TDDはあんまり使わなくなったけど心の中にある

今日は娘たちとコログ探しして楽しかった。

f:id:bufferings:20170910220749j:plain

この数年間、頭の中にTDDを入れた状態で開発をしてきたんだけど。タイトルに書いた風に思う。

良い所がいっぱいある

見失わずに済む

僕にとってTDDの良さは、まず、自分が何をしようとしているかを見失わずに済むところ。一歩先にゴールを立てて、そこに向かって一歩進む、たどり着いたら、次の一歩を進める。その繰り返し。だから、遠く離れたゴールに対して、急いで走って、途中で道に迷ってどこに向かってるか分かんなくなったりしないで済む。

余計なものを作らなくて済む

「必要なものはこれだよね?」という確認から入って、それを実現するための実装に集中するから余計なものを作らなくて済む。実装を先に作ると「こういう機能もあるといいかもだから入れとこうかな」ってついつい入れてしまう。

リファクタリングできる

まず最初に動くものを作ってから、その状態をキープしたまま、実装の改善をすることができる。

最初のクライアントになれる

テストを先に書くことで、その実装がどのように使われるかを、クライアント目線で考えることができる。

「考えたとおりに動いている」と言える

テストを通っているので開発者が「自分が考えたとおりに動いている」と自信を持って言える。「開発『は』終わりました!」って言わなくて済む。

とかとか。

でもあんまり使わなくなった

こんなに良いところがいっぱいあるのに、どうしてあんまり使わなくなったんだっけ?

もう少し大きな単位で考えるようになった

TDDで進めるときは、クラス単位とかメソッド単位で考えてしまうんだけど、複数のクラスを組み合わせた、もう少し大きめの「機能」の単位で最近は考えるようになったかなぁと思う。その単位でもテストを先に考えたりはするけど、それはRed->Green->Refactoringのリズムというよりは、最終的にこれが全部通ってたら大丈夫だね。というようなものなので、ちょっとTDDとは違うかなと思う。

実装をがらっと変えたりする

チームのスキルに合わせて、まずは手続き型でもいいから機能が動く状態に持って行く。その後、その機能が動く状態をキープしながら、中の実装をオブジェクト指向に変えていく。というようなことをちょくちょくやっている。そういうときには、クラスレベルのユニットテストはかえって邪魔になってしまうので、そういうのは手でやったら良くて。どうせ後で使わないし。リファクタリングするときには機能レベルのテストがあれば良いなーと。

あぁ、そうか。僕は最近は機能レベルのテストを使って、ちょっと大きめのサイクルを回すようになったのかもな。

心の中にある?

あんまり使わなくなったとはいっても、TDDの良さについては常に心の中にある。というのは、例えばちょっと要らないものを自分が作ろうとしていることに気づいた時には「それってどういうケースで必要になるんだっけ?」ってテストを頭の中で考えてみて「うむ。要らん。」って言ってみたり、何かに悩み始めたときには「まず一歩進めようかな」って言ってタスクを小さく切り分けて一歩ずつ進めようとしてみたりしてる。のだ。TDDのエッセンスが心の中にあって。そのループは頭の中で回しながら、手を動かすときは、もう少し大きな範囲でループを回してる。という感じ。

だから、TDDはあんまり使わなくなったけど、自分の心の中に染みこんでるなぁ、って思うのでした。

おまけ

僕には「こういうときにはTDDを使う」ってのがある。それは、メンバーに考え方を伝えるとき。「全部を相手にせずに、まずはこのテストを通そう。OKだね、じゃ次にいこう。こういう場合はどうなるのが正しい挙動かな?」とかで、自分の考える順番を伝えたい人がいるときは、TDD使う。「あぁ。今は綺麗にしなくていいよ。まずは動くコードを作ろう。」って。

今日はもう寝ようかな。おやすみなさい。

Maven Centralで公開するときの自分メモ

もりすさんのところにだいたい全部書いてあります。ありがとうございます。

tagomoris.hatenablog.com

全体の流れ

もりすさんも書いてるように、ここに流れが書いてある。

http://central.sonatype.org/pages/ossrh-guide.html

Maven Centralに上げるための要件

http://central.sonatype.org/pages/requirements.html

色々と情報をpomに書いておく必要がある。

デプロイのためのpomの設定

http://central.sonatype.org/pages/apache-maven.html

GPG署名用のプラグインとか色々。

できあがったpom

最低限のものになってるかなと思う。

https://github.com/bufferings/thymeleaf-extras-nl2br/blob/master/pom.xml

Thymeleaf extras nl2br 1.0.1 is released

There's no feature changes, but improved the source code. (Thank you Kazuki Shimizu (@kazuki43zoo) | Twitter !)

You can use it by Maven.

<dependency>
  <groupId>com.github.bufferings</groupId>
  <artifactId>thymeleaf-extras-nl2br</artifactId>
  <version>1.0.1</version>
</dependency>

Reference post (for 1.0.0 release)

bufferings.hatenablog.com

Thymeleaf extras nl2br is released

You can use nl2br:text="${sample}" attribute, which firstly escapes the HTML special characters in the input text, then inserts <br /> tags before newlines.

github.com

Background

I wanted to show a multiple lines input with <br /> tag for the newlines. There’re several ways to realize it: using th:utext after converting newlines to <br />, or having lines as list then using th:block with th:each. But I don’t want to allow other html tags, nor to write th:block with th:each many times. Finally, I decided to create it.

Usage

Maven

<dependency>
  <groupId>com.github.bufferings</groupId>
  <artifactId>thymeleaf-extras-nl2br</artifactId>
  <version>1.0.0</version>
</dependency>

Code

templateEngine.addDialect(new Nl2brDialect());

or if your application is Spring Boot application, you can add the dialect like this:

@Bean
public Nl2brDialect dialect() {
  return new Nl2brDialect();
}

Template

Then you can use nl2br:text attribute like this:

<p nl2br:text="${sample}">Hello!</p>

If you want to stop your IDE’s warning, you can add xmlns attribute like this:

<html lang="en" xmlns="http://www.w3.org/1999/html"
      xmlns:th="http://www.thymeleaf.org"
      xmlns:nl2br="https://github.com/bufferings/thymeleaf-extras-nl2br">

Example Project

github.com

f:id:bufferings:20170826164931p:plain

hope this serves someone :)