当我看到长长的参数列表时,我的第一个问题是这个函数或对象是否做得太多。考虑:
EverythingInTheWorld earth=new EverythingInTheWorld(firstCustomerId,
lastCustomerId,
orderNumber, productCode, lastFileUpdateDate,
employeeOfTheMonthWinnerForLastMarch,
yearMyHometownWasIncorporated, greatGrandmothersBloodType,
planetName, planetSize, percentWater, ... etc ...);
当然这个例子是故意荒谬的,但我见过很多真实的程序,其中的例子稍微不那么荒谬,其中一个类用于保存许多几乎不相关或不相关的东西,显然只是因为同一个调用程序需要两者或者因为程序员碰巧同时想到了两者。有时,简单的解决方案就是将类分解成多个部分,每个部分各司其职。
稍微复杂一点的是,当一个类确实需要处理多个逻辑事物时,例如客户订单和有关客户的一般信息。在这些情况下,为客户创建一个类和为订单创建一个类,并让它们在必要时相互交谈。所以而不是:
Order order=new Order(customerName, customerAddress, customerCity,
customerState, customerZip,
orderNumber, orderType, orderDate, deliveryDate);
我们可以:
Customer customer=new Customer(customerName, customerAddress,
customerCity, customerState, customerZip);
Order order=new Order(customer, orderNumber, orderType, orderDate, deliveryDate);
虽然我当然更喜欢只带 1 个或 2 个或 3 个参数的函数,但有时我们不得不接受,实际上,这个函数需要一堆,而且它本身的数量并不会真正造成复杂性。例如:
Employee employee=new Employee(employeeId, firstName, lastName,
socialSecurityNumber,
address, city, state, zip);
是的,这是一堆字段,但可能我们要做的只是将它们保存到数据库记录或将它们扔到屏幕上或类似的地方。这里实际上并没有太多的处理。
当我的参数列表变得很长时,我更喜欢可以为字段提供不同的数据类型。就像我看到这样的功能:
void updateCustomer(String type, String status,
int lastOrderNumber, int pastDue, int deliveryCode, int birthYear,
int addressCode,
boolean newCustomer, boolean taxExempt, boolean creditWatch,
boolean foo, boolean bar);
然后我看到它被称为:
updateCustomer("A", "M", 42, 3, 1492, 1969, -7, true, false, false, true, false);
我很担心。看着电话,根本不清楚所有这些神秘的数字、代码和标志的含义。这只是要求错误。程序员可能很容易混淆参数的顺序并意外切换两个,如果它们是相同的数据类型,编译器会接受它。我宁愿有一个所有这些东西都是枚举的签名,所以调用会传入诸如 Type.ACTIVE 而不是“A”和 CreditWatch.NO 而不是“false”等内容。