8. 不要使用单例模式
(译者注:这一条有些难理解,看不懂就略过吧)
单例模式是一种反模式,Brian Button 的解释:
- 单例通常被用做一个全局的实例,为什么不好?因为你在代码中隐藏了依赖,而不是通过接口暴露他们。通过将一些东西放到全局来避免传递他们是一种“代码异味(code smell)”
code smell 是指能够被开发者察觉到的不好的形式
- 它违反了 SPR原则(single responsibility principle): 由它自己控制自己的创建和生命周期
- 它本身就导致了代码的紧耦合。大多数情况下这使得通过伪造数据来测试变的相当困难。
不好的
class DBConnection
{
private static $instance;
private function __construct($dsn)
{
// ...
}
public static function getInstance()
{
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
// ...
}
$singleton = DBConnection::getInstance();
好的:
class DBConnection
{
public function __construct(array $dsn)
{
// ...
}
// ...
}
创建 DBConneciton
的实例,并配置 DSN
这样你就可以在你的应用程序中使用 DBConnection
的实例了。
9 封装条件判断
不好的:
if ($article->state === 'published') {
// ...
}
好的:
if ($article->isPublished()) {
// ...
}
避免否定类型的判断
不好的:
function isDOMNodeNotPresent($node)
{
// ...
}
if (!isDOMNodeNotPresent($node))
{
// ...
}
好的
function isDOMNodePresent($node)
{
// ...
}
if (isDOMNodePresent($node)) {
// ...
}
10. 避免条件判断
这似乎是一个不可能完成的任务。人们会问“如果不用 if
语句我该怎么做?”,答案是在许多情况下,你可以用多态来实现同样的效果。你可能还会问“这样有什么好处?”,答案是我们之前提到的原则:“一个函数应该只做一件事”, 当你的类或函数中有了 if
语句,相当于告诉别人你的函数做了一件以上的事情。
不好的:
class Airplane
{
// ...
public function getCruisingAltitude()
{
switch ($this->type) {
case '777':
return $this->getMaxAltitude() - $this->getPassengerCount();
case 'Air Force One':
return $this->getMaxAltitude();
case 'Cessna':
return $this->getMaxAltitude() - $this->getFuelExpenditure();
}
}
}
好的:
interface Airplane
{
// ...
public function getCruisingAltitude();
}
class Boeing777 implements Airplane
{
// ...
public function getCruisingAltitude()
{
return $this->getMaxAltitude() - $this->getPassengerCount();
}
}
class AirForceOne implements Airplane
{
// ...
public function getCruisingAltitude()
{
return $this->getMaxAltitude();
}
}
class Cessna implements Airplane
{
// ...
public function getCruisingAltitude()
{
return $this->getMaxAltitude() - $this->getFuelExpenditure();
}
}
11. 避免类型检查(第一部分)
PHP是弱类型语言,意味着你的函数可以接收任何类型的参数。有时你会因为这点自由而受害,这时你可能会在函数中检查参数类型,有许多途径可以避免在函数能做类型检查,首先要做的是有一致的接口。
不好的
function travelToTexas($vehicle)
{
if ($vehicle instanceof Bicycle) {
$vehicle->peddleTo(new Location('texas'));
} elseif ($vehicle instanceof Car) {
$vehicle->driveTo(new Location('texas'));
}
}
好的:
function travelToTexas(Traveler $vehicle)
{
$vehicle->travelTo(new Location('texas'));
}
避免类型检查(第二部分)
如果现在要处理的是基础数据类型,像字符串,整型和数组。现在如果你用的 PHP7以上的版本,而且现在很明显你也不能用多态。现在你应该考虑使用类型检查或者严格模式,它使你能够在php语法层面提供静态类型检查。手动判断类型的问题是,你需要添加许多额外的代码,你获得的人造的“类型安全”抵不过你代码可读性的损失。
不好的
function combine($val1, $val2)
{
if (!is_numeric($val1) || !is_numeric($val2)) {
throw new \Exception('Must be of type Number');
}
return $val1 + $val2;
}
好的
function combine(int $val1, int $val2)
{
return $val1 + $val2;
}
12.移除废弃的代码
废弃的代码跟重复的代码一样不好,没有理由在你的代码库继续保留他们,如果你想找回他们,到版本历史中找回就行了。
不好的
function oldRequestModule($url)
{
// ...
}
function newRequestModule($url)
{
// ...
}
$request = newRequestModule($requestUrl);
inventoryTracker('apples', $request, 'www.inventory-awesome.io');
好的
function requestModule($url)
{
// ...
}
$request = requestModule($requestUrl);
inventoryTracker('apples', $request, 'www.inventory-awesome.io');
转载请注明:大后端 » PHP 代码简洁之道——函数部分(二)