2011-08-23 3 views
0

이 동작을 수행하는 가장 좋은 패턴은 무엇입니까?PHP, 정적 메소드 및 상속 .. 유효한 패턴 검색

나는 하나의 매개 변수, 예를 들어 $ k로 모두 매개 변수화 할 수있는 method_1 .. method_N과 같은 많은 메소드가 있습니다. 나는이 같은 내 ComputationClass를 작성할 수 물론 그래서 내가 정적 메서드와 같은 클래스의 내부를하고 싶은 :

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

을 지금 $의 k는 값의 특정 범위에 속하기 때문에, { '개'라고, 'cat', 'mouse'}, 가능한 한 모든 값에 대해 하나씩 Computation의 여러 하위 클래스를 만들고 싶습니다.

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'; } 
} 

니스 시도하지만, 정적 메서드는 상속 스택을 기억하지 않는 것 때문에 작동하지 않습니다, 자기 :: getK을()는 Computation_Dog :: getK() 대신 Computation :: getK()를 호출합니다.

글쎄 .. 충분히 명확 해 지길 바래요. 어떻게이 행동을 고안하겠습니까? PS : 정말 내가 모든이 동작을 설계하지 않을 정적 메서드로

감사

답변

1

그들을 필요합니다. parent :: Method1 ('dog')를 호출해야하는 경우, 즉 parant가 개 계산에 대해 알고 있음을 의미합니다. Calculating_Dog 클래스는 속기가 포함 된 바보 같은 클래스입니다.

예, 기본 클래스에 메소드를 추가하면 다른 모든 클래스에 메소드를 추가해야합니다.

정적 클래스 대신 인스턴스가있는 경우 계산 유형이 포함 된 클래스에 속성을 추가 할 수 있습니다. 그런 다음 긴 기능이 필요하지 않습니다. 기본 클래스에 속기 함수를 추가하고 매개 변수 대신 속성을 사용할 수 있습니다. 이 클래스에 보호 된 생성자를 지정하고 올바른 유형으로 전달할 수 있습니다.

그런 다음 원하는 매개 변수로 부모 생성자를 호출하는 매개 변수없이 생성자가있는 하위 항목을 만들 수 있습니다. 그런 다음 이러한 자손에 대한 단일 참조를 만듭니다.

원하는대로 접근하는 방법이 될 것입니다. 그러나 이것이 최선의 해결책인지를 결정하기 위해 실제로 달성하고자하는 것을 보거나들을 필요가 있습니다.

[편집]

당신은 (PHP 5.3에서) 존재하지 않는 방법의 정적 메서드 호출을 잡으려고 __callStatic를 사용할 수 있습니다. 그런 다음 추가 '개'매개 변수를 특성 시작 부분으로 이동하고 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

대답 주셔서 감사합니다. 예, 당신이 무슨 말을 사실입니다 ...하지만, 내가 지정한대로, 나는 정적 메서드를 필요로 .. 그래, Calculating_Dog 클래스는 래퍼를 포함하는 단지 바보 같은 클래스입니다 ..하지만 내가이를 사용하여 가능한 솔루션을 추가 – user831634

+0

을 원하는 것을 정확히 __call 정적 마법 방법입니다. 모든 정적 함수 호출을 클래스 자체에 존재하지 않는 함수로 재 지정할 수 있습니다. 이렇게하면 모든 함수 선언을 모든 래퍼 클래스에 복사 할 필요가 없습니다. – GolezTrol

+0

다시 한 번 감사드립니다. __callStatic을 사용하면 좋은 트릭입니다. – user831634

0

는 내가 완전히 코드를 이해 모르겠지만, 나는 당신의 문제에 대한 해결책이 Late Static Bindings을 사용하고있는 것 : 두 가지 방법이 여기에 입증된다.

그러나 방법이 정확히 무엇인지 구체적으로 설명 할 수 있다면 더 나은 전체 솔루션을 제공 할 수 있습니다.

+0

감사합니다. 예, Late Static Bindings는 답변입니다 – user831634

0

php5.3부터 늦은 정적 바인딩을 사용할 수 있습니다. self::getK() 대신 static::getK()을 사용하십시오. Late Static Bindings

+0

고맙습니다. Late Static Bindings는 내가 필요한 것입니다. – user831634