简体   繁体   中英

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

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?

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.

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.

Use the Builder pattern

QualificationBuilder builder = new QualificationBuilder();
builder.setAchievableCode(achievableCode)
       .setAchievableTitle(achievableTitle)...
Qualification = builder.build();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM