PHP 代码简洁之道(小结)(6)

function splitIntoFirstAndLastName(string $name): array
{
 return explode(' ', $name);
}

$name = 'Ryan McDermott';
$newName = splitIntoFirstAndLastName($name);

var_dump($name); // 'Ryan McDermott';
var_dump($newName); // ['Ryan', 'McDermott'];

不要定义全局函数

在很多语言中定义全局函数是一个坏习惯,因为你定义的全局函数可能与其他人的函数库冲突,并且,除非在实际运用中遇到异常,否则你的 API 的使用者将无法觉察到这一点。接下来我们来看看一个例子:当你想有一个配置数组,你可能会写一个 config() 的全局函数,但是这样会与其他人定义的库冲突。

不好的:

function config(): array
{
 return [
  'foo' => 'bar',
 ]
}

好的:

class Configuration
{
 private $configuration = [];

 public function __construct(array $configuration)
 {
  $this->configuration = $configuration;
 }

 public function get(string $key): ?string
 {
  return isset($this->configuration[$key]) ? $this->configuration[$key] : null;
 }
}

获取配置需要先创建 Configuration 类的实例,如下:

$configuration = new Configuration([
 'foo' => 'bar',
]);

现在,在你的应用中必须使用 Configuration 的实例了。

不要使用单例模式

单例模式是个 反模式。 以下转述 Brian Button 的观点:

单例模式常用于 全局实例, 这么做为什么不好呢? 因为在你的代码里 你隐藏了应用的依赖关系,而没有通过接口公开依赖关系 。避免全局的东西扩散使用是一种 代码味道.
单例模式违反了 单一责任原则: 依据的事实就是 单例模式自己控制自身的创建和生命周期.
单例模式天生就导致代码紧 耦合。这使得在许多情况下用伪造的数据 难于测试。
单例模式的状态会留存于应用的整个生命周期。 这会对测试产生第二次打击,你只能让被严令需要测试的代码运行不了收场,根本不能进行单元测试。为何?因为每一个单元测试应该彼此独立。
还有些来自 Misko Hevery 的深入思考,关于单例模式的问题根源。

不好的示范:

class DBConnection
{
 private static $instance;

 private function __construct(string $dsn)
 {
  // ...
 }

 public static function getInstance(): DBConnection
 {
  if (self::$instance === null) {
   self::$instance = new self();
  }

  return self::$instance;
 }

 // ...
}

$singleton = DBConnection::getInstance();

好的示范:

class DBConnection
{
 public function __construct(string $dsn)
 {
  // ...
 }

  // ...
}


      

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/4018.html