zoukankan      html  css  js  c++  java
  • PHP多参数方法的重构

    假设我们要完成一个保存文章的功能,如果采用函数编程的方式,大概会是下面这个样子:

    1 <?php
    2 function saveArticle($title, $content, $categoryId)
    3 {
    4     // ...
    5 }
    6 ?>

    每个参数代表一个属性,但带来一个问题,参数列表会变得很长。此时采用对象编程的技术会是个好方法:

     1 <?php
     2 class Article
     3 {
     4     var $title;
     5     var $content;
     6     var $categoryId;
     7     function save()
     8     {
     9         // ...
    10     }
    11 }
    12 ?>

    在这里,原来的方法参数都转换为以对象的属性方式存在,从而大大降低了方法的参数数量。多数时候这个方法是不错的,不过并不是所有的参数都适合以对象属性的方式存在,区分的原则是,看这些参数是属于对象的内在属性还是外在特征,如果不加区分的统统转换为对象属性,这会让对象本身失去意义。

    举个例子,比如说我们的Article对象还有一个名为find的方法,使用它时可能会涉及limit, offset, order等参数:

     1 <?php
     2 class Article
     3 {
     4     var $title;
     5     var $content;
     6     var $categoryId;
     7     var $limit = 10;
     8     var $offset = 0;
     9     var $order = 'created DESC';
    10 
    11     function save()
    12     {
    13         // ...
    14     }
    15 
    16     function find($categoryId)
    17     {
    18         // ...
    19     }
    20 }
    21 ?>

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

     1 <?php
     2 class Article
     3 {
     4     var $title;
     5     var $content;
     6     var $categoryId;
     7 
     8     function save()
     9     {
    10         // ...
    11     }
    12 
    13     function find($categoryId, $limit = 10, $offset = 0, $order = 'created DESC')
    14     {
    15         // ...
    16     }
    17 }
    18 ?>
    19 
    20 可惜如此一来又出现了文章开头所说的问题,find方法的参数太多了,缺乏可读性,所以还得重构:
    21 
    22 <?php
    23 class Article
    24 {
    25     var $title;
    26     var $content;
    27     var $categoryId;
    28 
    29     function save()
    30     {
    31         // ...
    32     }
    33 
    34     function find($categoryId, $options = array())
    35     {
    36         $default = array(
    37             'limit' => 10,
    38             'offset' => 0,
    39             'order' => 'created DESC'
    40         );
    41 
    42         $options = array_merge($default, (array)$options);
    43          // ...
    44     }
    45 }
    46 ?>

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

    1 $article->find(123, array('limit' => 20));

    简单的说,就是用数组方式的参数,来模拟一种类似关键字参数的效果,采用这种方式的话,可以通过数组的键名来描述参数的作用,从而增加代码的可读性。

    类似这样的重构方法在CakePHP等项目里被大量使用,仔细体会,以后再写代码的时候就可以本能的写出高可读性的代码来。

    补充:相对array_merge来说,使用$options += $default;也是不错的选择。另外,如果options的逻辑很复杂的话,也可以不用数组的方式,转而使用一个专门的对象来封装逻辑操作。

    链接:https://mp.weixin.qq.com/s/w-2kxfY0eliY3Acg6jlrsQ

  • 相关阅读:
    SharePoint 2010 访问WebService 增删改列表
    TFS 项目删除
    一个或多个域类型未正确安装。请转到列表设置页删除这些域。
    IIS 应用程序池 已停用
    hadoop进程全部启动成功, LiveNode也正常,但界面显示 DataNode不一致
    Jenkins 打包发布java应用程序
    centos安装JDK与Tomcat
    JAVA XStream的使用
    MongoDB副本集的实现与维护实战
    基于.NET平台常用的框架整理(转)
  • 原文地址:https://www.cnblogs.com/clubs/p/11557623.html
Copyright © 2011-2022 走看看