Post Page Advertisement [Top]







クラスを作る時に最も基本となることは

コンストラクタをどのような形で付くるかと思います。


コンストラクタでオブジェクトを作り返すことはデータ管理の基本です。


ここ栄養素を管理するクラスがあると仮定してみましょ。


public class NutritionFacts {

    private int calories;
    private int fat;
    private int sodium;
    private int carbohydrate;
    .
    .
    .
}


このクラスにオブジェクトを返す最も基本的な方法は

コンストラクタを作ることです。


public NutritionFacts(int calories, int fat, int sodium, int carbohydrate) {
    this.calories = calories;
    this.fat = fat;
    this.sodium = sodium;
    this.carbohydrate = carbohydrate;
}

しかし、食品にはカロリーが0な食べ物もあるし
ダイエット食品として管理された脂肪フリー製品もあるはずです。

そのたびに、コンストラクタを再作成する必要があります。

今はメンバー変数が四つですので15の境遇-數が出ますが

栄養素は、この他にも酸、マグネシウム、亜鉛など、その種類が数え切れません。

このすべての内容を、コンストラクタで生成してると、
コードの長さ的にももちろん、効率も良くないと思います

ここで考慮する価値のあるパターンは、

setterを利用する方法である。


public class NutrtionFacts {

    private int calories=0;
    private int fat=0;
    private int sodium=0;
    private int carbohydrate=0;
    
    public void setCalories(int calories) {
        this.calories = calories;
    }
    public void setFat(int fat) {
        this.fat = fat;
    }
    public void setSodium(int sodium) {
        this.sodium = sodium;
    }
    public void setCarbohydrate(int carbohydrate) {
        this.carbohydrate = carbohydrate;
    }
}

基本的なコンストラクタのみ利用しながら

各変数のsetterメソッドを作成して使用する方法です。

このパータンを使うと


public class Main {

    public static void Main(String[] args) {
        NutrtionFacts cocaCola = new NutrtionFacts();

        cocaCola.setCalories(100);
        cocaCola.setCarbohydrate(100);
        cocaCola.setFat(100);
        cocaCola.setSodium(100);
    }
}

このような形式で栄養素をsetterに設定できます。

情報が必要な時はgetterメソッドを使用できます。

しかし、この方法には一つ短所があります。

オブジェクトの作成が一度に終わらないので、オブジェクトの一貫性が割れる可能性があります。

上記のコードで、コーラの炭水化物を100に設定した後プログラムが突然異常終了した場合

コーラオブジェクトは、脂肪と塩分の栄養素が設定されていない状態になります。

バグの原因になるkも知れません。

これらの欠点を解決するためのBuilderパターンがあります



public class NutrtionFacts {

    private final int servingSize;
    private final int servings; 
    private final int calories;
    private final int fat;
    private final int sodium;
    private final int carbohydrate;

   public static class Builder {

       private final int servingSize;
       private final int servings;

       private int calories = 0;
       private int fat = 0;
       private int carbohydrate = 0;
       private int sodium = 0;

       public Builder(int servingSize, int servings) {
           this.servingSize = servingSize;
           this.servings = servings;
       }

       public Builder calories(int val) 
       { calories = val;return this; }
       
       public Builder fat(int val)
       { fat = val; return this; }
       
       public Builder carbohydrate(int val)
       { carbohydrate = val; return this; }
       
       public Builder sodium(int val)
       { sodium = val; return this; }
       
       public NutrtionFacts build(){
           return new NutrtionFacts(this);
       }
   }
   
   private NutrtionFacts(Builder builder){
       servingSize = builder.servingSize;
       servings = builder.servings;
       
       calories = builder.calories;
       fat = builder.fat;
       sodium = builder.sodium;
       carbohydrate = builder.carbohydrate;
   }
}



栄養素クラスの内部にbuilderクラスがあります。

nutritionを外部で呼び出す際に

コンストラクタbuilderを呼び出します。
先にbuilderで不可欠な変数を設定した後(servingSize、serving)自分自身を返しながら、
他の必要な栄養素も設定してくれます。

次にbuildメソッドを呼び出してNutritionFactsのパラメータとして自分自身を入れます

こうすればNutritionFactsのコンストラクタがBuilderを受けたオブジェクトを作成し、

このように作られたオブジェクトが呼び出された側に返される形式でできています。


public class Main {
    public static void Main(String[] args) {
        NutrtionFacts cocaCola = new NutrtionFacts.
                Builder(240, 8).calories(100).carbohydrate(100).
                fat(100).build();    }
}

このような使用ができます。

このパターンを使用すると、以前の方法たちの欠点を解決することができます。

댓글 없음:

댓글 쓰기

Bottom Ad [Post Page]

| Designed by Colorlib