Laravel 代码简洁之道(12-22)
12、避免使用助手类
有时候人们会使用类来归类助手函数,可要小心了,这可能会让代码变得更混乱。常见的做法是定义一个只包含一个作为助手函数使用的静态方法的类。更好的做法是将这些方法放入具有具体逻辑的类中,或者是只将它们当做是全局函数。
// 坏的class Helper{ public function convertCurrency(Money $money, string $currency): self { $currencyConfig = config("shop.currencies.$currency"); $decimalDiff = ... return new static( (int) round($money->baseValue() * $currencyConfig[value] * 10**$decimalDiff, 0), $currency ); }}// 使用use AppHelper;Helper::convertCurrency($total, 'EUR');
// 好的class Money{ // 其他的 money/currency 逻辑 public function convertTo(string $currency): self { $currencyConfig = config("shop.currencies.$currency"); $decimalDiff = ... return new static( (int) round($this->baseValue() * $currencyConfig[value * 10**$decimalDiff, 0), $currency ); }}// 使用$EURtotal = $total->convertTo('EUR');
13、拿出一个周末来学习 OO
了解静态(static)/ 实例(instance)方法和变量,还有私有的(private)/ 保护的(protected)/ 公共的(public)之间的可见性的区别。还要了解 Laravel 如何使用魔法方法。当你是初学者的时候可能不会很常用,但是随着你的编码水平增长,这些是至关重要的。
14、不要在类中只写过程代码
这将前面的推文与此处的其他提示联系起来。OOP 的存在就是为了让你的代码更加具有可读性,请使用 OOP。不要再在控制器中写好几百行的过程代码了。
15、阅读 SRP 之类的内容,并进行合理的扩展
避免使用那种处理很多和当前类不相关逻辑的类,但是也不要为每件事都创建一个类。你是为了写干净的代码,而不是想在每件事上都做分离。
16、避免函数中参数过多
当您看到具有大量参数的函数时,它可能意味着:
- 该函数包含太多职责,应该分离。
- 职责没问题,但你应该学会重构他的长签名.
以下是修复第二种情况的两种策略.
17、使用数据传输对象 (DTO)
与其以特定顺序传递大量参数,不如考虑创建一个具有属性的对象来存储这些数据。 如果您发现某些行为可以移入此对象,则可以加分。
// 糟糕的示例public function log($url, $route_name, $route_data, $campaign_code, $traffic_source, $referer, $user_id, $visitor_id, $ip, $timestamp){ // ...}
// 推荐的示例public function log(Visit $visit){ // ...}class Visit{ public string $url; public string $routeName; public array $routeData; public string $campaign; public array $trafficSource[]; public string $referer; public string $userId; public string $visitorId; public string $ip; public Carbon $timestamp; // ...}
18、创建流式对象
你可以使用流式 API 来创建对象。使用单独的方法调用来逐渐添加数据,并且只要构造函数中的绝对最小值。正是因为每个方法都返回 $this ,你可以在任意一次调用后让整个流程停下来。
Visit::make($url, $routeName, $routeData) ->withCampaign($campaign) ->withTrafficSource($trafficSource) ->withReferer($referer) // ... 等等
19、使用自定义集合
创建自定义集合可以更好地写出更富有表现力的语法。参考这个订单合计的示例:
// 坏的$total = $order->products->sum(function (OrderProduct $product) { return $product->price * $product->quantity * (1 $product->vat_rate);});
// 好的$order->products->total();class OrderProductCollection extends Collection{ public function total() { $this->sum(function (OrderProduct $product) { return $product->price * $product->quantity * (1 $product->vat_rate); }); }}
20、不要使用缩写
不要觉得很长的变量名 / 方法名就是不对的,才不是这样,它们很有表现力。使用一个长的方法名比短的更好,配合查阅文档能更完整地了解它的功能。变量也是如此。不要使用无意义的几个字母的缩写。
// 坏的$ord = Order::create($data);// ...$ord->notify();
// 好的$order = Order::create($data);// ...$order->sendCreatedNotification();
21、尝试在控制器中只使用 CURD 动作
如果可以的话,只使用控制器中的 7 个 CURD 动作,通常来说会更少。不要在控制器中创建 20 多个方法,更短的控制器更好一些。
22、使用更具有表现力的方法名称
考虑「这个对象可以完成什么事情」,而不是「这个对象能做什么」。也会有例外,比如操作类。这是个很好的经验。
// 坏的$gardener->water($plant);$orderManager->lock($order);// 好的$plant->water();$order->lock();