返回顶部
首页 > 资讯 > 后端开发 > PHP编程 >怎么更好地重构PHP代码
  • 491
分享到

怎么更好地重构PHP代码

2023-07-05 12:07:46 491人浏览 独家记忆
摘要

这篇文章主要介绍“怎么更好地重构PHP代码”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么更好地重构php代码”文章能帮助大家解决问题。#1 - 表现力这可能只是一个简单的技巧,但编写富有表现力的

这篇文章主要介绍“怎么更好地重构PHP代码”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么更好地重构php代码”文章能帮助大家解决问题。

#1 - 表现力

这可能只是一个简单的技巧,但编写富有表现力的代码可以大大改进我们的代码。总是让代码自我解释,这样未来的你或其他开发人员都能知道代码中发生了什么。

不过也有开发人员表示,命名是编程中最困难的事情之一。这就是为什么这不像听起来那么容易的原因之一。

示例 #1 - 命名

之前

// ❌ 这个方法是用来做什么的,方法名表达并不清晰// ❌ 是设置状态还是检查状态呢?$status = $user->status('pending');

之后

// ✅ 通过添加 is,使方法名表达的意图更清晰// ✅ 检测用户状态是否与给定状态相等// ✅ 同时新变量名让我们可以推断它是布尔值$isUserPending = $user->isStatus('pending');

示例 #2 - 命名

之前

// ❌ 这个类返回的是什么?类名?类全名?还是类路径?return $factory->getTargetClass();

之后

// ✅ 我们获取的是类路径// ✅ 如果用户想要类名?则找错了方法return $factory->getTargetClassPath();

示例 #3 - 提取

之前

// ❌ 重复的代码 ( "file_get_contents", "base_path" 方法以及文件扩展)// ❌ 此刻,我们不去关心如何获得code examplespublic function setCodeExamples(string $exampleBefore, string $exampleAfter){    $this->exampleBefore = file_get_contents(base_path("$exampleBefore.md"));    $this->exampleAfter = file_get_contents(base_path("$exampleAfter.md"));}

之后

public function setCodeExamples(string $exampleBefore, string $exampleAfter){     // ✅ 代码直接说明了我们的意图:获取code example(不关注如何获取)    $this->exampleBefore = $this->getCodeExample($exampleBefore);    $this->exampleAfter = $this->getCodeExample($exampleAfter);}// ✅ 这个新方法可多次调用private function getCodeExample(string $exampleName): string{    return file_get_contents(base_path("$exampleName.md"));}

示例 #4 - 提取

之前

// ❌ 多重 where 语句,使阅读变得困难// ❌ 意图究竟是什么呢?User::whereNotNull('subscribed')->where('status', 'active');

之后

// ✅ 这个新的scope方法说明了发生了什么事// ✅ 如果我们需要了解更多细节,可以进入这个scope方法内部去了解// ✅ "subscribed" scope 方法可在其他地方使用User::subscribed();

示例 #5 - 提取

这是我之前项目的一个例子。我们用命令行导入用户。 ImportUsersCommand 类中含有一个 handle 方法,用来处理任务。

之前

protected function handle(){    // ❌ 这个方法包含太多代码    $url = $this->option('url') ?: $this->ask('Please provide the URL for the import:');    $importResponse =  $this->Http->get($url);    // ❌ 进度条对用户很有用,不过却让代码显得杂乱    $bar = $this->output->createProgressBar($importResponse->count());    $bar->start();    $this->userRepository->truncate();    collect($importResponse->results)->each(function (array $attributes) use ($bar) {        $this->userRepository->create($attributes);        $bar->advance();    });    // ❌ 很难说清此处发生了哪些行为    $bar->finish();    $this->output->newLine();    $this->info('Thanks. Users have been imported.');    if($this->option('with-backup')) {        $this->storage            ->disk('backups')            ->put(date('Y-m-d').'-import.JSON', $response->body());        $this->info('Backup was stored successfully.');    }}

之后

protected function handle(): void{    // ✅ handle方法是你访问该类首先会查看的方法    // ✅ 现在可以很容易就对这个方法做了些什么有个粗略的了解    $url = $this->option('url') ?: $this->ask('Please provide the URL for the import:');    $importResponse =  $this->http->get($url);    $this->importUsers($importResponse->results);    $this->saveBackupIfAsked($importResponse);}// ✅ 如果需要了解更多细节,可以查看这些专用的方法protected function importUsers($userData): void{    $bar = $this->output->createProgressBar(count($userData));    $bar->start();    $this->userRepository->truncate();    collect($userData)->each(function (array $attributes) use ($bar) {        $this->userRepository->create($attributes);        $bar->advance();    });    $bar->finish();    $this->output->newLine();    $this->info('Thanks. Users have been imported.');}// ✅ 不要害怕使用多行代码// ✅ 这个例子中它让我们核心的 handle 方法更为简洁protected function saveBackupIfAsked(Response $response): void{    if($this->option('with-backup')) {        $this->storage            ->disk('backups')            ->put(date('Y-m-d').'-import.json', $response->body());        $this->info('Backup was stored successfully.');    }}

#2 - 提前返回

提前返回指的是,我们尝试通过将结构分解为特定 case 来避免嵌套的做法。这样,我们得到了更线性的代码,更易于阅读和了解。不要害怕使用多个 return 语句。

示例 #1

之前

public function calculateScore(User $user): int{    if ($user->inactive) {        $score = 0;    } else {        // ❌ 怎么又有一个 "if"?        if ($user->hasBonus) {            $score = $user->score + $this->bonus;        } else {            // ❌ 由于存在多个层级,大费眼神 ?             $score = $user->score;        }    }    return $score;}

之后

public function calculateScore(User $user): int{    // ✅ 边缘用例提前检测    if ($user->inactive) {        return 0;    }    // ✅ 每个用例都有自己的代码块,使得更容易跟进    if ($user->hasBonus) {        return $user->score + $this->bonus;    }    return $user->score;}

示例 #2

之前

public function sendInvoice(Invoice $invoice): void{    if($user->notificationChannel === 'Slack')    {        $this->notifier->slack($invoice);    } else {        // ❌ 即使是简单的ELSE都影响代码的可读性        $this->notifier->email($invoice);    }}

之后

public function sendInvoice(Invoice $invoice): bool{    // ✅ 每个条件都易读    if($user->notificationChannel === 'Slack')    {        return $this->notifier->slack($invoice);    }    // ✅ 不用再考虑ELSE 指向哪里    return $this->notifier->email($invoice);}

Note: 有时你会听到 “防卫语句” 这样的术语,它是通过提前返回实现。

#3 - 重构成集合 Collection

在 PHP 中,我们在很多不同数据中都用到了数组。处理及转换这些数组可用功能非常有限,并且没有提供良好的体验。(array_walk, usort, etc)

要处理这个问题,有一个 Collection 类的概念,可用于帮你处理数组。最为人所知的是 Laravel 中的实现,其中的 collection 类提供了许多有用的特性,用来处理数组。

注意: 以下例子, 我将使用 Laravel 的 collect () 辅助函数,不过在其他框架或库中的使用方式也很相似。

示例 #1

之前

// ❌ 这里我们有一个临时变量 $score = 0;// ❌ 用循环没有问题,不过可读性还是有改善空间foreach($this->playedGames as $game) {    $score += $game->score;}return $score;

之后

// ✅ 集合是带有方法的对象// ✅ sum 方法使之更具表现力return collect($this->playedGames)    ->sum('score');

示例 #2

之前

$users = [    [ 'id' => 801, 'name' => 'Peter', 'score' => 505, 'active' => true],    [ 'id' => 844, 'name' => 'Mary', 'score' => 704, 'active' => true],    [ 'id' => 542, 'name' => 'NORMan', 'score' => 104, 'active' => false],];// 请求结果: 只显示活跃用户,以 score 排序  ["Mary(704)","Peter(505)"]$users = array_filter($users, fn ($user) => $user['active']);// ❌ usort 进行排序处理的又是哪一个对象呢?它是如何实现?usort($users, fn($a, $b) => $a['score'] < $b['score']);// ❌ 所有的转换都是分离的,不过都是users相关的$userHighScoreTitles = array_map(fn($user) => $user['name'] . '(' . $user['score'] . ')', $users);return $userHighScoreTitles;

之后

$users = [    [ 'id' => 801, 'name' => 'Peter', 'score' => 505, 'active' => true],    [ 'id' => 844, 'name' => 'Mary', 'score' => 704, 'active' => true],    [ 'id' => 542, 'name' => 'Norman', 'score' => 104, 'active' => false],];// 请求结果: 只显示活跃用户,以 score 排序  ["Mary(704)","Peter(505)"]// ✅ 只传入一次usersreturn collect($users)    // ✅ 我们通过管道将其传入所有方法  ->filter(fn($user) => $user['active'])  ->sortBy('score')  ->map(fn($user) => "{$user['name']} ({$user['score']})"  ->values()    // ✅ 最后返回数组  ->toArray();

#4 - 一致性

每一行代码都会增加少量的视觉噪音。代码越多,阅读起来就越困难。这就是为什么制定规则很重要。保持类似的东西一致将帮助您识别代码和模式。这将导致更少的噪声和更可读的代码。

示例 #1

之前

class UserController {    // ❌ 确定如何命名变量(驼峰或是蛇形等),不要混用!    public function find($userId)    {    }}// ❌ 选择使用单数或者复数形式命名控制器,并保持一致class InvoicesController {    // ❌ 修改了样式,如花扣号的位置,影响可读性    public function find($user_id) {    }}

之后

class UserController {    // ✅ 所有变量驼峰式命名    public function find($userId)    {    }}// ✅ 控制器命名规则一致(此处都使用单数)class InvoiceController {    // ✅ 花括号的位置(格式)一致,使代码更为可读    public function find($userId)    {    }}

示例 #2

之前

class pdfExporter{    // ❌ "handle" 和 "export" 是类似方法的不同名称    public function handle(Collection $items): void    {        // export items...    }}class CsvExporter{    public function export(Collection $items): void    {        // export items...    }}// ❌ 使用时你会疑惑它们是否处理相似的任务// ❌ 你可能需要再去查看类源码进行确定$pdfExport->handle();$csvExporter->export();

之后

// ✅ 可通过接口提供通用规则保持一致性interface Exporter{    public function export(Collection $items): void;}class PdfExporter implements Exporter{    public function export(Collection $items): void    {        // export items...    }}class CsvExporter implements Exporter{    public function export(Collection $items): void    {        // export items...    }}// ✅ 对类似的任务使用相同的方法名,更具可读性// ✅ 不用再去查看类源码,变可知它们都用在导出数据$pdfExport->export();$csvExporter->export();

重构 ❤️ 测试

我已经提到过重构不会改变代码的功能。这在运行测试时很方便,因为它们也应该在重构之后工作。这就是为什么我只有在有测试的时候才开始重构代码。他们将确保我不会无意中更改代码的行为。所以别忘了写测试,甚至去 TDD。

关于“怎么更好地重构PHP代码”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网PHP编程频道,小编每天都会为大家更新不同的知识点。

--结束END--

本文标题: 怎么更好地重构PHP代码

本文链接: https://lsjlt.com/news/351514.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 怎么更好地重构PHP代码
    这篇文章主要介绍“怎么更好地重构PHP代码”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么更好地重构PHP代码”文章能帮助大家解决问题。#1 - 表现力这可能只是一个简单的技巧,但编写富有表现力的...
    99+
    2023-07-05
  • 教你如何更好地重构PHP代码
    本篇文章给大家带来了关于php的相关知识,其中主要跟大家聊一聊什么是重构?怎么更好的重构PHP代码?感兴趣的朋友下面一起来看一下吧,希望对大家有帮助。重构指的是在不改变原有功能的情况下,修改或者重新编写代码。下面的例子中,我将向你展示如何更...
    99+
    2023-05-14
    php
  • JavaScript中怎么重构代码
    这篇文章给大家介绍JavaScript中怎么重构代码,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。1. 提炼函数在JavaScript开发中,我们大部分时间都在与函数打交道,所以我们希...
    99+
    2024-04-02
  • PHP 代码重构最佳实践
    答案:php 代码重构遵循提高解耦性、可读性、可维护性、减少复杂性的原则。实践:使用命名空间组织代码。用依赖注入容器解耦组件。重构冗余代码。分解大型类。使用现代代码风格。 PHP 代码...
    99+
    2024-05-06
    php 重构 phpstorm laravel
  • Linux下的PHP IDE:如何更好地编写对象代码?
    随着Web应用的不断发展,PHP作为一种强大的服务器端语言,越来越受到程序员们的欢迎。而在Linux系统中,PHP的开发工具也越来越多,其中PHP IDE是最为常用的一种。那么,在Linux下如何更好地编写对象代码呢?本文将为大家介绍一些...
    99+
    2023-07-05
    ide linux 对象
  • Git API如何帮助PHP开发者更好地管理代码?
    Git是一个强大的版本控制系统,它可以帮助PHP开发者更好地管理代码。Git API是一个程序接口,它可以让开发者在自己的应用程序中使用Git功能。在本文中,我们将讨论如何使用Git API来管理PHP代码。 一、Git API简介 Gi...
    99+
    2023-08-14
    开发技术 git api
  • 怎么编写更好的React代码
    这篇文章主要介绍“怎么编写更好的React代码”,在日常操作中,相信很多人在怎么编写更好的React代码问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么编写更好的React...
    99+
    2024-04-02
  • 怎么编写更好的JS代码
    这篇文章主要介绍“怎么编写更好的JS代码”,在日常操作中,相信很多人在怎么编写更好的JS代码问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么编写更好的JS代码”的疑惑有所帮...
    99+
    2024-04-02
  • 怎么重构冗长的Python代码
    1.将for循环转换为list/dictionary/set 表达式我们在时经常遇到的一个情况是,创建一个值的集合。举个例子,我们可以创建一个立方数字列表,通过迭代方式将其填充。大多数语言的标准方法如下:cubes = [] for i i...
    99+
    2023-05-20
    Python
  • PHP代码重构的原则与方法
    php 重构遵循单一职责、开放-封闭、里氏替换等原则,通过提取方法、使用设计模式、借助工具和测试来实现重构。例如,将复杂函数拆分,使用依赖注入提高可测试性,实现代码的扩展性和可维护性。 ...
    99+
    2024-05-09
    php 代码重构 重构代码 lsp
  • 八个重构技巧使得Python代码更Pythonic
    1.合并嵌套的if语句我们从简单的开始。不要像这样嵌套 if 语句,只需将它们合并为一个即可。if a: if b: pass # -> refactor if a and b: pas2.使用 any 而不是循环这里我们要检查列表中是否...
    99+
    2023-05-14
    Python 重构 Pythonic
  • PHP 代码重构:提高代码质量和可维护性
    PHP 代码重构:提升代码质量和可维护性 引言 随着时间的推移,PHP 代码库会变得臃肿、难以维护和理解。代码重构是一个系统化过程,可以改善代码的结构、清晰度和可维护性,从而避免这些问...
    99+
    2024-05-12
    php 代码重构
  • Java和Git:如何更好地管理你的代码?
    在软件开发领域,代码管理是至关重要的一环。随着项目的规模不断扩大,代码量的增加,管理代码变得越来越困难。为了更好地管理代码,我们需要使用工具来帮助我们完成这项任务。在这篇文章中,我们将介绍两个最常用的工具:Java和Git。 Java是一...
    99+
    2023-07-31
    git django javascript
  • Django与Git:如何更好地管理您的代码?
    在现代软件开发中,代码管理非常重要。有时候,您需要追踪代码的更改并回溯到之前的版本。这个过程可以通过版本控制系统来完成。Git是最流行的版本控制系统之一,并且在Django项目中使用它可以更好地管理代码。在本文中,我们将讨论如何使用Git...
    99+
    2023-08-25
    存储 django git
  • 初学者怎么更好自学Python代码
    这篇文章主要讲解了“初学者怎么更好自学Python代码”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“初学者怎么更好自学Python代码”吧!1.列表,字典和集合理解列表理解是许多Python...
    99+
    2023-06-16
  • 怎么更好的进行C++代码编译
    这期内容当中小编将会给大家带来有关怎么更好的进行C++代码编译,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。在刚刚刚开始学C++代码时遇到一个问题,这个问题导致程序不能够完全的进行运行,看完本文后对您一定...
    99+
    2023-06-17
  • Apache和对象编程:如何更好地维护代码?
    Apache是一个世界著名的开源软件基金会,其下的许多项目都是以对象编程为基础的。对象编程是一种程序设计模式,它将数据和方法封装在一个对象中,从而更好地组织和维护代码。本文将介绍如何使用Apache和对象编程来更好地维护代码。 一、Apa...
    99+
    2023-06-01
    apache 编程算法 对象
  • 了解 VSCode 如何帮助你更好地编写代码
    标题:探索VSCode如何助你更优秀编程技巧 在当今的数字化时代,编程已经成为了人们生活和工作中不可或缺的技能。而一款优秀的代码编辑器则是每位开发者必备的利器。在众多的代码编辑器中,V...
    99+
    2024-04-02
  • PHP开发中如何优化代码重构和重用性
    在PHP开发过程中,代码的重构和重用性是非常重要的方面。通过优化代码的结构和设计,可以提高代码的可读性和维护性,同时还能减少代码的冗余,避免重复编写相同的逻辑。本文将介绍几种常用的优化代码重构和重用性的方法,并给出具体的代码示例。函数和类的...
    99+
    2023-10-21
    代码重构(Code Refactoring) PHP开发(PHP development) 代码重用性(Code Reu
  • PHP中如何进行代码重构和优化?
    PHP是一门常用于Web开发的脚本语言,但在开发过程中,程序会变得越来越大、越来越复杂。在这种情况下,程序重构就显得尤为重要和必要,可以提高代码质量、减少代码维护成本、提高开发效率等。本文将介绍如何进行PHP代码重构和优化,帮助开发者提高P...
    99+
    2023-05-14
    代码重构(Code Refactoring) 性能优化(Performance Optimization) 编程技巧(P
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作