在 PhpStorm 中,我们可以通过自带的重构功能(Refactor)非常方便地对代码进行重构,从而提升代码复用性。
1、重构变量/属性
我们以下面这段代码为例进行演示:
代码语言:javascript复制<?php
$n1 = pow(100, 2); // 10000
$n2 = sqrt(100); // 10
$n3 = decbin(100); // 转化为二进制
$n4 = mt_rand(0, 100); // 生成0-100之间的随机数
比如我们想要将上述代码中的数字 100
重构为通过变量引入,可以选中要重构的代码,通过快捷键 Ctrl T 快速打开代码重构操作界面(也可以通过右键 -> Refactor 弹出,Windows 下对应的快捷键是 Ctrl Alt Shift T):
选择引入变量(序号3对应的操作),并且应用到所有数字 100 出现的地方(只应用到当前位置,选择只替换当前位置选项即可):
这样,引入变量替换内联数字的重构就完成了:
注意到现在 number
外面有个红框,意思是你如果想要将其命名为其他变量名,可以现在进行编辑,这个修改会批量应用到其他位置:
如果你想要切换会之前的内联数字(Inline),可以在代码重构界面选择 Inline 选项切换回去(当然,也可以通过 Option Command N 快捷键跳过这个选择界面直接操作):
同样的操作也可以应用到将内联变量值(即以字面量形式直接引入的变量值,比如上面的数字 100
,或者字符串、布尔类型字面量,比如 "学院君"
、true
等)重构为常量、类属性,操作流程完全一样,这里就不重复展示了。
2、重构函数/方法
除了重构变量、属性、常量外,还可以将某个代码块重构为一个函数/方法来提高复用性。
重构函数
还是以上面的示例代码为例,选中整段代码,通过 Ctrl T 快捷键弹出代码重构菜单:
选择 Extract Method… 选项,即可进入重构方法流程(你也可以通过 Option Command M 快捷键直接进入),但是此时会报错:
这是因为上面的代码都是赋值语句,没有任何表达式,我们修改示例代码如下:
代码语言:javascript复制<?php
$num = 100;
$n1 = pow($num, 2); // 10000
$n2 = sqrt($num); // 10
$n3 = decbin($num); // 转化为二进制
$n4 = mt_rand(0, $num); // 生成0-100之间的随机数
printf("pow(%d, 2) = %dnsqrt(%d)=%dndecbin(%d)=%dnmt_rand(0, %d)=%dn",
$num, $n1, $num, $n2, $num, $n3, $num, $n4);
这一次,通过快捷键 Option Command M 即可直接进入方法重构导航界面,不要选中第一行代码,这样,系统会将 $num
变量作为参数传入,我们设置函数名为 math_func_test
:
点击「Refactor」按钮,就可以看到重构后的代码了:
是不是很方便?这样一来,我们就可以传入不同的数字多次调用这个函数了,而不必反复编写重复的代码。
重构类方法
同理,我们也可以在类中通过这种机制来重构类成员方法。
以下面这段示例代码为例:
代码语言:javascript复制class LynkCo01 extends Car
{
public function __construct()
{
$this->brand = '领克01';
parent::__construct($this->brand);
}
public function drive()
{
echo "启动{$this->brand}汽车" . PHP_EOL;
}
}
我们可以为 brand
属性重构出 Getters/Setters 方法(当然,你可以通过 Generate 功能快速生成,不过这里我们以代码重构的形式进行演示)。
首先通过重构变量的方式将内联变量 '领克01'
重构为 $brand
变量:
public function __construct()
{
$brand = '领克01';
$this->brand = $brand;
parent::__construct($this->brand);
}
然后选中要重构的代码进行方法重构操作,重构类成员方法的界面和重构函数的界面略有不同,这里多了方法可见性设置:
同理,你可以对 drive
方法中获取 brand
属性的操作进行重构:
最后,呈现的重构后代码如下所示:
代码语言:javascript复制class LynkCo01 extends Car
{
public function __construct()
{
$this->setBrand('领克01');
parent::__construct($this->brand);
}
public function drive()
{
echo "启动{$this->getBrand()}汽车" . PHP_EOL;
}
/**
* @param string $brand
*/
public function setBrand(string $brand): void
{
$this->brand = $brand;
}
/**
* @return mixed
*/
public function getBrand()
{
return $this->brand;
}
}
在父子类之间转移方法
你可以通过代码重构菜单中的「Pull Members Up…」选项将子类方法上移到父类中:
选择要上移的方法:
点击「Refactor」按钮,就可以将子类方法上移到父类中:
代码语言:javascript复制abstract class Car
{
protected $brand;
/**
* Car constructor.
* @param $brand
*/
public function __construct($brand)
{
$this->setBrand($brand);
}
abstract public function drive();
/**
* @param string $brand
*/
public function setBrand(string $brand): void
{
$this->brand = $brand;
}
/**
* @return mixed
*/
public function getBrand()
{
return $this->brand;
}
}
该重构支持逆操作,你还可以将指定方法从父类下沉到子类中去:
3、重构接口
除此之外,我们还可以将一组实现类似功能的类方法抽象出来构建一个接口,比如汽车、轮船、飞机、摩托车都属于交通工具,交通工具有一些共性,比如可以驾驶、具备品牌属性。
我们以上面的抽象类 Car
为例,将其中 drive
、setBrand
、getBrand
方法抽象出来构建一个 Transportation
接口,要完成这个重构,需要选中对应的类名,通过 Ctrl T 弹出重构菜单,选择「Extract Interface…」:
然后在弹出窗口中编写接口名,选择要声明的接口方法:
点击「Refactor」按钮即可创建对应的接口文件,并且在接口文件中生成对应的接口代码:
这个时候,回到定义抽象类 Car
的地方,可以看到它已经声明为实现 Transportation
接口:
abstract class Car implements Transportation
4、其他重构操作
最后,如果你想要将某个类移动/复制到其他地方,或者对其进行重命名、删除,可以通过重构菜单里面的下面几个选项完成:
这些操作都有对应的快捷键(右侧),重命名和删除都是日常经常用到的操作,对于移动操作,如果移动到的目录命名空间与当前不一致的话,记得进行调整:
以上就是 PhpStorm 中常用的代码重构功能,合理的代码重构,可以提升代码复用性,而 PhpStorm 为代码重构提供的快捷操作,可以提升我们日常进行代码重构的效率。
(全文完)