Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to refactor method of class with a lot of arguments?

Tags:

c#

refactoring

everyone I have a problem with the legacy code in ASP.NET MVC Application, in this code there is a class Service in business logic layer. This class has method with 20 arguments this method creates an instance of object using this 20 arguments. How to refactor this code, because this is a problem when the created objects is changed and it is need to change the arguments in method. This service class is used in the controller class and in unit test. Help me with refactor this code Thanks in advance.

EDIT Additional information:

I can show the signature of the method

public Qualification CreateQualification(string achievableCode, string achievableTitle,
        string accreditationRef, bool brandingPrefix, long brand, float guidedLearningHours, 
        int creditValue, long level, long type, long gradingType, long area, int subArea,
        DateTime accreditationStartDate, DateTime accreditationEndDate,
        DateTime lastCertDate, string nameOnCert, 
        long organisationId)

I think it is need to apply Kely and Chevex aproach for example I can extract some classes

one will be from parameters:

 long area, int subArea

other

bool brandingPrefix, long brand,

And after extract sub classes I can use Introduce Parameter Object I correct understood?

like image 277
Serghei Avatar asked Mar 03 '11 21:03

Serghei


People also ask

How do you refactor a method with many parameters?

Refactoring steps To refactor the multiple arguments to a parameter object, follow these steps. Create a new class that will represent the parameters. Add this new class as a parameter to the existing method parameter list. You can start by passing null to all existing calls of the method.

How do you avoid too many arguments?

There are two techniques that can be used to reduce a functions' arguments. One of them is to refactor the function, making it smaller, consequently, reducing the arguments' number. The Extract Method technique can be use to achieve this goal.

How many arguments should a method have?

The ideal number of arguments for a function is zero (niladic). Next comes one (monadic), followed closely by two (dyadic). Three arguments (triadic) should be avoided where possible. More than three (polyadic) requires very special justification - and then shouldn't be used anyway.


2 Answers

Create an object to hold those 20 arguments and pass that object to the method.

For example:

public void MyMethod(MyArguments args)
{
    // do stuff
}

EDIT

While this pattern may be useful for a one-time refactor, if you find yourself using the same arguments in multiple methods, consider Chevex's answer. It's the better approach.

like image 186
Kyle Trauberman Avatar answered Oct 08 '22 16:10

Kyle Trauberman


You might try to identify related data in the arguments and factor them into their own custom objects. For example, pretend you have this object:

public class Person
{
    public Person(string firstName, string lastName, int age,
        string streetAddress, string city, string state, int zipCode)
    {
        this.FirstName = firstName;
        this.LastName = lastName;
        this.Age = age;
        this.StreetAddress = streetAddress;
        this.City = city;
        this.State = state;
        this.ZipCode = zipCode;
    }

    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }
    public string StreetAddress { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public int ZipCode { get; set; }
}

Try refactoring this to be two classes, extracting the related address info into its own class and then adding that object as a property of the original object:

public class Person
{
    public Person(string firstName, string lastName, int age, Address address)
    {
        this.FirstName = firstName;
        this.LastName = lastName;
        this.Age = age;
        this.Address = address;
    }

    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }
    public Address Address { get; set; }
}

public class Address
{
    public Address(string streetAddress, string city, string state, int zipCode)
    {
         this.StreetAddress = streetAddress;
         this.City = city;
         this.State = state;
         this.ZipCode = zipCode;
    }

    public string StreetAddress { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public int ZipCode { get; set; }
}

Without more information I'd say this is your best approach.

like image 36
Chev Avatar answered Oct 08 '22 14:10

Chev