2012-07-25 3 views
3

나는 많은 공개 및 비공개 방법이있는 클래스 Foo을 가지고 있습니다. 이러한 메소드 중 하나가 상당히 커지고 있으며이를 위해 특별히 별도의 클래스로 포크 화하려고합니다. 이런 식으로 뭔가 :PHP의 친구 수업 시뮬레이트

<?php 

class Foo 
{ 
    // ... 

    public function doX($a, $b) 
    { 
    $x = new FooXDoer; 
    $x->foo = $this; 
    return $x->run($a, $b); 
    } 

    // ... 
} 

class FooXDoer 
{ 
    public $foo; 

    public function run($a, $b) 
    { 
    // ... 
    } 

    // ... 
} 

FooXDoerFoo의 공개 방법 및 속성 $this->foo를 통해 액세스 할 수 있습니다.

어떻게 이미 Foo를 사용하는 코드의 나머지 부분에 공개하지 않고, Foo의 개인 메서드와 속성에 FooXDoer 액세스 권한을 부여 할 수 있습니까?

private 메서드가 public이고, Foo이 랩핑 된 별도의 클래스 FooPrivate을 만들고 FooXDoer을 참조해야합니까? 무엇 FooPrivate 전화해야합니까?

아니면 내 접근 방식이 완전히 잘못 되었습니까? 이 문제를 어떻게 해결합니까?

+1

당신이 여기서하려고하는 것은 꽤 분명하지 않다.실제 사례를 사용할 수 있습니까? – Sherlock

+0

클래스 사이의 기능을 분리하려면 클래스에 정보가 있는지 확인하십시오. 함수 X가 객체 y의 데이터에 의존하고 그것에 대한 조작을 수행한다면 객체 y에 기능을 유지하는 것이 좋습니다. – bkwint

+0

나는 make 'public으로 말하고 싶지만, 다른 코더들에게 경고하기 위해 코멘트에 넣는다. 당신이 프로그래밍 방식으로 다른 클래스의 액세스를 막을 수있는 무언가를 만들 수는 있지만 꽤 좋지는 않을 것입니다. –

답변

4

traits과 같이 보이면 PHP> = 5.4를 사용하는 경우 문제를 해결하는 것이 가장 좋습니다.

class A { 
    private static $allowedClasses = array('B'); 
    private $a = 1; 

    public function __get($property) { 
     $caller = debug_backtrace(false); 
     if(!isset($caller[1])) 
      throw new Exception('Bla bla'); 
     if(!in_array($caller[1]['class'], self::$allowedClasses)) 
      throw new Exception('Bla bla'); 
     return $this->$property; 
    } 

    public function testB() { 
     $b = new B(); 
     $b->instA = $this; 
     echo $b->getA(); 
    } 

} 

class B { 
    public $instA; 
    public function getA() { 
     return $this->instA->a; 
    } 
} 

class C { 
    public function getA() { 
     $instA = new A(); 
     return $instA->a; 
    } 
} 

$a = new A(); 
$a->testB(); // Works ok; 
$c = new C(); 
$c->getA(); // Throws exception here; 

이 코드는 확실히 가장 좋은 방법이 아닙니다 :)하지만이 가능하기 때문에 내가 여기에 넣어 :

하지 않으면, 나는 다음과 같은 솔루션을 생각했다.

+0

문제에 대한 정확한, 그러나 끔찍한 해결책. 형질이 어떻게 이것을 해결할 수 있는지 간단히 설명해 주시겠습니까? – Jesse

+1

그냥 미친. – Alex

+1

형질은 사용 된 클래스의 메서드와 속성에 액세스 할 수 있습니다. 따라서 특성에 큰 함수를 구현하고 Foo 클래스의 모든 속성을 사용할 수 있습니다. – Eugene

2

PHP는 더 일반적인 전략은 문제 또는 질문으로, 없다, 나는 그것이 PHP는 디자이너에 의해 잘못된 결정이다 언급하지 않았다 읽은로부터 친구 클래스 개념, ...

이럴이 없습니다 너무 광범위 : run() 필요하다

  • 얼마나 많은 개인 특성과 Foo 방법 : 고려해야 할 너무 많은 요인이있다?
  • 추상화의 관점에서 : run()은 얼마나 밀접하게 Foo에 얽혀 있습니까? 그것은 정말로 독립적 인 계급에 속할 자격이 있습니까?
  • FooXDoerFoo 외부로 사용 하시겠습니까?

두 용액 아이디어 : 값 값 또는 배열 또는 객체를 반환 FoocompileRunData() 구현하여 어느

손 필요한 데이터에 foo에서 fooDoer에,

public function doX($a, $b) 
{ 
$x = new FooXDoer; 
$workEnvironment = $this->compileRunData(); 
$x->setEnvironment($workEnvironment); 
$x->foo = $this; 
return $x->run($a, $b); 
} 

또는 상속을 사용하십시오. 특히 보호 속성의 개념을 사용하십시오.

abstract class FooAbstract 
{ 
protected $_basicVar1; 
protected function basicMethod1(/*...*/) { 
    //... 
} 
// ... 
} 

abstract class FooRunner extends FooAbstract 
{ 
protected $_runVar1; 

protected function runMethod1(/*...*/) { 
    //... 
} 

public function run($a, $b) { 
    // ... 
} 
} 

public class Domain_Model_Foo extends FooRunner 
{ 

} 

편집 : 안녕하세요, SO가 이미 대답을 표시하지 않았습니다. 그래, 형질에 대해서도 생각해 봤지만 지금까지는 사용하지 않았기 때문에 그들에 대해 정말로 논평 할 수는 없다.

+0

상속은이 문제에 대한 최선의 해결책이라고 생각합니다. – PiTheNumber