Передает ли много параметров родительскому элементу :: __, создает ли запах кода / плохой ООП? - PullRequest
4 голосов
/ 12 декабря 2011

Я писал какой-то код, и я начал чувствовать себя немного некомфортно из-за грязных вызовов parent::__construct, и мне было интересно, во-первых, это плохая практика ООП, а во-вторых, есть ли более чистый способ сделать это?Посмотрите на особенно экстремальный пример ниже, который вызвал мой вопрос.

<?php
class BrowseNodeLookupRequest extends Request {

    protected $BrowseNodeId;

    public function __construct($Service, $AWSAccessKeyID, $AssociateTag,
            $Operation, $MerchantID = null, $ResponseGroup = null,
            $Version = null, $Style = null, $ContentType = null,
            $XMLEscaping = null, $Validate = null, $BrowseNodeId) {
        parent::__construct($Service, $AWSAccessKeyID, $AssociateTag,
                $Operation, $MerchantID, $ResponseGroup, $Version, $Style,
                $ContentType, $XMLEscaping);
        $this->setBrowseNodeId($BrowseNodeId);
    }

    protected function setBrowseNodeId($BrowseNodeId) {
        if (is_string($BrowseNodeId)) {
            $this->BrowseNodeId = $BrowseNodeId;
        } else {
            throw new Exception('BrowseNodeLookupRequest Parameter (BrowseNodeId
                                 ) Must be a String');
        }
    }

}
?>

Ответы [ 4 ]

3 голосов
/ 12 декабря 2011

Это плохая практика - иметь столько аргументов для любой функции, будь то __parent::construct или нет.

Слишком легко все испортить, особенно в PHP.Часто это указывает на то, что вам не хватает объектов (или слишком сильное сцепление между деталями).Я бы даже предпочел передать объект «конфигурации», если вы не можете найти другие отсутствующие объекты.

class ConfigFoo
{
  public $Service, $AWSAccessKeyID, ..., $foo, $bar;
}

$cfg = new ConfigFoo();
$cfg->Service = 'whatever';
...

$req = new BrowseNodeLookupRequest($cfg);

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

И, конечно, класс может быть более продвинутым, чем простые общедоступные свойства.Вы можете управлять целостностью данных и т. Д.

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

1 голос
/ 12 декабря 2011

Вааааа, слишком много параметров ИМО. Id либо передает массив или потенциально разделяет задачи в различные модели, а затем внедряет их в объект через конструктор.

0 голосов
/ 13 декабря 2011

Благодаря всем комментаторам, в частности Мэтью, решение, с которым я пришел, состоит в том, чтобы удалить необязательные параметры из метода конструктора родительского класса и добавить их в общедоступные методы установки, доступные в родительском классе. Пересмотренный код ниже с примером использования. Обратите внимание, что '-> setValidate' и '-> setResponseGroup' являются новыми методами, унаследованными от родительского класса. Очевидно, что если вы находитесь в подобной ситуации, но все ваши параметры обязательны, вам нужно выбрать один из других вариантов, описанных в ответах.

Пересмотренный класс:

<?php
class BrowseNodeLookupRequest extends Request {

    protected $BrowseNodeId;

    public function __construct($Service, $AWSAccessKeyID, $AssociateTag,
            $Operation, $BrowseNodeId) {
        parent::__construct($Service, $AWSAccessKeyID, $AssociateTag, $Operation);
        $this->setBrowseNodeId($BrowseNodeId);
    }

    protected function setBrowseNodeId($BrowseNodeId) {
        if (is_string($BrowseNodeId)) {
            $this->BrowseNodeId = $BrowseNodeId;
        } else {
            throw new Exception('BrowseNodeLookupRequest Parameter (BrowseNodeId
                                 ) Must be a String');
        }
    }

}
?>

Пример использования:

<?php
$noderequest = new BrowseNodeLookupRequest($Service, $AWSAccessKeyID, $AssociateTag,
            $Operation, $BrowseNodeId);
//If the optional params are required//
$noderequest->setResponseGroup('Blah');
$noderequest->setValidate('True');
//etc.
?>
0 голосов
/ 12 декабря 2011

Совершенно неплохо вызывать parent :: __ construct ();

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

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

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