我有一个用 PHP 编写的域模型,并且我的一些类(聚合内的实体)具有公共方法,它们永远不应该从聚合外部调用。
PHP没有包可见性概念,所以我想知道是否有某种标准化的方式来定义@package
和@visibility package
在文档块中,并有一个静态分析工具来报告可见性范围的违规行为。
我目前正在试用PHPStorm,到目前为止我发现它非常好,所以我想知道这个软件是否支持这个功能;如果没有,您知道任何静态代码分析工具吗?
我在 PHP 的功能中看到的与这种思路最接近的平行是使用“受保护”范围而不是公共的这些方法。当然,这需要使用继承来授予对受保护项目的访问权限。在我多年管理 phpDocumentor 的过程中,我从未遇到过任何试图模仿我在 Java 时代记得的那种“包范围”的东西。
如果聚合根中的实体在不通过聚合根的情况下不可修改,那么您必须控制的唯一方法是使实体成为私有或受保护的成员,以便对实体的所有修改都必须通过聚合。
class RootEntity {
private $_otherEntity;
public function DoSomething() {
$this->_otherEntity->DoSomething();
}
public function setOtherEntity( OtherEntity $entity ) {
$this->_otherEntity = $entity;
}
}
有人仍然可以这样做:
$otherEntity = new OtherEntity();
$otherEntity->DoSomethingElse();
$rootEntity->setOtherEntity($otherEntity);
不过,我想您可以使用神奇的 __call() 方法来禁止在除构造期间之外的任何地方设置 _otherEntity。这属于总黑客类别:)
class RootEntity {
private $_otherEntity;
private $_isLoaded = false;
public function __call( $method, $args ) {
$factoryMethod = 'FactoryOnly_'.$method;
if( !$this->_isLoaded && method_exists($this,$factoryMethod) {
call_user_func_array(array($this,$factoryMethod),$args
}
}
public function IsLoaded() {
$this->_isLoaded = true;
}
protected function FactoryOnly_setOtherEntity( OtherEntity $otherEntity ) {
$this->_otherEntity = $otherEntity;
}
}
因此,从那里,当您构建对象时,您可以从您的工厂或存储库中调用 $agg->setOtherEntity($otherEntity)。然后,当您完成构建对象时,调用 IsLoaded()。从那里,没有其他人能够将新的 OtherEntity 引入类中,并且必须在您的聚合上使用公开可用的方法。
我不确定您是否可以称其为“好”答案,但这是我能想到的唯一真正限制对聚合中实体的访问的事情。
[编辑]:另外,忘了提...最接近的文档是phpdoc有一个@internal: http ://www.phpdoc.org/docs/latest/for-users/tags/internal.html
但是,我怀疑它会修改 IDE 的代码完成。不过,您可能会创建一个公共函数/属性,但使用 phpdoc 将其标记为“@access private”,以防止它进入代码完成状态。
到目前为止,PHPStorm 似乎还没有提供这个功能。