4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Java】変更に強いコード - 値オブジェクト1(Value Object)

Posted at

変更に強いコードを書くための考え方を学びます

#変更に強いコードの5つのポイント

  • 1. 変数名は説明になるようにつけよう
    • 入力、処理、出力の役割ごとに変数名を使う(説明用の変数を導入)
  • 2. 目的ごとに変数を用意しよう
    • 計算した結果に対して変数を用意して、使いまわさない
  • 3. コードは意味のある段落に分けよう
    • 入力、処理、出力に分ける
  • 4. コードのまとまり(段落)をメソッドとして独立させよう
    • 異なるクラスでの重複コードはなくそう
  • 5. 狭い関心ごとに特化したクラス(ドメインオブジェクト)にしよう
    • 凝集度up = あるクラスはある目的にのみ存在する
    • ex: 送料クラスの関心事は送料のみ

#小さなクラスでわかりやすく安全に

  • 5つのポイントをおさえ、特定の関心に特化した小さなクラスを作る
    • メソッドは短く、クラスは小さく
    • クラスの可読性up、変更が簡単になる
  • 継承で共通機能は親クラスへ
    • 派生クラスでは差分のspecificな部分のみ書くことで最低限のコードにする
  • **値を扱う専用のクラス(値オブジェクト)**を作る

#値オブジェクト(Value Object)とは?

  • データを使った業務ロジック:判断/加工/計算
  • このデータの種類ごとに、値を扱う専用のクラスを作るということ。
    • 専用の型を用意(クラスやインターフェース)
    • 専用の型を使うと不適切な値が混入するバグを防げる!
    • 変更時にも、クラスやインターフェース名を手掛かりに変更できる
    • 値オブジェクトは非常に重要

##値オブジェクト実践

  • 以下のコードをリファクタする時。。🤔
int unitPrice = UNIT_PRICE;
int basePrice = unitPrice * quantity;
int basePriceWithTax = (int)(basePrice*TAX);
  • intは基本型なので使わないほうがいい
    • ここで値の種類ごとに専用の型を用意!=値オブジェクト
    • valuesクラスにもつint 型のvalueを保存
Project Root
└─src
    └─ main
        └─ java  
            └─ Main
        └─ values
            └─ Price
            └─ Quantity
            └─ Tax

##Price / Quantity / Tax型を作る

  • 基本型ではなく専用型を用意し、intやfloatをPrice、Quantity、Taxに変更
  • getter(ここではgetValue())で値を返し、外から参照できるようにする
  • 処理中身はintなので計算中ではintになっているが、
  • 入力/処理/出力の処理のみintで、クラスの中に閉じ込め、返すのはPrice型
    • →変更をここだけに閉じ込めることができる🌟
Price.java
package values;

public class Price {
    private int value;
    public Price(int value){
        this.value = value;
    }
    public Price multiple(Quantity quantity){
        return new Price(this.value * quantity.getValue());
    }
    public Price getPriceWithTax(Tax tax){
        //tax.getValueはfloatなのでCast
        int priceWithTax = (int)(this.value * tax.getValue());
        //新しいオブジェクトを返す
        return new Price(priceWithTax);
    }

    public int getValue() {
        return value;
    }
}
Quantity.java
package values;

public class Quantity {
    private int value;

    public Quantity (int value){
        this.value = value;
    }

    public int getValue() {
        return value;
    }
}


Tax.java
package values;

public class Tax {
    private float value;

    public Tax (float value){
        this.value = value;
    }
    public float getValue() {
        return value;
    }
}


Main.java
import values.Price;
import values.Quantity;
import values.Tax;

public class Main {

    private final static int UNIT_PRICE = 3000;
    private final static float TAX = 1.1f;

    public static void main(String[] args) {
       //コンストラクタで初期化
        var instance = new Main();
        var quantity = new Quantity(3);
        var totalCost = instance.getTotalCost(quantity);
        System.out.println(quantity.getValue());

        System.out.println("totalCost" + totalCost.getValue());
    }

    Price getTotalCost(Quantity quantity){
        Price unitPrice = new  Price(UNIT_PRICE);
        Price basePrice = unitPrice.multiple(quantity);
        System.out.println("basePrice: "+basePrice.getValue());
        Tax tax = new Tax(TAX);
        Price basePriceWithTax = basePrice.getPriceWithTax(tax);

/*リファクタ前
          int unitPrice = UNIT_PRICE;
          int basePrice = unitPrice * quantity;
          int basePriceWithTax = (int)(basePrice*TAX);
*/
        return basePriceWithTax;
    }

}

##関心事を外に閉じ込められてない例

  • 上のMain.javaでの操作はこんな風に書くこともできる。が。。。。
  • 値オブジェクトを使いながら、実際の処理を外に書いてしまっている🙀 (= Priceクラスを使う側で処理を書いている)
  • なので、せっかく値オブジェクトを使っているのに、関心事を外に閉じ込められてないということになります。。
//よくない例
Price unitPrice = new Price(UNIT_PRICE);
int basePrice = unitPrice.getValue() * quantity.getValue();
Tax tax = new Tax(TAX);
int basePriceWithTax = (int) (basePrice * tax.getValue());
4
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?