我有一个类Foo
,其中包含许多公共和私有方法。其中一种方法变得相当大,我想把它分成一个专门为此目的的单独的类。像这样:
<?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 )
{
// ...
}
// ...
}
FooXDoer
可以通过Foo
访问$this->foo
的公开方法和属性。
如何让FooXDoer
访问Foo
的私有方法和属性,而不将其公开用于已使用Foo
的其余代码?
我应该创建一个单独的类FooPrivate
,其中私有方法是公共的,Foo
包装,然后FooXDoer
引用它?应该FooPrivate
应该叫什么?
或者我的方法完全错了?你如何解决这个问题呢?
答案 0 :(得分:4)
如果您使用PHP&gt; = 5.4,traits似乎最能解决您的问题。
如果没有,我想到了以下解决方案:
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;
这段代码绝对不是最佳做法:)但是因为我可以把它放在这里。
答案 1 :(得分:2)
PHP没有朋友类概念,从我读过的内容我不会说这是一个错误的决定由php设计师...
恕我直言,没有一般策略,因为问题或问题太广泛:有太多因素需要考虑:Foo
中需要多少run()
个私有媒体资源和方法?run()
与Foo
的紧密联系有多紧密?是否真的“值得”进入一个独立的班级? FooXDoer
之外使用Foo
?解决方案的两个想法:
将所需数据从foo
移交给fooDoer
,值为值或通过在compileRunData()
上实现返回数组或对象的Foo
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
{
}
编辑:嘿,所以没有告诉我已经有答案了。是的,也考虑过特质,但直到现在才使用它们所以不能真正评论它们