PHP - 设计无状态类

时间:2017-08-30 16:48:59

标签: php dependency-injection

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

我们假设我们有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...
  }

}

此类的单个实例难以重用。如何让它成为无国籍?

3 个答案:

答案 0 :(得分:0)

  

如何使其无国籍

你不会在这里谈论'无国籍'。见https://en.wikipedia.org/wiki/Stateless

让您的函数保持静态:https://secure.php.net/manual/en/language.oop5.static.php

class DirectoryUtils {
    ...

    public static function renameDirectory($newName) {
        ...
    }

}

然后你简单地称之为:

DirectoryUtils::renameDirectory($name);

答案 1 :(得分:0)

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

重写你的课程:

{{ showAll }}

答案 2 :(得分:0)

我认为您需要扩大您在此处调查的范围:您可以将哪些有意义的服务放入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']); 
    }
]

您可能创建的另一种服务类型是 factory ,它抽象部分文件系统,并为您提供不同的Directory个对象,例如:

$my_home_dir = $factory->getHomeDir('imsop');

这里,在DI中构建的状态可能是在以下内容中工作的基本目录:

[
     'DirectoryFactory' => function($config) { 
         return new DirectoryFactory($config['base_dir_path']); 
     }
]

这些类都不是&#34;无状态&#34;,但两者都是不可变的 - 一旦构建,你不会将它们改为指向不同的目录,你使用不同的实例各种目的。

DirectoryFactory类实际上可以通过对所有逻辑进行硬编码来实现无状态(例如,#34;主目录始终为'/home/' . $user_name&#34;)。这可能对放入DI容器很有用,因为您可以用具有不同硬编码规则的版本或测试模拟替换。然而,如图所示,缺乏状态并不是一个必要的前提条件,因为它可以作为一个单独的&#34;从这个意义上说。