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

 <?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的逻辑很复杂的话,也可以不用数组的方式,转而使用一个专门的对象来封装逻辑操作。

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

PHP多参数方法的重构的更多相关文章

  1. PHP 多参数方法的重构

    假设我们要完成一个保存文章的功能,如果采用函数编程的方式,大概会是下面这个样子: <?php function saveArticle($title, $content, $categoryId ...

  2. 代码重构与单元测试——使用“以查询取代临时变量”再次对Statement()方法进行重构(七)

    代码重构与单元测试(一) 代码重构与单元测试--测试项目(二) 代码重构与单元测试--"提取方法"重构(三) 代码重构与单元测试--重构1的单元测试(四) 代码重构与单元测试--对 ...

  3. Action接收页面传来的参数方法

    接收页面传来的参数方法 1.第一种:在action中设置相应的变量 在相应的action中设置与将要传进来的参数名相同的变量 eg: 页面传给后台两个参数 name=chance & age ...

  4. C# 中的可变参数方法(VarArgs)

    首先需要明确一点:这里提到的可变参数方法,指的是具有 CallingConventions.VarArgs 调用约定的方法,而不是包含 params 参数的方法.可以通过MethodBase.Call ...

  5. 【功能代码】---4用JS获取地址栏参数方法

    用JS获取地址栏参数方法 // 方法一:采用正则表达式获取地址栏参数:( 强烈推荐,既实用又方便!) function GetQueryString(name) { var reg = new Reg ...

  6. SSM-SpringMVC-11:SpringMVC中ParameterMethodNameResolver参数方法名称解析器

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 或许曾经的我们也见过一种方式http://localhost:8080/项目名/后台servlet?actio ...

  7. Java之hashCode的作用和equals方法的重构规则

    这个是博主对hashcode的初步理解,以后加深了会再来更新: 1.hashcode是什么? hashcode是对象的散列码,不同的对象几乎不一样,说几乎是因为还是可以一样的. 特点:每一个对象都有h ...

  8. RhinoMock中无参数方法和无返回值方法的使用

    无返回值方法,RhinoMock的例子是这么做的: demo.VoidThreeArgs(, "", 0f); LastCall.On(demo).Callback<int, ...

  9. JavaScript&jQuery获取url参数方法

    JavaScript&jQuery获取url参数方法 function getUrlParam(name){ var reg = new RegExp("(^|&)" ...

随机推荐

  1. Spring 2.5配置文件详解(转)

    http://book.51cto.com/art/201004/193743.htm 6.2.3  Spring 2.5配置文件详解 Spring配置文件是用于指导Spring工厂进行Bean生产. ...

  2. js unshift()

    定义与用法 unshift()方法可像数组添加一个或多个元素 并返回新长度 语法 arrayObject.unshift(newElement1,newElement2,......,newEleme ...

  3. 2PC和3PC

    原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11484077.html 2PC 是计算机网络尤其是在数据库领域内,为了使基于分布式系统架构下的所有节点 ...

  4. 【leetcode】901. Online Stock Span

    题目如下: 解题思路:和[leetcode]84. Largest Rectangle in Histogram的核心是一样的,都是要找出当前元素之前第一个大于自己的元素. 代码如下: class S ...

  5. 【leetcode】679. 24 Game

    题目如下: 解题思路:24点是非常经典的游戏了,因为本题数据量小,可以使用穷举法,把所有的可能结果都算出来.假设nums = [a,b,c,d],记f(n)表示用nums中n个数字进行运算可以得到的结 ...

  6. jdbcTemplate查询结果为对象list

    RowMapper<WmsExpensesSettleEntity> rowMapper1=new BeanPropertyRowMapper<WmsExpensesSettleEn ...

  7. c#获取MAC地址和IP地址

    一获取mac地址 1.先添加system.management的dll组件2.添加引用 public string GetMACAddress(){string MoAddress = "& ...

  8. GIT上传下载报错:[You do not have permission to pull from the repository]的解决方案!

    第一步:打开我的电脑 第二步:选择此电脑,右击弹出框点击属性进入控制面板 第三步:进入控制面板 第四步:搜索管理凭据 第五步:编点击右侧按钮,进行编辑用户名和密码的操作添加凭据 git:https:/ ...

  9. python中API接口是什么

    首先还是举个例子:你要去银行取钱的例子.如果没有银行柜员给你服务,你自己去存钱,你需要做的事情有: 一,打开金库的大门 二,把钱放进去 三,记账,存放了多少钱 四,离开. 问题解决了,但是其中有不少问 ...

  10. UML的类型

    分类 UML从考虑系统的不同角度出发,定义了用例图.类图.对象图.包图.状态图.活动图.序列图.协作图.构件图.部署图等10种图. 常见的UML图有用例图(Use Case Diagram).类图(C ...