Order Parameters
Almost always, a method’s parameters possess a natural ordering. It’s a good idea to follow that order.
As is so often the case, this concept is best explained with a few code examples:
Example 1
Please take a look at the function signature BuildUrl()
:
Url BuildUrl(string path, string scheme, string query, string host)
Hmm, that’s not all that illuminating. Maybe a call to BuildUrl()
helps:
var url = BuildUrl("/customers/CUST-1234", "https", "?detailed=true&contacts=true", "test.example.com");
Isn’t that confusing? The arguments don’t read right—they are out of the expected order.
Better:
var url = BuildUrl("https", "test.example.com", "/customers/CUST-1234", "?detailed=true&contacts=true");
And here is the function signature to match:
Url BuildUrl(string scheme, string host, string path, string query)
That reads much more along the lines we are used to with URLs.
Example 2
What about this parameterised constructor for class Customer
?
What’s wrong here?
public Customer(string streetAddress, string firstName, int age, string townOrCity, int loyaltyPoints, string lastName, Country country, int loyaltyScore)
The parameters may not follow a natural order as they did with BuildUrl()
; however, there still exist obvious parameter groupings that have been ignored for this constructor:
Address parameters:
streetAddress
townOrCity
country
Personal parameters:
firstName
lastName
age
Loyalty parameters:
loyaltyPoints
loyaltyScore
Furthermore:
- There exist inter-grouping orders. For example,
firstName
should come beforelastName
for the personal parameter sub-grouping.age
, being less important than name should probably come last, and - Usually we can also establish an order among the sub-groupings: Personal parameters describe the most important aspects of a customer and should be listed first. After that, it probably ought to be the Address details and, lastly, the Loyalty parameters.
So, a better constructor signature would have been
public Customer(string firstName, string lastName, int age, string streetAddress, string townOrCity, Country country, int loyaltyPoints, int loyaltyScore)
That’s better but by no means perfect. Next time we’ll look at how we can improve this long parameter list further.
Example 3
Sometimes a parameter order is not so clear. Even then, we may perceive an implicit difference in the relative importance between parameters.
Say, we have a method Pay()
to pay for a shopping cart using a payment gateway. We have decided to pass instances of classes PaymentGateway
and ShoppingCart
as parameters to Pay()
.
Which of these method signatures should we choose?
public void Pay(PaymentGateway gateway, ShoppingCart cart)
public void Pay(ShoppingCart cart, PaymentGateway gateway)
I feel that option 2 is better for these reasons:
- The
ShoppingCart
is essential to the process—it holds the critical data, how much to pay and what we are paying for. - On the other hand, the
PaymentGateway
is required only as part of the payment process—it’s a mechanism. Once we have paid for theShoppingCart
thePaymentGateway
will no longer be needed.
In conclusion, ordering parameters well makes code easier to understand.
Leave a Reply
Want to join the discussion?Feel free to contribute!