PHP-设计一个无状态类

PHP-设计一个无状态类,php,dependency-injection,Php,Dependency Injection,我想设计一个无状态类,以便在应用程序的多个位置重用同一实例,而不会产生任何副作用。这是必要的,因为许多依赖项注入容器总是返回相同的类实例 假设我们有DirectoryUtils类: <?php class DirectoryUtils{ private $dir; public function __constructor($dir){ if($this->checkDirectory($dir)){ $this->dir = $dir;

我想设计一个无状态类,以便在应用程序的多个位置重用同一实例,而不会产生任何副作用。这是必要的,因为许多依赖项注入容器总是返回相同的类实例

假设我们有
DirectoryUtils
类:

<?php

class DirectoryUtils{

  private $dir;

  public function __constructor($dir){
    if($this->checkDirectory($dir)){
      $this->dir = $dir;
    }else{
      throw new Exception("Invalid Directory");
    }
  }

  public function deleteAllFiles(){
    // code to delete all files in $this->dir;
  }

  public function renameDirectory($newName){
    // code to rename $this->dir name to $newName
  }

  private function checkDirectory($dir){
    // check if directory exists, is writable...
  }

}

如何使它成为无国籍的

你在这里不谈“无国籍”。看

将您的功能设置为静态:

i、 e

那么你就这么简单地称呼它:

DirectoryUtils::renameDirectory($name);

无状态类的基本规则是没有任何实例变量/属性来存储状态。类方法类似于只处理参数的实用程序或帮助函数

重写您的类:

<?php

class DirectoryUtils{      

  public function deleteAllFiles($dir){
    // code to delete all files in $dir;
  }

  public function renameDirectory($dir, $newName){
    // code to rename $dir name to $newName
  }
}

我认为您需要扩大您在这里研究的范围:您可以将什么有意义的服务放在DI容器中以供重用

类的问题不在于它是有状态的,而在于它的名称反映了对其用途的误解。这个类代表一个特定的目录,因此应该适当地命名,例如

$my_home_dir = new Directory('/home/imsop');
$your_home_dir = new Directory('/home/abskmj');
$diff_tool->compareDirs($my_home_dir, $your_home_dir);
在您的DI容器中,您将为需要访问的特定目录放置几个此类的特定实例,例如

[
    'CacheDir' => function($config) { 
        return new Directory($config['cache_path']); 
    },
    'LogDir' => function($config) { 
        return new Directory($config['log_path']); 
    }
]
您可能创建的另一种服务类型是工厂,它抽象了文件系统的一部分,并为您提供不同的
目录
对象,例如:

$my_home_dir = $factory->getHomeDir('imsop');
在这里,DI中构造的状态可能是要在其中工作的基本目录:

[
     'DirectoryFactory' => function($config) { 
         return new DirectoryFactory($config['base_dir_path']); 
     }
]
这两个类都不是“无状态”的,但它们都是不可变的——一旦构建,您不会将它们更改为指向不同的目录,而是为每个目的使用不同的实例


实际上,
DirectoryFactory
类通过硬编码所有逻辑(例如,“主目录总是
'/home/'.$user\u name
”)可以是无状态的。这对于放入DI容器仍然很有用,因为您可以用不同的硬编码规则或测试模拟替换版本。然而,如图所示,缺少状态并不是在这个意义上作为“单例”有用的必要先决条件。

StateLess==不知道以前发生了什么。这是必要的,因为许多依赖项注入容器总是返回类的同一实例-其中许多容器还允许您解决这个问题。您尝试过哪些?@iainn PHP-DI将在下一个主要版本中删除prototype作用域。
无状态类的基本规则是没有任何实例变量/属性来存储状态
那么为什么还要有构造函数呢?PHP没有添加默认构造函数。但是,如果所有方法都是静态的,则不需要构造函数。实际上,它可能具有某些共享属性,例如可以跨多个方法共享的数据库连接calls@abskmj构造函数从来都不是必需的。参考资料中讨论的问题是,当您创建子类时,您必须知道父类是否有构造函数,是否调用它;但是如果没有,您可以跳过对它的调用,这样就没有问题了。因此,如果您希望人们从类继承,那么提供一个空的是有帮助的,但这不是必需的。谢谢@IMSoP,我同意,本次讨论的背景是不同的。我已经用代码更新了。我不是在说静态方法。。。看这里:你说的是单例。单例范围(与PHP-DI相关),而不是单例设计模式。我强烈建议你读一下。
[
     'DirectoryFactory' => function($config) { 
         return new DirectoryFactory($config['base_dir_path']); 
     }
]