views:

221

answers:

3

I have never seen a way to do this nicely, i would be interested in seeing how others do it. Currently i format it like this:

public Booking createVehicleBooking(Long officeId, 
                                    Long start, 
                                    Long end,
                                    String origin, 
                                    String destination, 
                                    String purpose,   
                                    String requirements, 
                                    Integer numberOfPassengers) throws ServiceException {
/*..Code..*/
}
+3  A: 
public Booking createVehicleBooking(
    Long officeId, 
    Long start, 
    Long end,
    String origin, 
    String destination, 
    String purpose,                 
    String requirements, 
    Integer numberOfPassengers)

throws ServiceException {
/*..Code..*/
}
John Millikin
If there are multiple exception thrown, do you line each of them vertically also?
Chris Noe
Chris -- depends on how many. If enough that it runs off the side of the screen, yes. General rule is: if it runs off the side, align them. If the function name is too damn long, nest and indent.
John Millikin
that's pretty nice. the only change i'd make is to move the closing parenthesis onto the same line as the "throws", so that you can easily see that it's part of a larger statement.
nickf
+10  A: 

A large set of parameters like this is often (but not always) an indicator that you could be using an object to represent the parameter set. This is especially true if either:

  • There are several methods with similar large parameter sets, that can be replaced with a single method taking a parameter object.

  • The method is called create...

So your above code could become (pardon my C++, I'm a Java developer):

class BuildVehicleBooking {
    Long officeId;
    Long start;
    Long end;
    String origin;
    String destination;
    String purpose;             
    String requirements;
    Integer numberOfPassengers;

    Booking createVehicleBooking () throws ServiceException { ... }
}

This is the Builder Pattern. The advantage of this pattern is that you can build up a complex set of parameters in pieces, including multiple variations on how the parameters relate to each other, and even overwriting parameters as new information becomes available, before finally calling the create method at the end.

Another potential advantage is that you could add a verifyParameters method that checked their consistence before you go as far as creating the final object. This is applicable in cases where creating the object involves non-reversible steps, such as writing to a file or database.

Note that, as with all patterns, this doesn't apply in every case and may not apply in yours. If your code is simple enough then this pattern may be over-engineering it. If the code is getting messy, refactoring into this pattern can be a good way to simplify it.

Marcus Downing
Unfortunately i do not think i can get away with this because this is a SOAP endpoint for a web service, but very informative nonetheless.
Abarax
You can absolutely employ this technique, even for web services. You need to make your class serializable, and potentially deploy schema depending on what you are using to host web services (axis, for example will require that I believe, whereas asp.net will handle it for you)
Jeremy
The builder pattern is useful, good advice!For total world domination (thread safety), make sure that the create-method copies all parameters before validating them.(Also, minor tips: Use long instead of Lon, int instead of Integer and provide getter/setter methods.)
volley
Since entering this answer, I've found myself using the builder pattern more, in some very useful ways. Odd.
Marcus Downing
+1  A: 

I'be inclined to go about it with several objects instead of just one.

So it becomes

public Booking createVehicleBooking(Long officeId, DateRange dates, TripDetails trip)

While DateRange and Trip details contain only the relevant portions of the data. Although arguably the dateRange could be part of the trip while Requirements and Number of Passengers could be remoived from TripDetails and made part of the request.

In fact there are several ways to dice the data but I'd have to say breaking your large list into groups of related parameters and building an object for them will allow a clearer programming style and increase possible reuse.

And remember it is always possible to imbed objects in object thus allowing you to have

public Booking createVehicleBooking(BookingParameters parameters)

While BookingParameters Contains TripDetails and DateRange objects as well as the other parameters.

Brody
This question is about formatting. (Sometimes you do need to work with the code base your given before refactoring ;-)
Chris Noe