PHPでクラスのメソッドに複数(5つ以上)のパラメータを渡す必要がでてきたのですが、例えば、下記のようにメソッドに引数として記述すると冗長になってしまいます。


public function hoge($arg1, $arg2, $arg3, $arg4...)

元のクラスを継承してパラメータをプロパティに記述という手も考えたのですが、

protected $arg1 = 1;
protected $arg2 = 2;
protected $arg3 = 3;
protected $arg4 = 4;
:
public function hoge()

あまりよい方法ではないと思い悩んでいます。

他によい方法がありましたら教えてください。
(できればメリット/デメリットも併せて頂くと助かります)

※パラメータを配列にまとめて引数として渡す方法は、できれば個人的にやりたくないので、それ以外でお願いします

回答の条件
  • 1人1回まで
  • 13歳以上
  • 登録:2015/02/15 09:43:07
  • 終了:2015/02/22 09:45:03

ベストアンサー

id:syamaoka No.2

syamaoka回答回数19ベストアンサー獲得回数82015/02/15 21:41:08

ポイント50pt

メソッドの引数の増加は、『Smalltalk Best Practice Patterns』(Kent Beck)や『Refactoring: Improving the Design of Existing Code』(Martin Fowler)といった名著でも扱われているありふれたテーマです。

これらの書籍で紹介されている、引数の増加に対する有名な2つの対処法を紹介します。

1. 引数オブジェクトの導入
個別に渡している引数をクラスに集め、そのクラスのインスタンスを渡す手法です。

<?php
class Parameter {
    public $arg1;
    public $arg2;
    public $arg3;
}

hoge(Parameter $parameter);

2. メソッドに対して引数を渡している側にメソッドの処理自体を移す
多くの引数に依存するメソッドは、そのメソッドが本来あるべきクラスに定義されていないということが往々にしてあります。引数を渡すということ自体を見直し、呼び出し側に処理を移す手法です。

<?php
class NewClass {
    private $arg1;
    private $arg2;
    private $arg3;

    public function hoge() {
        // $arg1, $arg2, $arg3 を使った処理
    }
}

いかがでしょうか。

ちなみに、質問文に書かれているように、クラスに継承関係を作り、派生クラスを導入する方法は、(質問文だけでは設計の詳細が完全に把握はできていませんが)「あまり良くない」設計ではなく「悪い」設計であろうことが伺われます。なぜ悪手なのかは、「リスコフの置換原則」や「型の継承 実装の継承 違い」などのキーワードで検索して調べてみてください。

id:wankodon

遅くなりましたが、大変参考になりました。なるほど。色々あるのですね。
頂いたキーワードを元にあとで調べてみます。

回答どうも有り難うございました。

2015/02/18 07:35:41

その他の回答(1件)

id:gizmo5 No.1

gizmo5回答回数484ベストアンサー獲得回数1382015/02/15 10:22:53

ポイント50pt

PHP 5.6 以降では可変長引数がサポートされています。
http://php.net/manual/ja/functions.arguments.php#functions.variable-arg-list

<?php
function sum(...$numbers) {
    $acc = 0;
    foreach ($numbers as $n) {
        $acc += $n;
    }
    return $acc;
}

echo sum(1, 2, 3, 4);
?>
id:wankodon

回答有り難うございます。
可変長だとメソッド内で引数のチェックを行う処理が面倒なので、それはちょっと使えません。。

2015/02/15 10:45:58
id:syamaoka No.2

syamaoka回答回数19ベストアンサー獲得回数82015/02/15 21:41:08ここでベストアンサー

ポイント50pt

メソッドの引数の増加は、『Smalltalk Best Practice Patterns』(Kent Beck)や『Refactoring: Improving the Design of Existing Code』(Martin Fowler)といった名著でも扱われているありふれたテーマです。

これらの書籍で紹介されている、引数の増加に対する有名な2つの対処法を紹介します。

1. 引数オブジェクトの導入
個別に渡している引数をクラスに集め、そのクラスのインスタンスを渡す手法です。

<?php
class Parameter {
    public $arg1;
    public $arg2;
    public $arg3;
}

hoge(Parameter $parameter);

2. メソッドに対して引数を渡している側にメソッドの処理自体を移す
多くの引数に依存するメソッドは、そのメソッドが本来あるべきクラスに定義されていないということが往々にしてあります。引数を渡すということ自体を見直し、呼び出し側に処理を移す手法です。

<?php
class NewClass {
    private $arg1;
    private $arg2;
    private $arg3;

    public function hoge() {
        // $arg1, $arg2, $arg3 を使った処理
    }
}

いかがでしょうか。

ちなみに、質問文に書かれているように、クラスに継承関係を作り、派生クラスを導入する方法は、(質問文だけでは設計の詳細が完全に把握はできていませんが)「あまり良くない」設計ではなく「悪い」設計であろうことが伺われます。なぜ悪手なのかは、「リスコフの置換原則」や「型の継承 実装の継承 違い」などのキーワードで検索して調べてみてください。

id:wankodon

遅くなりましたが、大変参考になりました。なるほど。色々あるのですね。
頂いたキーワードを元にあとで調べてみます。

回答どうも有り難うございました。

2015/02/18 07:35:41

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません