Java方法参数过多

Java方法参数过多

96 
西门狂野 
2016.04.15 16:08*  字数 764  阅读 1003 评论 1
重构--Java方法参数过多
  • 示例方法
public void getNews(Context context,
                        Callback callback,
                        String uuid,
                        String uid,
                        String from,
                        String token,
                        String uid,
                        String .....){
                        //逻辑
}
  • 示例构造函数
public class Person {
    public String lastName;
    public String firstName;
    public String middleName;
    public String salutation;
    public String suffix;
    public String streetAddress;
    public String city;
    public String state;
    public boolean isFemale;
    public boolean isEmployed;
    public boolean isHomeOwner;
    public Person(String lastName, String firstName, String middleName, String salutation,
                  String suffix, String streetAddress, String city, String state,
                  boolean isFemale, boolean isEmployed, boolean isHomeOwner) {
        this.lastName = lastName;
        this.firstName = firstName;
        this.middleName = middleName;
        this.salutation = salutation;
        this.suffix = suffix;
        this.streetAddress = streetAddress;
        this.city = city;
        this.state = state;
        this.isFemale = isFemale;
        this.isEmployed = isEmployed;
        this.isHomeOwner = isHomeOwner;
    }
}
  • 问题:
    • 添加大量参数理解难度

    • 易参数位置不正确且运行正常

    • 不易维护

    • 那一个方法或者构造方法多少个参数才好了--没有答案

      函数参数的理想个数是零,其次是一,紧随其后的是二,应该尽可能避免三个参数的情况。参数如果多于三个则需要特殊的理由,而且无论如何都不应该再使用。
      
      • Steve McConnell在Code Complete中写到:开发者应该限制参数在七个以内
解决方法
  • 引入参数对象

    • 参数关系紧密合并到一个对象中

      • Person.class

    public class Person {
    public FullName fullName;
    public Address address;
    public boolean isFemale;
    public boolean isEmployed;
    public boolean isHomeOwner;
    public Person(FullName fullName, Address address, boolean isFemale, boolean isEmployed, boolean isHomeOwner) {
    this.fullName = fullName;
    this.address = address;
    this.isFemale = isFemale;
    this.isEmployed = isEmployed;
    this.isHomeOwner = isHomeOwner;
    }
    }
    ````

      - FullName.class
      
      ````
    

    public class FullName {
    public String lastName;
    public String firstName;
    public String middleName;
    public String salutation;
    public String suffix;
    public FullName(String lastName, String firstName, String middleName, String salutation, String suffix) {
    this.lastName = lastName;
    this.firstName = firstName;
    this.middleName = middleName;
    this.salutation = salutation;
    this.suffix = suffix;
    }
    }
    ````

      - Address.class
      
      ````
    

    public class Address {
    public String streetAddress;
    public String city;
    public String state;
    public Address(String streetAddress, String city, String state) {
    this.streetAddress = streetAddress;
    this.city = city;
    this.state = state;
    }
    }

      ````
      - 问题:参数对象可能被滥用。如果一个开发者纯粹为了减少参数数量,把联系不紧的几个参数强捆在一个类中这肯定是行不通的,在可读性上甚至适得其反。
    
  • Builder模式:

    • 需求:当一个对象需要不同的参数构造方法?不能写5*5满足所有的需求吧
    • 适用范围:构建对象时,如果碰到类有很多参数——其中很多参数类型相同而且很多参数可以为空时,使用Builder模式来完成。当参数数量不多、类型不同而且都是必须出现时,通过增加代码实现Builder往往无法体现它的优势。在这种情况下,理想的方法是调用传统的构造函数。再者,如果不需要保持不变,那么就使用无参构造函数调用相应的set方法吧。
    • 代码
      • Person.class

public class Person {
public FullName fullName;
public Address address;
public boolean isFemale;
public boolean isEmployed;
public boolean isHomeOwner;

public Person(FullName fullName, Address address, boolean isFemale, boolean isEmployed, boolean isHomeOwner) {
    this.fullName = fullName;
    this.address = address;
    this.isFemale = isFemale;
    this.isEmployed = isEmployed;
    this.isHomeOwner = isHomeOwner;
}

public static class Builder {
    private FullName fullName;
    private Address address;
    private boolean isFemale;
    private boolean isEmployed;
    private boolean isHomeOwner;

    /**
     * 如果有必填参数这里可以构造必填构造方法
     */
    public Builder() {
    }

    public Builder setFullName(FullName fullName) {
        this.fullName = fullName;
        return this;
    }

    public Builder setAddress(Address address) {
        this.address = address;
        return this;
    }

    public Builder setFemale(boolean female) {
        isFemale = female;
        return this;
    }

    public Builder setEmployed(boolean employed) {
        isEmployed = employed;
        return this;
    }

    public Builder setHomeOwner(boolean homeOwner) {
        isHomeOwner = homeOwner;
        return this;
    }

    public Person create() {
        return new Person(fullName, address, isFemale, isEmployed, isHomeOwner);
    }
}

}

````

- FullName.class

````

public class FullName {
public String lastName;
public String firstName;
public String middleName;
public String salutation;
public String suffix;

public FullName(String lastName, String firstName, String middleName, String salutation, String suffix) {
    this.lastName = lastName;
    this.firstName = firstName;
    this.middleName = middleName;
    this.salutation = salutation;
    this.suffix = suffix;
}

public static class Builder {
    private String lastName;
    private String firstName;
    private String middleName;
    private String salutation;
    private String suffix;

    public Builder() {
    }

    public Builder setLastName(String lastName) {
        this.lastName = lastName;
        return this;
    }

    public Builder setFirstName(String firstName) {
        this.firstName = firstName;
        return this;
    }

    public Builder setMiddleName(String middleName) {
        this.middleName = middleName;
        return this;
    }

    public Builder setSalutation(String salutation) {
        this.salutation = salutation;
        return this;
    }

    public Builder setSuffix(String suffix) {
        this.suffix = suffix;
        return this;
    }

    public FullName create() {
        return new FullName(lastName, firstName, middleName, salutation, suffix);
    }
}

}

````
 
 - Address.class
 
 ````

public class Address {
public String streetAddress;
public String city;
public String state;
public Address(String streetAddress, String city, String state) {
this.streetAddress = streetAddress;
this.city = city;
this.state = state;
}
public static class Builder {
private String streetAddress;
private String city;
private String state;

    public Builder() {
    }

    public Builder setStreetAddress(String streetAddress) {
        this.streetAddress = streetAddress;
        return this;
    }

    public Builder setCity(String city) {
        this.city = city;
        return this;
    }

    public Builder setState(String state) {
        this.state = state;
        return this;
    }

    public Address create() {
        return new Address(streetAddress, city, state);
    }
}

}

 ````
 调用的地方
 
 ````
 public static void main(String[] args) {
    FullName fullName = new FullName.Builder().setFirstName("yes")
            .setLastName("no").create();
    Address address = new Address.Builder().setCity("china").setState("12")
            .create();
    Person person = new Person.Builder().setAddress(address)
            .setFullName(fullName).create();
}
 ````
 - 优点:客户端代码的可用性和可读性得到了大大提高,构造函数的参数数量明显减少调用起来非常直观。单个builder构建多个对象时Builder参数可在创建期间进行调整,还可以根据对象不同而进行改变,有效的避免重载构造函数。
 - 缺点:增加代码量,代码变得更加冗长(相比较参数数量的增加,相同类型的参数混在一起,可选参数的增加而言,改善代码可读性更有价值)
  • 重载

    • 适用范围:方法中参数可选参数或者参数中指定参数相同
    • 代码
    public String name(String name,int year) {
        return name+year;
    }
    /**
     * 重载
     * @param name
     * @return
     */
    public String name(String name) {
        return name+"null";
    }
    
    • 优点:遇到可选参数或者默认参数时,使用方法重载会十分有效。
  • 参考资料

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值