设为首页 收藏本站
查看: 752|回复: 0

[经验分享] PHP 多参数方法的重构

[复制链接]

尚未签到

发表于 2017-4-3 06:08:07 | 显示全部楼层 |阅读模式
  起:在百度上看到了 老王 的一篇函数重构的文章 很好~ 但是没看懂 DSC0000.gif ,留下自己以后慢慢看.
  ----------------------------------
  作者:老王
  地址:http://hi.baidu.com/thinkinginlamp/blog/item/f4bd08fa41c9f19e58ee902b.html
  假设我们要完成一个保存文章的功能,如果采用函数编程的方式,大概会是下面这个样子:

<?php
function saveArticle($title, $content, $categoryId)
{
// ...
}
?>
  每个参数代表一个属性,但带来一个问题,参数列表会变得很长。此时采用对象编程的技术会是个好方法:

<?php
class Article
{
var $title;
var $content;
var $categoryId;
function save()
{
// ...
}
}
?>

  在这里,原来的方法参数都转换为以对象的属性方式存在,从而大大降低了方法的参数数量。多数时候这个方法是不错的,不过并不是所有的参数都适合以对象的属性方式存在,区分的原则是看这些参数是属于对象的内在属性还是外在特征,如果不加区分的统统转换为对象属性,这会让对象本身失去意义。举个例子,比如说我们的Article对象还有一个名为find的方法,使用它时可能会涉及limit, offset, order等参数:

<?php
class Article
{
var $title;
var $content;
var $categoryId;
var $limit = 10;
var $offset = 0;
var $order = 'created DESC';
function save()
{
// ...
}
function find($categoryId)
{
// ...
}
}
?>

  如上所示,一旦我们把limit,offset,order等参数转换为对象的属性,这个对象本身就变得不伦不类了,因为虽然title,content,categoryId可以算作是对象的内在属性,而limit,offset,order却不是,顶多也只能算作是外部特征,不加区分的结果基本是噩梦的开始,所以,还是老老实实的把外在特征放到方法的参数里好些(更严格的说find方法应该是一个static类型的方法,不过文本就是一个简单的说明,不必细究):

<?php
class Article
{
var $title;
var $content;
var $categoryId;
function save()
{
// ...
}
function find($categoryId, $limit = 10, $offset = 0, $order = 'created DESC')
{
// ...
}
}
?>

  可惜如此一来又出现了文章开头所说的问题,find方法的参数太多了,缺乏可读性,所以还得重构:

<?php
class Article
{
var $title;
var $content;
var $categoryId;
function save()
{
// ...
}
function find($categoryId, $options = array())
{
$default = array(
'limit' => 10,
'offset' => 0,
'order' => 'created DESC'
);
$options = array_merge($default, (array)$options);
// ...
}
}
?>

  看上去还不错,调用时可以使用类似下面的方法:

$article->find(123, array('limit' => 20));
  简单的说,就是用数组方式的参数来模拟一种类似关键字参数的效果,采用这种方式的话,可以通过数组的键名来描述参数的作用,从而增加代码的可读性。类似这样的重构方法在CakePHP等项目里被大量使用,仔细体会,以后再写代码的时候就可以本能的写出高可读性的代码来。
  补充:相对array_merge来说,使用$options += $default;也是不错的选择,另外,如果options的逻辑很复杂的话,也可以不用数组的方式,转而使用一个专门的对象来封装逻辑操作
  -----------------------------------------------
  贴上此函数的说明(出自 PHP5手册):
  array_merge() :

说明
  array array_merge ( array array1, array array2 [, array ...])

  array_merge() 将两个或多个数组的单元合并起来,一个数组中的值附加在前一个数组的后面。返回作为结果的数组。
  如果输入的数组中有相同的字符串键名,则该键名后面的值将覆盖前一个值。然而,如果数组包含数字键名,后面的值将不会覆盖原来的值,而是附加到后面。
  


  例子 1. array_merge() 例子

<?php
$array1
= array ("color" => "red", 2, 4);
$array2 = array ("a", "b", "color" => "green", "shape" => "trapezoid", 4);
$result = array_merge ($array1, $array2);
print_r($result);
?>
  $result 成为:

Array
(
    [color] => green
    [0] => 2
    [1] => 4
    [2] => a
    [3] => b
    [shape] => trapezoid
    [4] => 4
)




运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-359300-1-1.html 上篇帖子: PHP正则表达式学习笔记 下篇帖子: PHP跨数据库事务处理
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表