Java学習 DbCとimuutableオブジェクトについて

Design by Contractについて学んでいて、少し疑問に思ったことがあったので、まとめました。

[事前条件を満たしておくとなぜ有用なのか?]

例えば、5つの数がありその中にある数Xがあるかチェックする、Xがあるならば10000回2倍する、その数を引数で渡して5倍した結果を戻す処理をしたい場合。

<事前条件を満たす場合>
(メインメソッド側)
Xがあるかチェックする。
Xのみ10000回2倍する。
また、nullなどの例外を引き起こす値がないかチェックする。
必要な物(Xを10000回2倍した数)だけ計算メソッドに渡す。

(5倍の計算メソッド側)
事前にXを10000回2倍した数だとチェックされた結果を受け取り、計算して戻り値を返す。

5回判定、10000回計算、最後に5倍して戻り値として返していることになります。
合計10006回の計算です。

<事前条件を満たさない場合>
(メインメソッド側)
5つの数全てに対して10000回2倍をする。

(5倍の計算メソッド側)
そもそも10000回2倍する前にXはあったのかチェックする。
10000回2倍する前の数に戻すための計算をする。
Xがあるかチェックする。
XがあったらXを10000回2倍したものだけ、5倍して戻り値として返す。

10万回近く計算処理をする羽目にはり、計算量は約10倍になりました。

・・・・・・すみません絶望的に例題をつくるのが下手でした。
意味がよくわからなかった方は、事前条件を早めに満たしておくと、色々な計算が少なくなる傾向にありますくらいに受け止めてください。

今回のような単純な数値計算だと、前提条件など意識しなくても最適な方法で実装していると思いますが、コードを書きながらどうしようか、ああしようかと悩んだ末に実装したコードは、後でリファクタリングの余地がないか見直す必要があるかもしれないと私は理解しました。

また、こちらの方が重要だと思いますが、上述のような状態だとバグがあった場合「使う側が渡したデータ」がそもそも何か間違っていたのか「使われる側がデータの加工に失敗したのか」がわかりにくいでしょう。

なので、使う側は引数として渡すデータをチェックする義務があります。

[不変条件をコード上で実装する]

事前条件がしっかりと満たされていて、いざ計算となった時、5倍計算する側が持っている値が変更されていては困ります。

前述したコードで言うと、
①Xを10000回2倍しました。
②Xの計算結果を5倍計算メソッドに渡しました。
③なぜかIMIHUMEIの値が5倍計算メソッドに更に渡されました。
④IMIHUMEIが5倍されて返ってきてしまいました。

こんなことになってしまう可能性があります。

これがたまたまintで計算するところにStringを渡した、くらいだったらすぐに気付くはずですが、極小の少数を計算していたなどだとどうでしょう・・・。

こういった不必要な再代入を防ぐことも含めて、使われる側が初期状態を整えておくことを「不変条件を満たす」というそうです。

具体的に言うと3点です。
①Setterメソッドを提供しない。
②finalをつけて定数として扱う。
③クラスにfinalをつけて継承を不可能にする。

package immutableCheck;

public class immutable {
	
	private int price;
	private String itemName;

	public immutable(int price, String itemName) {
		super();
		this.price = price;
		this.itemName = itemName;
		
		
	}

	public String getItemName() {
		return itemName;
	}

	
	public int getPrice() {
		return price;
	}
}

こんな感じ、上のコードにはfinalはついていないですが。

これでコンストラクタで初期化されたインスタンスが持っている値は不変となりました。
このようなインスタンスをimuutable(不変)であるというそうです。

[事後条件について]

事前条件と不変条件が満たされた結果(正常終了した)、どうなるか。
使われる側がちゃんと機能したなら欲しかった戻り値が返りますよね?ってことだと思います。

[まとめ]

DbCとimmutableについて、学びました。

immutableを保証したほうが良いもの、しなくても良いものを分けて設計できるようになりたいと思います。


この記事が気に入ったらサポートをしてみませんか?