Php, статические методы и наследование .. в поисках правильного шаблона - PullRequest
0 голосов
/ 23 августа 2011

Каков наилучший шаблон для достижения этого поведения?

У меня есть много методов, скажем method_1 .. method_N, которые могут быть все параметризованы одним параметром, скажем, $ k.Я хотел бы, чтобы они были внутри класса в качестве статических методов, поэтому, конечно, я мог бы написать свой ComputationClass следующим образом:

class Computation {
    static function method1( $k, $otherParams ) { ... }
    static function method2( $k, $otherParams ) { ... }
    static function method3( $k, $otherParams ) { ... }
}        

Теперь, поскольку $ k принадлежит определенному диапазону значений, скажем {'dog',' cat ',' mouse '}, я хотел бы создать множество подклассов вычислений, по одному на каждое возможное значение.

class Computation_Dog extends Computation {
    static function method1( $otherParams ) { parent::method1('dog', $otherParams); }
    static function method2( $otherParams ) { parent::method2('dog', $otherParams); }
    static function method3( $otherParams ) { parent::method3('dog', $otherParams); }
}
class Computation_Cat extends Computation { .. }
class Computation_Mouse extends Computation { .. }

Но это довольно уродливо и заставляет меня отказаться от преимуществнаследование: что произойдет, если я добавлю метод в вычисления?нужно отредактировать все подклассы .. Затем я ловко переключился на это:

abstract class Computation {
    abstract static function getK();

    static function method1($otherParams) { ... self::getK() .. }
    static function method2($otherParams) { ... self::getK() .. }
    static function method3($otherParams) { ... self::getK() .. }
}

class Computation_Dog extends Computation {
    static function getK() { return 'dog'; }
}

Хорошая попытка, но она не работает, потому что статические методы, кажется, не запоминают стек наследования, и self ::getK () будет вызывать Computation :: getK () вместо Computation_Dog :: getK ().

Хорошо .. в надежде быть достаточно ясным ... как бы вы разработали такое поведение?PS: мне действительно нужны они как статические методы

Спасибо

Ответы [ 3 ]

1 голос
/ 23 августа 2011

Я бы не стал проектировать это поведение вообще. Если вам нужно вызвать parent :: Method1 ('dog'), это означает, что парант, очевидно, знает о вычислении собак. Ваш класс Calculating_Dog - это просто тупой класс, содержащий сокращения.

И да, если вы добавите метод в базовый класс, вам придется добавить его ко всем другим классам.

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

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

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

[править]

Вы можете использовать __callStatic (из PHP 5.3) для перехвата статических вызовов методов несуществующих методов. Затем вы можете отменить дополнительный параметр 'dog' в начале атрибутов и вызвать базовый класс Calculate. Здесь показаны два способа:

/* METHOD 1 Use __callStatic and make the parent function protected
   to hide them. Else __callStatic won't work. */
class Calculate1
{
    protected static function Method1($type, $param)
    {
        echo "Retrieving call for $type with param $param.";
    }
}

class Calculate_wrapper1 extends Calculate1
{
    static function __callStatic($functionName, $attributes)
    {
        array_unshift($attributes, 'dog');
        var_dump($attributes);
        // using get_parent_class()
        return call_user_func_array(array(get_parent_class(), $functionName), $attributes);
    }
}

Calculate_wrapper1::Method1('String');

/* METHOD 2 Don't inherit the wrapper from Calculate. This way the methods of
   Calculate itself can (must!) be public. */
class Calculate2
{
    public static function Method1($type, $param)
    {
        echo "Retrieving call for $type with param $param.";
    }
}

class Calculate_wrapper2
{
    static function __callStatic($functionName, $attributes)
    {
        array_unshift($attributes, 'dog');
        var_dump($attributes);
        // using the fixed class name
        return call_user_func_array(array('Calculate2', $functionName), $attributes);
    }
}

Calculate_wrapper2::Method1('String');
0 голосов
/ 23 августа 2011

Начиная с php5.3, вы можете использовать Поздние статические привязки. Используйте static::getK() вместо self::getK(). Поздние статические привязки

0 голосов
/ 23 августа 2011

Я не уверен, что полностью понимаю код, но думаю, что для решения вашей проблемы используется Поздние статические привязки .

Однако, если вы немного уточните, что именно делают методы, мы могли бы предложить вам лучшее общее решение.

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