tonkat-prtq / java-bingo-app

0 stars 0 forks source link

isHitのテストをしたい #4

Open tonkat-prtq opened 2 years ago

tonkat-prtq commented 2 years ago

1e8bb73

今日はとりあえずJunitを使ってみる、書いてみる、というのを目的とし、上記コミットで書いてみました。

この中で、BingoTroutのisHitメソッドのテストがうまく書けませんでした。

https://github.com/tonkat-prtq/java-bingo-app/blob/1e8bb731b7b9db56def03a985e7b604cab78c8ab/src/com/company/BingoTrout.java#L1-L26

というところで詰まっています。

k-sawahata commented 2 years ago
private boolean hitStatus = false;とprivateにしているため、BingoTrout.hitStatus = trueのように書けず、他のテストのようにテストのためのデータを簡単に用意することができない。

ヒット状態かどうかはビンゴやリーチ確認のときにどうせ確認しそうな気がするから、getterあってもいいのでは・・・? と純粋に疑問に思ったのですが、getterっていらない設計なんですかね?

k-sawahata commented 2 years ago

isHit()という名称で戻り値なしはちょっと危ないです。 is~という名前のメソッドは基本的にはbooleanに関連する変数名・メソッド名で使われることが多いです。

boolean isHit ← false:ヒットしていない, true:ヒットしている 変数名(属性)の場合は上記のようにfalseとtrueの内容まで一発で表せるということで、この書き方をコーディング規約にしているところもあったりします。

(どんな名前にすればよいのかは現状思いついてないのですが、hitNumber()や単純にhit()とかでもよいかも?)

tonkat-prtq commented 2 years ago

ヒット状態かどうかはビンゴやリーチ確認のときにどうせ確認しそうな気がするから、getterあってもいいのでは・・・? と純粋に疑問に思ったのですが、getterっていらない設計なんですかね?

getter / setter についての知識が足りず、使うことを現段階ではまだ考えていませんでした。 スッキリわかるJavaなどを参考に、getterの要不要と実装の見直しをしようと思います!

isHit()という名称で戻り値なしはちょっと危ないです。 is~という名前のメソッドは基本的にはbooleanに関連する変数名・メソッド名で使われることが多いです。

こう書いたらtrueかfalseが返ってくることを期待するのが常識、という感じですね。 命名を修正します!

@k-sawahata

nega321345 commented 2 years ago

(澤畑です) もう理解しているかもしれないですが、一応まとめ的に。。。

Javaの慣習的な部分なのですが、 「フィールドはprivate」「メソッドはpublic」が基本の形かなと思います。 なぜ基本かというと、JavaにはJavaBeansと呼ばれる、Javaを扱う上での基本となるクラスの型のような物があり、 その取り決めの一つにフィールドにgetter/setterが置いてあるという項目があります。 Javaのフレームワークの一つのEJBなどではそのBeansの形を使う前提で機能が盛り込まれており、 その流れでJavaではprivateなフィールドに対して、getter/setterを置く形が基本とされているところがあります。

もちろん、これは基本の形というだけであるため、フィールドをprivateにしなくてはいけないわけでも、 getter/setterをpublicで必ず置かなくてはいけないわけでもないです。 (lombokというJavaのツールだと@のアノテーションだけでgetter/setterができちゃうので、特に考えずにpublicになっていることも多々ある印象ではあります。)

ちなみに、もう少しだけ解説しておくと、 publicなフィールドとgetter/setterは何が違うでしょうか?

これは「意図が見える」という前提がやはりあります。

publicなフィールドは、その項目が様々な位置から使われているのかなという印象を受けます。 (グローバル変数のような形) この場合は、static finalの形で「定数クラス」と呼ばれるような使い方をされることもある印象です。

public class 定数クラス {
    static final int TAX = 10;
}

のような形。

で、一応JavaにはEnumと呼ばれる定数値を管理することに特化したクラスもあり、 うちのプロジェクトではこの形が使われています。 (めちゃくちゃ便利なので、余裕があればこれも調べてみてください。)

本題のgetter/setterとの違いについては、 getter/setterが「設定されている」ということが大事です。 逆にいうと、使わない時には「設定しない」ことが重要です。

getter/setterが設定されていないということは、あくまでその値に関しては、 このクラス内でだけ操作が行われるものであり、 他のクラスからの干渉を受けていないことがこれにて保証されます。 (DDDでも散々言われている依存の方向性を整える話の基本段階みたいなものですね。)

また、メソッドでgetter/setterが設定されることによって、 その中に必要であれば処理を入れることができます。 これも重要。

publicでフィールドを使われていると、そこに何らかの制限を後からつけることは基本的に無理です。 しかし、参照する時にはgetterを通して行われているのであれば、 getter内にif文を入れればいいのです。

直で変数を参照すると、保守性が落ちてしまいます。 単純な機能でも一つ一つが保守性を考えられて設計されていたりするので、 その辺を改めて考えてみるのも面白いですよね〜。