13

私は約を作成する必要があります。5 ~ 7 クラスの場合、すべてのクラスに多数のメンバーが含まれます (各クラスに 20 人のメンバーが含まれるとします)。次のように、パブリック アクセスを使用してそれらを作成できます。

class A {
    public $myPropertyOne = '';
    public $myPropertyTwo = '';
    ...
}

もちろん、これらのメンバーを非公開にし、各プロパティの get/set メソッドを作成する私の好みの方法です。いえ

class A {
    private $myPropertyOne = '';
    private $myPropertyTwo = '';

    public function getMyPropertyOne() {
            return $this->myPropertyOne;
    }

    public function setMyPropertyOne($myPropertyOne) {
            $this->myPropertyOne = $myPropertyOne;
    }

    public function getMyPropertyTwo() {
            return $this->myPropertyTwo;
    }

    public function setMyPropertyTwo($myPropertyTwo) {
            $this->myPropertyTwo = $myPropertyTwo;
    }
}

しかし、クラスには 20 個のプロパティがあることを考えると、これに加えて 40 個のメソッドを追加する必要があります。そして、ここでの私の懸念は、これによりスクリプトがどのように遅くなり、より多くのメモリが必要になるかということです (このようなクラスがいくつかあることを思い出してください)。

別の解決策として、魔法の関数 __set、__get を使用することもできますが、開発 IDE のコード補完では重要なプロパティが提案されないため、そうしたくありません。

これがコンパイルされた言語 (C++ など) である場合、質問はなく、ゲッター、セッターを使用してソリューションを使用しますが、PHP はインタープリター言語であるため、スクリプトで使用する RAM を減らし、できるだけ高速にすることに関心があります。

事前に感謝します。この質問に関するご意見をお待ちしております。


私の意見

ご回答いただきありがとうございます。誰かがこの質問に対する回答を探している場合に備えて、私の意見を共有したかっただけです。

これはオプティマイザのタスクであるため、パフォーマンスを気にするべきではないという人たちには完全には同意できません。これは重要な要素だと思います (少なくとも私にとっては)。PHP などのインタープリター言語を扱うときは、常にメモリと速度について考える必要があります (これは、私が DOS 用のシステム アプリを開発していたときのことを思い出します :) そして、常に貧弱な CPU と合計 RAM のキロバイトに制限されていたので、追加で節約できれば幸せです。バイト)、PHP開発では、追加するサーバーの数に関係なく、ユーザー数は常に高くなるため、クラシック/セーフ/適切な方法に従うか、これを回避するかを常に決定する必要があります。速度またはメモリがいくらか向上します。

だから....私の意見では、ここでの最善の方法は、すべてのメンバーにパブリックアクセスを使用し、すべてのプロパティのゲッター/セッターを避け、値の前にデータの検証または初期化が必要なプロパティの get/set メソッドでプライベートアクセスを使用することです。悩ませる。

例えば:

class B {
    public $myPropertyOne = '';
    public $myPropertyTwo = '';
    private $myPropertyThree = array();


    public function getMyPropertyThree() {
        return $this->myPropertyThree;
    }

    public function setMyPropertyThree($val) {
        if(!is_array($val)) {
            return;
        }

        $this->myPropertyThree = $val;
    }
}

私の質問に時間を割いていただきありがとうございます!

4

6 に答える 6

5

簡単なテストでは、インスタンスが同じ量のメモリを使用し、クラス内のメソッドの数に影響されないことが示されています。

メソッドのないクラス:

class Test1 { }

20個のメソッドを持つクラス:

class Test2 {

    function test1() { return true; }
    function test2() { return true; }
    function test3() { return true; }
    function test4() { return true; }
    function test5() { return true; }
    function test6() { return true; }
    function test7() { return true; }
    function test8() { return true; }
    function test9() { return true; }
    function test10() { return true; }
    function test11() { return true; }
    function test12() { return true; }
    function test13() { return true; }
    function test14() { return true; }
    function test15() { return true; }
    function test16() { return true; }
    function test17() { return true; }
    function test18() { return true; }
    function test19() { return true; }
    function test20() { return true; }

}

テストループ、両方のテストで同じ:

$test = array();
$base = memory_get_usage();
for ($i = 0; $i < 10000; $i++) {
    $test[] = new ClassToBeTested();
}
$used = memory_get_usage() - $base;
print("used: $used\n");

クラスTest1の結果(メソッドなし):

used: 3157408

クラスTest2の結果(20メソッド):

used: 3157408

1つのスクリプトで2つのテストを実行すると、PHPの内部割り当てが明らかになり、2番目のテストは、どちらが1番目か2番目かに関係なく、最初のテストよりも少ないメモリを消費するため、2つの別々のスクリプトで実行しました。

実際のクラス定義のためにより多くのメモリを使用することは確かですが、明らかにこのコストは、インスタンスごとではなく、クラスごとに1回だけ発生します。メモリ使用量について心配する必要はありません。

于 2012-06-23T07:51:12.087 に答える
5

しかし、クラスを考えると20のプロパティがあります

これだけ多くのプロパティがあることは、通常、情報が間違っていることを示しています。それらのいくつかを独自のクラスにグループ化できるかどうかを確認してください。

これに加えて、40個のメソッドを追加します。

全くない。これらのクラスがダムデータ構造体でない限り、カプセル化を破るため、ゲッターとセッターは必要ありません。オブジェクトに処理を指示するためのパブリックAPIにメソッドを配置します。

そして、ここでの私の懸念は、これによってスクリプトがどのように遅くなり、これに必要なメモリが大幅に増えるかということです(このようなクラスがいくつかあることを忘れないでください)。

これは問題ではありません。

別の解決策は、魔法の関数__set、__ getを使用することですが、開発IDEのコード補完では、私にとって重要なプロパティが提案されないため、使用したくありません。

最新のIDEは、魔法のメソッドでオートコンプリートできます。

ただし、マイクロレベルでのパフォーマンスについてすでに懸念している場合は、魔法のメソッドは間違いなく遅いため、必要ありません。

それとは別に、Magicメソッドは、ゲッターとセッターの代わりではなく、アクセスできないプロパティまたはメソッドが呼び出されたときにトリガーされるエラーハンドラーです。

また、魔法のメソッドは自明ではなく、APIを読みにくくします。

于 2012-06-23T07:52:05.823 に答える
1

マジック メソッドによって実装されたクラスのプロパティを IDE で強調表示するには、次のように @property PHPDoc@propertyタグを使用します。

<?php
/**
* @property int id Blog post ID
* @property string title Blog post Title
*/
class Post {

}

PHPDoc の @property の詳細はこちら: http://manual.phpdoc.org/HTMLSmartyConverter/PHP/phpDocumentor/tutorial_tags.property.pkg.html

質問された他の問題については、Karoly Horvath のコメントがPHP OOP の多くのセッター、ゲッターを完全にカバーしています。

于 2012-06-23T08:52:27.937 に答える
0

私のコードでは、プロパティの名前が小文字で宣言されていると見なされていることに注意してください...

  <?php

    class Modelo {
        var $attr1 = "default";
        var $attr2 = 0;


        public function __call($name, $arguments)
        {
            if (method_exists($this, ($method = $name))){
                return $this->$method();
            }
            else{       
                $attribute = split("get",$name);
                if(count($attribute)==2){
                    $attribute = strtolower($attribute[1]);
                    if(isset($this->$attribute)){
                        return ($this->$attribute);
                    }
                }else{
                    $attribute = split("set",$name);
                    if(count($attribute)==2){
                        $attribute = strtolower($attribute[1]);
                        if(isset($this->$attribute) && count($arguments)==1){
                            $this->$attribute=$arguments[0];
                        }else{
                            die("$name number of arguments error: ".join($arguments,","));
                        }
                    }else{
                        die("$name doesn't exist!");
                    }               
                }           
            }
        }


    }

    echo "<pre>";
    $m = new Modelo();
    print_r(
        array(
            "objetct"=>$m
            ,"getAttr1"=>$m->getAttr1()
            ,"getAttr2"=>$m->getAttr2()
        )
    );
    echo "setAttr1\n";
    $m->setAttr1("by set method");
    print_r(
        array(
            "objetct"=>$m
            ,"getAttr1"=>$m->getAttr1()
            ,"getAttr2"=>$m->getAttr2()
        )
    );

    ?>
于 2012-06-23T08:13:23.993 に答える
0

前に述べたように、クラスに非常に多くのプロパティが必要なのは非常に奇妙です。ただし、場合によっては(かなりまれに)発生する可能性があります。ただし、通常、これらのプロパティには一種のリンクが必要です。つまり、プロパティではなくハッシュマップに格納できます。次に、ゲッターとして1つのメソッドが必要になります。

さて、それは確かにより多くのリソースを消費するでしょう、本当です。オートコンプリートについては、定数を使用してください:次のように入力するだけです:

 $my_class->getFromHashMap($parameter)

また、パラメータを入力するときは、クラスに格納されている定数を使用します。ここでは、オートコンプリートが役立ちます。

于 2012-06-23T08:16:50.400 に答える