Сколько статических методов слишком много для одного класса? - PullRequest
3 голосов
/ 15 января 2009

ОБНОВЛЕНИЕ: Перефразируя вопрос, задают ли «слишком много» статических методов (я понимаю, что сейчас в этой структуре классов только 4, но я изначально начал с 2)? Если да, какие-либо предложения о том, как изменить эти классы, чтобы использовать какой-то класс Finder, чтобы я мог удалить статические функции из классов Model?

У меня есть следующий абстрактный класс:

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?

Ответы [ 6 ]

4 голосов
/ 15 января 2009

Я должен согласиться с Brubaker и добавить, что, по моему мнению, это не столько количество методов, сколько функциональность этих методов. Если вы начнете думать, что в вашем классе есть много методов (статических или иных), вы можете обнаружить, что их можно перегруппировать и преобразовать в более интуитивную архитектуру.

3 голосов
/ 15 января 2009

Первый индикатор, который я использую при определении, есть ли у меня много статических методов, - это если функциональность методов не без состояний. Если статические методы изменяют состояние объекта, в котором они находятся, они, вероятно, не должны быть статическими.

2 голосов
/ 15 января 2009

Если вы хотите создать повторно используемый и тестируемый код, вам следует вообще избегать статических методов . Код, который вызывает статические методы (или конструкторы классов, не относящихся к данным), нельзя тестировать изолированно.

Да, вам придется обойтись большим количеством объектов, если вы исключите статические методы. Это не обязательно плохо. Это заставляет вас думать о границах и сотрудничестве между вашими компонентами дисциплинированным образом.

2 голосов
/ 15 января 2009

Я согласен с BaileyP и добавлю пару копеек:

Я всегда работаю с идеей, что у класса должна быть одна причина существования; у него должна быть одна работа, и она должна делать это хорошо. После того, как я это решил и выяснил, каким должен быть интерфейс к этому классу, я прошёл и пометил все функции, которые не меняют состояние экземпляра класса, как статические.

1 голос
/ 15 января 2009

Лично я считаю, что любое количество статических методов является признаком проблемы. Если в вашем классе есть методы экземпляра и статические методы, то, скорее всего, вы можете разделить класс на две отдельные сущности и изменить статические методы на методы экземпляра.

Думайте о классе как об особом объекте, с характерным свойством которого он является глобальным по своей природе. Поскольку это глобальная переменная, она подразумевает очень сильный уровень связности, поэтому вам следует уменьшить количество ссылок на нее. Статические члены должны будут быть направлены, это означает, что ваш код получит сильный уровень связи с классом.

1 голос
/ 15 января 2009

Я добавлю 2 цента.

Прежде всего, я согласен с тем, что установка какого-то произвольного предела бесполезна, например: «Как только у меня в классе более 10 статик, это слишком много!». Рефакторинг, когда это имеет смысл, но не начинайте делать это только потому, что вы достигли какой-то воображаемой границы.

Я бы не согласился на 100% с комментариями Брубэйкера о сохранении состояния без сохранения состояния - я думаю, что проблема скорее в классах против экземпляров. Потому что статический метод может изменить значение другого статического свойства, которое является изменением состояния.

Итак, подумайте об этом так: если метод / свойство принадлежит или относится к классу , то он, вероятно, должен быть статическим. Если метод / свойство принадлежит или относится к экземпляру класса, он не должен быть статическим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...