8

これをオンラインで検索してきましたが、理解できるほど明確なものが見つからないようです。Javaでこれについてここで「同様の」質問を見ました。

class animal{
    private $name;

    // traditional setters and getters
    public function setName($name){
        $this->name = $name;
    }

    public function getName(){
        return $this->name;
    }

    // animal constructors
    function __construct(){
       // some code here
    }

    // vs

    function __construct($name){
        $this->name = $name;
        echo $this->name;
    }
}

$dog = new animal();
$dog->setName("spot");
echo $dog->getName();

// vs

$dog = new animal("spot");
  1. セッターとゲッター、またはコンストラクターを介してプライベート フィールドを宣言してアクセスする必要がありますか?
  2. ベストプラクティスはどれですか?
  3. コンストラクターの目的は理解していますが (そうでない場合もあります)、setter と getter を介してプライベート フィールドを宣言およびアクセスできる場合、コンストラクターを使用する意味は何ですか?

注意してください... Web開発とPHPでOOPを使用するのはこれが初めてで、OOPの特定のことを理解するためにコードを書くことで手を「汚す」ことで学ぼうとしています。シンプルにしてください。

4

6 に答える 6

9

言うまでもなく、ベストプラクティスというよりもセマンティクスの問題です。

あなたの例では、ビジネス ロジックによって、動物には常に名前が必要であると判断される場合があります。したがって、名前を付けてオブジェクトを構築することは理にかなっています。動物の名前の変更を許可したくない場合は、setter を作成しません。

すなわち

class Animal 
{
    private $name;

    public function __construct($name)
    {
        $this->name = $name;
    }

    public function getName()
    {
        return $this->name;
    }
}

動物が持っている必要のない他のプロパティを持っているかもしれません.

class Animal
{
    private $name;
    private $owner;

    public function __construct($name)
    {    
        $this->name = $name;
    }

    public function getName()
    {
        return $this->name;
    }

    public function setOwner($owner)
    {
        $this->owner = $owner
    }
}

しかし、常に所有者と一緒に動物を作成していることがわかった場合は、便宜上、それをコンストラクターの署名に入れたいと思うかもしれません。

class Animal
{
    private $name;
    private $owner;

    public function __construct($name, $owner = null)
    {    
        $this->name = $name;
        $this->owner = $owner;
    }

    public function getName()
    {
        return $this->name;
    }

    public function setOwner(Owner $owner)
    {
        $this->owner = $owner
    }

    public function getOwner()
    {
        return $this->owner;
    }
}

所有者がアプリケーション内の別のクラスである場合は、コンストラクターが特定の型 (クラス) の所有者を必要とするヒントを入力できます。これらはすべて、あなたや別の開発者がコードの背後にある要件/ロジックの一部を理解しやすくするために使用されます。また、あちこちでバグをキャッチする可能性もあります。

class Owner 
{
    private $name;

    public function __construct($name)
    {    
        $this->name = $name;
    }
}

class Animal
{
    private $name;
    private $owner;

    public function __construct($name, Owner $owner = null)
    {    
        $this->name = $name;
        $this->owner = $owner;
    }

    public function getName()
    {
        return $this->name;
    }

    public function setOwner(Owner $owner)
    {
        $this->owner = $owner
    }

    public function getOwner()
    {
        return $this->owner;
    }
}

// Create a new owner!
$dave = new Owner('Farmer Dave');

// a standard php empty object
$otherObj = new \stdClass();

// Create a new animal
$daisy = new Animal('Daisy');

// Farmer dave owns Daisy
$daisy->setOwner($dave);

// Throws an error, because this isn't an instance of Owner
$daisy->setOwner($otherObj);

// Set up Maude, with Dave as the owner, a bit less code than before!
$maude = new Animal('Maude', $dave);
于 2012-07-31T12:44:45.667 に答える
3

セッターとゲッター、またはコンストラクターを介してプライベート フィールドを宣言してアクセスする必要がありますか?

このような状況では、私は自分自身に尋ねます:

  • 1 行の関数を保持するためだけにメソッドを作成する必要があるのはなぜですか? (+コンストラクタ)

  • 2 つ、3 つ、4 つ、5 つ、またはそれ以上のゲッター/セッターと 1 つのコンストラクターをリファクタリングするのはどれくらい大変ですか?(+ コンストラクター)

  • 2 つ、3 つ、4 つ、5 つ、またはそれ以上の getter/setter と 1 つのコンストラクターを比較して文書化するのはどれくらい難しいでしょうか?(+Constructor)

  • 文書化されるデフォルト値はありますか? (+コンストラクタ)

  • 私はドキュメンテーションが好きで、人々が読むことを期待していますか? (+コンストラクタ)

  • 初期値は不定ですか?(+Setter)

  • 必要な引数に対して構文的に正しいものとしてすべて受け入れられる同等の形式 (短縮形、国際、ニックネーム) のセットはありますか? (+セッター)

  • デフォルト値を持つオプションの引数のセットはありますか? (+セッター)

  • 初期値を文字列化して解析する一般的な必要性はありますか? (+セッター)

  • ドキュメントが嫌いで、人々が実験することを期待していますか? (+セッター)

ベストプラクティスはどれですか?

このDateオブジェクトは、ほとんどの言語で最も複雑なクラスのように思われるため、その PHP 実装はベスト プラクティスの参考になります。

セッターとゲッターを介してプライベート フィールドを宣言およびアクセスできる場合、コンストラクターを使用する意味は何ですか?

コンストラクターは、その型の結果のデータ構造の既定の状態をカプセル化するために、オブジェクトのインスタンス化時に暗黙的に呼び出されます。

CDD: コンテキスト駆動型開発の役割 - 作成者、オブジェクト、動作

参考文献

于 2014-07-01T18:39:33.217 に答える
2
  1. 依存します。通常、依存関係が必要な場合はコンストラクターを使用し、オプションの場合はゲッター/セッターを使用します。
  2. それらのいずれかを優先することも、反対することもありません。
  3. コンストラクターには、オブジェクトが作成された直後に実行されるコードが含まれており、オブジェクトを安定した使用可能な状態のままにしておく必要があります。それがコンストラクターの背後にある考え方であり、どのような場合でも機能しませんが、何を入れるべきかという考えが得られるはずです。

たとえば、後でプロパティを置換できるようにする場合など、同じプロパティに対してコンストラクター引数とセッターの両方を実装することもできることに注意してください。

$bingo = new Dog;
echo $bingo->getName(); // DogHasNoNameException <-- maybe better as constructor argument?

$bingo = new Dog('Bingo');
echo $bingo->getName(); // "Bingo"
$spike = new Dog; // Missing argument 

$bingo->setName('Spike'); // Or maybe "rename()" ;)
echo bingo->getName(); // "Spike"
于 2012-07-31T12:37:34.707 に答える
2

セッターとゲッターを介して、またはコンストラクターを介してプライベート フィールドを宣言してアクセスする必要がありますか? ベストプラクティスはどれですか?

両方。それはあなたのニーズに依存します。特定のフィールドに値が必要な場合は、パラメータを __construct()-Method に追加してください。または、オプションの Param を追加して__construct、属性を設定するオプションをユーザーに提供することもできます

コンストラクターの目的は理解していますが (そうでない場合もあります)、setter と getter を介してプライベート フィールドを宣言およびアクセスできる場合、コンストラクターを使用する意味は何ですか?

コンストラクターは、初期化する必要がある属性を初期化する必要があります。

于 2012-07-31T12:40:21.153 に答える
2

私の意見では、セッターとゲッターを記述する方が正しいと思います。それ以降、プロパティの数は増える一方です。そして __construct は、キーの名前のプロパティの配列 (プロパティ => 値) を取り、それらをプロパティに設定できます。

于 2012-07-31T12:41:20.597 に答える
1

1 > それはあなたの選択です: 依存関係が必要な場合は、コンストラクターを使用することをお勧めします。それ以外の場合は、getter を使用してください。

2 > ベスト プラクティスは最初に、

実際、動物には名前がありますが、種類と性別を追加するとどうなりますか? タイプ、性別、または名前を別々に呼び出したい場合、最初の方法は2番目の方法よりも優れています。

class animal{
private $name, $type, $sex;

// traditional setters and getters
public function setName($name){
    $this->name = $name;
}

public function setSex($sex){
    $this->sex = $sex;
}

public function setType($type){
    $this->type = $type;
}

public function getName(){
    return $this->name;
}

public function getSex(){
    return $this->sex;
}

public function getType(){
    return $this->type;
}

// animal constructors
function __construct(){
   // some code here
}

}

$dog = new animal();
$dog->setName("spot");
$dog->setSexe("male");
$dog->setType("dog");
echo $dog->getName().' is a '.$dog->getType().'('.dog->getSex().')';

3 > それは最初の質問に依存します... しかし、グローバルには、サンプルのために常に 1 つの依存関係が必要です:

class animal{
private $name, $type, $sex;

// traditional setters and getters
public function setName($name){
    $this->name = $name;
}

public function setSex($sex){
    $this->sex = $sex;
}

private function setType($type){
    // if type is string ( cat, dog, lion ) and you want
    // to linked string in an id in your database (1, 2, 3...). 
    // you want to call your database connection ( declared in you constructor) 
    // and search type id here. 
    $this->type = $type;
}

public function getName(){
    return $this->name;
}

public function getSex(){
    return $this->sex;
}

public function getType(){
    return $this->type;
}

// animal constructors
public function __construct($type){
    // for sample you want to open your database here
    this->setType($type);
}

public function __destruct(){
    // and you want to close your connection here.
}

}
于 2012-07-31T12:50:57.160 に答える