大话重构 之 你的参数列表像蚯蚓一样让人厌恶吗

checkout("zhangsan", "chengdu",
			"236891001Y", 1, 1.59,
			"279645311R", 2, 2.50,
			"357498670R", 1, 19.90,
			"139776685")

不知道小伙伴们看到上面的函数有何感想?一码是真的有股骂人的冲动。这一二一,一二一的,是在走正步吗?天知道是什么意思。如果你在一个大型商业项目中编写代码,则一定碰到过比这还凌乱的参数列表。。。想骂就骂吧,别憋出内伤。&#*``...

长参数列表的由来

为啥会写出这么长的参数列表呢?

还真是有说法的。在面向过程的语言中,全局变量会使人陷入问题和调试的深渊。为了避免使用全局变量,大伙都谨遵一条法则:需要啥就向函数传啥。

到了面向对象语言中,有人依然没有适应过来,在没人提醒的情况下,然后。。。就没有然后了。

一码今天就来提醒依然有这个问题的小伙伴们。

合理构建对象,隐藏部分数据

在面向对象的语言中,对象即为数据和行为的结合体。对象有了数据,再调用对象方法的时候,需要传的数据就少多了。

前提是构建合理的对象,让它封装一部分数据。

拿篇首的例子来说,checkOut是选好商品后,去买单的意思。买单得有个人吧,消费者出来了。

case class Customer(name: String, address: String)

val customer = Customer("zhangsan", "chengdu")
customer.checkout("236891001Y", 1, 1.59,
			"279645311R", 2, 2.50,
			"357498670R", 1, 19.90,
			"139776685")

消费者一出,参数减少了两个。

该重构手法叫 提取类 ,在 消除过长类 中也有使用。

引入参数对象

继续识别对象。购物嘛,薯片1盒,苹果两斤,打包成对象,多个同类产品构成订单项,多个订单项构成订单。

case class Product(id: String, price: Float)
case class OrderItem(amount: Int, product: Product)
case class Order(id: String, items: List[OrderItem])

val orderItems = List(
	OrderItem(1, Product("236891001Y", 1.59)),
	OrderItem(2, Product("279645311R", 2.50)),
	OrderItem(1, Product("357498670R", 19.90))
)
val order = Order("139776685", orderItems)

customer.checkout(order)

主谓宾,和造句一样,整个代码终于又有画面感了。道法自然,面向对象的代码也讲究自然。一个商业项目的代码会维护较长时间,人要读很多次,所以写代码一定要讲人话。面向对象对可读性的贡献不可谓不大。

这种重构的手法,叫 引入对象参数 。顾名思义,把参数列表中相关度较高的参数打包形成对象,进而减少参数数量。该重构手法在 消除过长方法 一文中也有使用。

除了上面的重构手法,还可以通过下面两种手法减少参数数量。

保持对象完整

如果发现方法的参数里面有多个来自于一个对象,那么就直接传入这个对象。

val begin = dateRange.begin
val end = dateRange.end

withinPlan = plan.withinRange(begin, end)

重载个withinRange方法,支持直接传入完整的DateRange对象。

withinPlan = plan.withinRange(dateRange)

保持对象完整消除过长方法 也有使用。

用方法替代参数

用方法替代参数 有以下两个两个场景:

  1. 方法中某个参数可以通过当前类内部的某个方法直接获得
  2. 方法中某个参数可以通过另外一个对象参数的方法直接获得
val basePrice = quantity * itemPrice
val discountLevel = getDiscountLevel()
val finalPrice = discountPrice(basePrice, discountLevel)

把discountLevel参数去掉,在discountPrice方法内部直接调用getDiscountLevel方法。

val basePrice = quantity * itemPrice
val finalPrice = discountPrice(basePrice)

之前有人反馈说内容有难度,今天的主题应该还好,不长而且比较轻松,希望小伙伴们能有所收获,下一篇见。

推荐

解决万恶之首“重复代码”

消除过长方法

消除巨无霸类

答读者问

你的参数列表像蚯蚓一样让人厌恶吗

职责单一原则真的简单吗

查看《大话重构》系列文章,请进入YoyaProgrammer公众号,点击 核心技术,点击 大话重构。

分类 大话重构

优雅程序员 原创 转载请注明出处

图片二维码

posted @ 2015-06-15 09:29  一码  阅读(3153)  评论(11编辑  收藏  举报