4

最近、Matthew Weier O'Phinney(ZFプロジェクトリーダー)による記事に出くわしました。この記事には、次のようなサンプルコードが含まれています。

class User
{
    protected $_data = array(
        'username' => null,
        'email'    => null,
        'fullname' => '',
        'role'     => 'guest',
    );

    /* ... */
}

従来は4つの異なるメンバー変数であったものが1つの配列に統合されていることに注目してください。$_dataクリーンなコンストラクター(パラメーターが1つだけ)の利点はわかりますが、IDEが配列でオートコンプリートをうまく実行できるとは思えません。

私が考えることができる1つの代替案は、魔法のメソッドを使用して、単一のパラメーターと4つのメンバーを持つコンストラクターを作成することです。

class User
{
    protected $_username = null;
    protected $_email = null;
    protected $_fullname = '';
    protected $_role = 'guest';

    public function __construct($data)
    {
        foreach ($data as $key => $value) {
            $this->$key = $value;
        }
    }

    public function __set($name, $value) {
        $member = "_$name";
        $this->$member = $value;
    }
}

コードの2番目のブロックの方が優れているようです...しかし、O'Phinney氏よりも優れたコードを記述できるとは思えません。コンストラクターへのクリーンなインターフェイスを維持しながら、クラスメンバーを処理するための最良の方法は何ですか?

4

2 に答える 2

2

記事に示されているように、all-in-an-arrayメソッドの背後にある大きな目的は、__set最初に配列をチェックすることによって、メソッドが設定されるものと設定されないものを制御できるようにすることです。あなたの現在__setはそれをしませんが、それは単純な追加です:

public function __set($name, $value) {
    $member = "_$name";
    if(property_exists($member, $this)) // <- New magic.
        $this->$member = $value;
}

コンストラクターでも同じことをしたいと思うでしょう。

ただし、オートコンプリートの問題は引き続き発生します。インスタンスのメソッドと変数を表示するのに十分な知識を持つ最新のIDEは、パブリック、プロテクト、プライベートのいずれであるかに基づいてリスト内の項目を表示または非表示にするのに十分なほど賢いことがよくあります。すべてが保護されていると宣言すると、IDEに関する限り、基本的にアレイ内でそれらを非表示にするのと同じ効果があります。これは、保護されたインスタンス変数とを使用することの大きな欠点__setです。

于 2010-06-22T02:50:16.247 に答える
1

それはすべてトレードオフです。IDE のオートコンプリートに依存したい場合、MO'P のコードは確かに問題を引き起こします。利点は、 __toArray() 関数の実装などを非常に簡単にする便利な内部配列があることです。

あなたが提案する妥協は私にはばかげているようです。IDE は、引数を作成するときにまだ役に立ちません。魔法の __set() は基本的に、保護されたプロパティを効果的に公開するだけです。チャールズの回答と同じように魔法を追加できますが、言及されているのと同じ注意事項があります(つまり、オートコンプリートの問題がまだあるということです)。

MO'P の投稿からも多くのことを学びましたが、一般的に、彼のように実装するのは賢明ではありません。彼のサンプル コードのほとんどは、概念を示すためのものであり、実用的な現実世界のアプローチを示すものではありません。

オプションの構成キーが多数ある場合、引数が 1 つのコンストラクターは非常に便利です。完璧な世界では、コンストラクターの有効な構成配列キーを文書化できるように、phpDoc に何らかの拡張機能が存在する可能性があります。

とはいえ、オートコンプリートに依存したいが、__toArray() などの疑似プロパティの明示的なセットが必要ない場合は、パブリック プロパティまたは set-method を作成し、phpDocs を追加して、コンストラクターにそれらのいずれも設定させないでください。割り当てまたはメソッド呼び出しによってオブジェクトを明示的に構成するようにコードを強制するだけです。

于 2010-06-22T03:00:17.430 に答える