質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.51%

  • Java

    13790questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

パラメータクラスの必須、任意項目はクラスのコンストラクタとしてどう作ればよいか?

解決済

回答 3

投稿

  • 評価
  • クリップ 2
  • VIEW 1,065

arcanum_jp

score 63

こんにちは、Javaでとあるメソッドに渡す、パラメータクラスみたいなのを作ろうとしています。
その場合に、パラメータには必須項目と任意項目があり、クラスの設計として何が最善かを教えていただければと思います。

class Parameter {
    private String a;    // 必須
    private String b;    // 任意
    private String c;    // 任意

}


このようなインスタンス変数があるとして、変数のセット方法は

  • 1.全てクラスのコンストラクタで求める
  public Parameter(String, String, String);
    // a,b,cはゲッターのみ定義
  • 2.必須項目のみクラスのコンストラクタで求める
  public Parameter(String);
    // aはゲッターのみ定義,b,cはゲッター/セッターを定義
  • 3.全てセッターを定義し、必須も任意項目もプログラマにセットさせる
  public Parameter();
    // 全てゲッター/セッターを定義

が考えられると思います。

通常、パラメータクラスはどの方法が良いのか教えていただければと思います。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

+5

私個人の考えですが、まずメンバはこうします。

class Parameter {
    private String a;    // 必須
    private Optional<String> b;    // 任意
    private Optional<String> c;    // 任意
}


任意の部分はOptionalにしておくことで「存在しないかもしれないこと」を明示的にします。
その上で「必須項目のみのコンストラクタ」と、「任意項目も含めたコンストラクタ」の2種類を用意します。

// 必須項目のみ
Parameter(String a) {
    this(a, null, null);
}
// 任意項目も受け付ける 入れないものはnullに設定させる
Parameter(String a, String b, String c) {
    this.a = Objects.requireNonNull(a); // 必須なので、nullが入らないようチェック
    this.b = Optional.ofNullable(b);
    this.c = Optional.ofNullable(c);
}


あなたのコードの中で3は最悪だと思います。aが必須である保証がなされません。
あとセッターは不要だと思います。

nullを使いたくないということであれば、ファクトリメソッドという手もあります。ただ、どれを入れないかでメソッドが増えてしまいますが。

// この後のファクトリメソッドで作成することを前提とするため、コンストラクタを非公開にする
private Parameter(String a, String b, String c) {
    this.a = a;
    this.b = Optional.ofNullable(b);
    this.c = Optional.ofNullable(c);
}

public static Parameter of(String a, String b, String c) {
    Objects.requireNonNull(a);
    return new Parameter(a, b, c);
}

public static Parameter of(String a) {
    return of(a, null, null);
}

public static Parameter withB(String a, String b) {
    return of(a, b, null);
}

public static Parameter withC(String a, String c) {
    return of(a, null, c);
}

追記

改めてOptionalについて調べてみたら、Optionalは返り値に使うことを想定していて、メンバに使うのは望ましくないとのことだったので改造

class Parameter {
    private String a;    // 必須
    private String b;    // 任意
    private String c;    // 任意

    private Parameter(String a, String b, String c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }

    public static Parameter of(String a, String b, String c) {
        Objects.requireNonNull(a);
        return new Parameter(a, b, c);
    }

    public static Parameter of(String a) {
        return of(a, null, null);
    }

    public static Parameter withB(String a, String b) {
        return of(a, b, null);
    }

    public static Parameter withC(String a, String c) {
        return of(a, null, c);
    }

    public String getA() {
        return a;
    }

    public Optional<String> getB() {
        return Optional.ofNullable(b);
    }

    public Optional<String> getC() {
        return Optional.ofNullable(c);
    }
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/08 23:52

    今更だが、Builderパターンを使うのが良さそう。

    キャンセル

+1

私なら1の全てをコンストラクタで定義する。を選ぶかと思います。ケースバイケースだと思いますので、他の方の回答も参考になさってください。

  • まず3は選びません。プログラマがこのクラスを外から使う時に、必須の変数に気付く可能性が限りなく小さくなってしまうからです。基本的には呼び出し元から呼び出したクラスの中の設計を意識させないことが重要だと思います。使用者が、Parameter()を呼び出して使用したところ必須のパラメータがないことで不具合が起きるということが頻繁に起こり得ます。
  • 次に、1と3ですが、setterを定義すると言うことは、Parameter()が初期化されたのちに変数を変更できる余地を与えることになります。もしもクラスを初期化したのちに変数を変更する可能性や必要性がないのであれば、全てコンストラクタで定義した方が良いかと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

check解決した方法

-2

*後出しになりますが、、この質問をした経緯です。

3はもともとあり得ないと思っていましたが、パターンとしてあり得るという事で書いていました。1,2ともいずれも以下の悩みがありました。

1.は、第二引数を入力したくない場合、nullを入れなくてはならないというところ。

2.は、必須項目と任意項目で任意項目はセッターでセットというのはどうなのか?ということころ

なるべくならデータはイミュータブルに近い方が良いのではないかと考えていたところ2.はあり得ない

ご回答にありましたように、基本的にはコンストラクタで解決するとして、任意項目でnullを許容するのは致し方ないということろでしょうか。解決としては以下に考えました

1.必須項目のみと、必須項目と任意項目のコンストラクタを用意(swordoneさんの提案です)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.51%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Java

    13790questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • トップ
  • Javaに関する質問
  • パラメータクラスの必須、任意項目はクラスのコンストラクタとしてどう作ればよいか?