在“干净代码”中,写有“函数的理想参数个数为零”。解释原因并讲得通。我所需要的是重构具有4个或更多参数的方法来解决此问题的技术。
一种方法是将参数提取到新的类中,但是那肯定会导致类的爆炸式增长吗?那些类可能以违反某些命名规则的名称结尾(以“ Data”或“ Info”等结尾)?
另一种技术是使多个函数使用的变量成为私有成员变量,以避免传递它们,但这扩大了变量的范围,可能使它向实际上不需要它的函数开放。
只是寻找使函数参数最小化的方法,就已经接受了这样做的好主意。
在“干净代码”中,写有“函数的理想参数个数为零”。解释原因并讲得通。我所需要的是重构具有4个或更多参数的方法来解决此问题的技术。
一种方法是将参数提取到新的类中,但是那肯定会导致类的爆炸式增长吗?那些类可能以违反某些命名规则的名称结尾(以“ Data”或“ Info”等结尾)?
另一种技术是使多个函数使用的变量成为私有成员变量,以避免传递它们,但这扩大了变量的范围,可能使它向实际上不需要它的函数开放。
只是寻找使函数参数最小化的方法,就已经接受了这样做的好主意。
Answers:
要记住的最重要的事情是,这些是准则,而不是规则。
在某些情况下,方法仅必须带有一个参数。+
例如,考虑一下数字方法。或add
用于收集的方法。
实际上,甚至可能会争辩说,将两个数字相加的含义取决于上下文,例如在ℤ中3 + 3 == 6
,但是在ℤ | 5中 3 + 3 == 2
,因此,加法运算符实际上应该是上下文对象上的方法,该方法采用两个参数而不是a带一个参数的数字的方法。
同样,用于比较两个对象的方法必须是一个对象将另一个作为参数的方法,或者是将两个对象作为参数的上下文的方法,因此,将比较方法与少于一个论点。
也就是说,可以通过以下几项操作来减少方法的参数数量:
Point
对象,而不是两个坐标,或者传递一个对象,而不是传递用户名和电子邮件IdCard
。)一种方法是将参数提取到新的类中,但是那肯定会导致类的爆炸式增长吗?
如果您的域模型包含许多不同种类的对象,那么您的代码将最终包含许多不同种类的对象。没错。
那些类可能以违反某些命名规则的名称结尾(以“ Data”或“ Info”等结尾)?
如果找不到合适的名称,则可能是将太多参数组合在一起或将参数组合得很少。因此,您要么只是一个类的一部分,要么您有多个类。
另一种技术是使多个函数使用的变量成为私有成员变量,以避免传递它们,但这扩大了变量的范围,可能使它向实际上不需要它的函数开放。
如果您有一组方法都使用相同的参数,而另一组方法却不同,则它们可能属于不同的类。
请注意我经常使用“也许”一词吗?这就是为什么这些只是准则,而不是规则。也许您的带有4个参数的方法非常好!
add
对自然数函数和add
对整数环功能模N是在两个不同类型的两种不同的功能操作。我也不明白您所说的“上下文”是什么意思。
请注意,零参数并不表示副作用,因为您的对象是隐式参数。例如,看看Scala的不可变列表有多少种零度方法。
我将一种有用的技术称为“镜头聚焦”技术。聚焦摄像机镜头时,如果将焦点对准太远,则更容易看到其真实对焦点,然后将其向后对准正确的点。软件重构也是如此。
尤其是如果您使用的是分布式版本控制,则可以轻松地尝试软件更改,看看您是否喜欢它们的外观,如果不喜欢它们,则选择退出,但是出于某些原因,人们似乎常常不愿意这样做。
在您当前的问题中,这意味着编写零或一个参数版本,首先要编写几个分离的函数,然后相对容易地看出哪些函数需要组合以提高可读性。
请注意,作者还是测试驱动开发的忠实拥护者,由于您从琐碎的测试用例开始,因此一开始往往会产生低arity函数。
一种简单的方法(天真-甚至我应该盲目地说)只是旨在减少可能错误的函数参数的数量。具有大量参数的函数绝对没有错。如果逻辑需要它们,那么它们也是必需的...只要正确地设置了格式并对其进行了注释以提高可读性,长参数列表根本不会让我担心。
如果参数的全部或子集属于一个唯一的逻辑实体,并且通常在整个程序中成组传递,则将它们分组到某个容器(通常是结构或其他对象)中可能是有意义的。典型示例可能是某种消息或事件数据类型。
您可以轻松地过度使用该方法-一旦发现在此类运输容器之间进行装箱和拆箱所产生的开销超过了其提高可读性的开销,那么您可能已经走得太远了。
OTOH,较大的参数列表可能表明您的程序可能结构不正确-可能需要大量参数的函数只是试图做太多事情,应该分成几个较小的函数。我宁愿从这里开始,也不必担心参数数量。