3

更新:このクラス構造に「多すぎる」静的メソッド(現在は4つしかないことに気づきましたが、最初は2つから始めました)という質問を言い換えますか? もしそうなら、モデルクラスから静的関数を削除できるように、これらのクラスをリファクタリングしてある種の Finder クラスを使用する方法に関する提案はありますか?

次の抽象クラスがあります。

abstract class LP_Model_Abstract
{
protected static $_collectionClass = 'LP_Model_Collection';

protected $_row = null;

protected $_data = array();

public function __construct($row = null)
{
    $this->_row = $row;
}

public function __get($key)
{
    if(method_exists($this, '_get' . ucfirst($key)))
    {
        $method = '_get' . ucfirst($key);
        return $this->$method();            
    }
    elseif(isset($this->_row->$key))
    {
        return $this->_row->$key;
    }
    else
    {
        foreach($this->_data as $gateway)
        {
            if(isset($gateway->$key))
            {
                return $gateway->$key;
            }
        }
    }   
}

public function __set($key, $val)
{
    if(method_exists($this, '_set' . ucfirst($key)))
    {
        $method = '_set' . ucfirst($key);
        return $this->$method($val);            
    }
    elseif(isset($this->_row->$key))
    {
        $this->_row->$key = $val;
        return $this->_row->$key;
    }
    else
    {
        foreach($this->_data as $gateway)
        {
            if(isset($this->_data[$gateway]->$key))
            {
                $this->_data[$gateway]->$key = $val;
                return $this->_data[$gateway]->$key;
            }
        }
    }
}

public function __isset($key)
{
    return isset($this->_row->$key);
}

public function save()
{
    $this->_row->save();
}

abstract public static function get($params);
abstract public static function getCollection($params = null);
abstract public static function create($params);

}

そして、クラス テーブルの継承スキームに追加機能を提供するこのクラス (ファクトリ方式で追加機能を決定するには型が重要です):

abstract class LP_Model_Factory_Abstract extends LP_Model_Abstract
{
    protected static $_collectionClass = 'LP_Model_Collection_Factory';

    abstract public static function factory($row);
}

これらは、最終的に次のタイプのクラス宣言になります。

class Model_Artifact extends LP_Model_Factory_Abstract
{
    protected static $_artifactGateway = 'Model_Table_Artifact';

    public static function create($params)
    {

    }

    public static function get($params) 
    {
        $gateway = new self::$_artifactGateway();

        $row = $gateway->fetchArtifact($params);

        return self::factory($row);        
    }

    public static function getCollection($params = null) 
    {
        $gateway = new self::$_artifactGateway();

        $rowset = $gateway->fetchArtifacts($params);

        $data = array(
            'data' => $rowset,
            'modelClass' => __CLASS__
        );

        return new self::$_collectionClass($data);
    }

    public static function factory($row)
    {
        $class = 'Model_Artifact_' . $row->fileType;
    }
}

クラスにあまりにも多くの静的メソッドがあることにいつ気がつきますか? また、静的メソッドがある種の Finder クラスにカプセル化されるように、既存の設計をどのようにリファクタリングしますか?

4

6 に答える 6

4

Brubakerに同意し、それを私の考えに追加する必要があります。それは、メソッドの数ではなく、前述のメソッドの機能です。クラスに多くのメソッド(静的またはその他)が必要であると考え始めた場合、それらを再グループ化して、より直感的なアーキテクチャにリファクタリングできることに気付くかもしれません。

于 2009-01-14T22:06:01.377 に答える
3

多くの静的メソッドが必要かどうかを判断するときに使用する最初の指標は、メソッドの機能がステートレスでないかどうかです。静的メソッドが存在するオブジェクトの状態を変更する場合、それらはおそらく静的であってはなりません。

于 2009-01-14T21:59:56.957 に答える
2

私は BaileyP に同意し、数ペニーを追加します。

私は常に、クラスには存在する理由が 1 つあるべきだという考えに取り組んでいます。1 つのジョブを実行する必要があり、それをうまく実行する必要があります。それを決定し、そのクラスへのインターフェースがどうあるべきかを理解した後、クラスのインスタンスの状態を変更しない関数を調べて、静的としてマークします。

于 2009-01-14T23:45:40.690 に答える
1

私は私の2セントを投入します。

まず、「クラスに10を超える統計が多すぎると!」など、なんらかの任意の制限を設定しても役に立たないことに同意します。理にかなっているときにリファクタリングしますが、架空の境界に達したという理由だけでリファクタリングを開始しないでください。

ステートフルとステートレスについてのBrubakerのコメントに100%同意することはできません。問題はクラスとインスタンスに関するものだと思います。静的メソッドは、ステートフルな変更である別の静的プロパティの値を変更できるためです。

したがって、次のように考えてください。メソッド/プロパティがクラスのものであるか、クラスに関連している場合は、おそらく静的である必要があります。メソッド/プロパティがクラスのインスタンスのものであるか、クラスのインスタンスに関連している場合、静的であってはなりません。

于 2009-01-14T22:32:33.710 に答える
1

個人的には、静的メソッドがいくつあっても問題の兆候であることがわかりました。クラスにインスタンス メソッドと静的メソッドがある場合、ほとんどの場合、クラスを 2 つの別個のエンティティに分割し、静的メソッドをインスタンス メソッドに変更できます。

クラスは、本質的にグローバルであるという独特の特性を持つ、特別な種類のオブジェクトと考えてください。これはグローバル変数であるため、非常に強いレベルの結合を意味するため、それへの参照を減らす必要があります。静的メンバーを参照する必要があります。つまり、コードはクラスに強いレベルで結合されます。

于 2009-01-14T23:24:01.687 に答える