Refactoring Day 23 : Introduce Parameter Object

This refactoring comes from Fowler’s refactoring catalog and can be found here

Sometimes when working with a method that needs several parameters it becomes difficult to read the method signature because of five or more parameters being passed to the method like so:

   1: public class Registration

   2: {

   3:     public void Create(decimal amount, Student student, IEnumerable<Course> courses,

   4:         decimal credits)

   5:     {

   6:         // do work

   7:     }

   8: }

In this instances it’s useful to create a class who’s only responsibility is to carry parameters into the method. This helps make the code more flexible because to add more parameters, you need only to add another field to the parameter object. Be careful to only use this refactoring when you find that you have a large number of parameters to pass to the method however as it does add several more classes to your codebase and should be kept to a minimum.

   1: public class RegistrationContext

   2: {

   3:     public decimal Amount { get; set; }

   4:     public Student Student { get; set; }

   5:     public IEnumerable<Course> Courses { get; set; }

   6:     public decimal Credits { get; set; }

   7: }

   8:  

   9: public class Registration

  10: {

  11:     public void Create(RegistrationContext registrationContext)

  12:     {

  13:         // do work

  14:     }

  15: }

This is part of the 31 Days of Refactoring series. For a full list of Refactorings please see the original introductory post.

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Sean Chambers

I am a Senior software developer from Palm Coast, Florida. An advocate of Domain Driven Design, Behavior Driven Development, creator of FluentMigrator and community activist. I am married to my beautiful wife Erin and am the proud father of two wonderful children. I currently reside at ACI, a local insurance industry/mortgage software company that excels in creating solutions using Agile methodologies.
This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Michael Kjörling

    You also need to be very careful with input validation since (especially when adding fields to the parameter object class that is already used in multiple places throughout your codebase) it is very easy to forget one field/parameter out of the bunch. Much more so than if you need to go through the parameter list when calling the method; in that case, if you miss a spot, the compiler will alert you. In some cases it might even be worth creating a method on the RegistrationContext class such as Create() that takes a Registration object and calls Create() on that after verifying that all fields are properly filled in. This is a slight deviation from the separation of responsibility principle but since the RegistrationContext class cannot exist on its own anyway, it seems like it could be an acceptable trade-off. Something like this:

    public class RegistrationContext
    {
    // … parameter fields go here …

    public void Create(Registration registration)
    {
    // … validate all context class fields and fail if appropriate …

    registration.Create(this);
    }
    }

  • http://www.lostechies.com/members/schambers/default.aspx schambers

    Excellent point Michel. This leads into Day 25 where I talk about Design By Contract checks that would be an excellent example of input validation in a scenario like this.

  • ryzam

    I think its time to thing parameter object as a message.Using message it would give you Ubiquitous Language which minimize the gap between domain expert and developer