有没有一种方法可以使构造函数中的参数为可选?

时间:2020-03-31 03:57:15

标签: java

我正在为练习编写一个简单的库存系统,并且我有一个包含以下值的物料类:

private String name;
private int quantity;
private Integer ID;
private Double pricePerUnit;
private Double totalPrice;

我正在编写此类的构造函数,并且我希望除名称和数量之外的所有内容都是可选的,因为用户可以选择是否为这些字段输入任何数据。目前,我有两个看起来像这样的构造函数:

public Item(String name, int quantity)
{
    this.name=name;
    this.quantity=quantity;
}

public Item(String name, int quantity, Integer ID, Double pricePerUnit, Double totalPrice)
{
    this(name, quantity);
    this.ID=ID;
    this.pricePerUnit=pricePerUnit;
    this.totalPrice=totalPrice;
}

有什么办法可以使第二个构造函数中的某些参数成为可选参数,还是非强制性的?

谢谢!

3 个答案:

答案 0 :(得分:1)

自然,在这种情况下,我会想到两种可能来获得所需的东西,Constructor OverloadingBuilder Pattern

尽管当您具有相同的数据格式时,您自然不能依靠前者。在这种情况下(例如OP的问题),最好的选择是采用构建器设计模式。

您可以按照以下步骤构建Item.class的实例


public class Item {



\\... other public functions.. etc


 static class ItemBuilder{

    private Item item;

    public ItemBuilder withNameAndQuantity(String name, int quantity){
      item = new Item(); //default constructor or as per your usecase a private constructor
      item.setName(name);
      item.setQuantity(quantity);
      return this;
    }

    public ItemBuilder withPricePerUnit(Double pricePerUnit){
      if(item!=null){
       item.setPriceUnit(pricePerUnit);
      }
      return this;
    }

    public ItemBuilder withTotalPrice(Double totalPrice){
      if(item!=null){
        item.setTotalPrice(totalPrice);
      }
      return this;
    }

   public Item build(){
    if(item!=null){
      return item;
    }else{
      throw new IllegalStateException("item is null, no name or id set");
    }
   }
 }
}


最后,您可以通过执行以下操作来构建新商品:

Item item = new Item.ItemBuilder(). withNameAndQuantity("apple",10). withTotalPrice(100).build();

答案 1 :(得分:0)

理想情况下,您将类分解为连贯的片段,就像标准化数据库模式一样。

Builder Pattern

通过使构造函数将所有属性设为“规范构造函数*并转发至该属性,可以更好地编写代码。这也将使在记录可用时切换到记录变得更容易。

bootstrap modal

(不是public Item(String name, int quantity) { this(name, quantity, null, null, null); } public Item(String name, int quantity, Integer id, Double pricePerUnit, Double totalPrice) { this.name = name; this.quantity = quantity; this.ID = ID; this.pricePerUnit = pricePerUnit; this.totalPrice = totalPrice; // Shouldn't this be calculated? } 的理想选择。)

答案 2 :(得分:0)

一种方法是创建更多的构造函数,另一种方法是放松不变性并引入setter方法。

因此,您可以使用 Builder Pattern (构建器模式),因为构建器模式将帮助您使用其他属性,同时保留Item类的不变性。

下面是编码的解决方案。这使用了一个附加类ItemBuilder,该类可以帮助我们构建具有所有必需属性和可选属性组合的所需Item对象,而不会失去不变性。

public class Item {
    //All final attributes
    private String name; // required
    private int quantity; // required
    private Integer ID; // optional
    private Double pricePerUnit; // optional
    private Double totalPrice; // optional

    private Item(ItemBuilder builder) {
        this.name = builder.name;
        this.quantity = builder.quantity;
        this.ID = builder.ID;
        this.pricePerUnit = builder.pricePerUnit;
        this.totalPrice = builder.totalPrice;
    }

    //All getter, and NO setter to provide immutability
    public String getName() {
        return name;
    }
    public int getQuantity() {
        return quantity;
    }
    public Integer getID() {
        return ID;
    }
    public Double getPricePerUnit() {
        return pricePerUnit;
    }
    public Double getTotalPrice() {
        return totalPrice;
    }

    @Override
    public String toString() {
        return "User: "+this.name+", "+this.quantity+", "+this.ID+", "+this.pricePerUnit+", "+this.totalPrice;
    }

    public static class ItemBuilder
    {
        private String name; // required
        private int quantity; // required
        private Integer ID; // optional
        private Double pricePerUnit; // optional
        private Double totalPrice; // optional

        public ItemBuilder(String name, int quantity) {
            this.name = name;
            this.quantity = quantity;
        }
        public ItemBuilder ID(Integer ID) {
            this.ID = ID;
            return this;
        }
        public ItemBuilder pricePerUnit(Double pricePerUnit) {
            this.pricePerUnit = pricePerUnit;
            return this;
        }
        public ItemBuilder totalPrice(Double totalPrice) {
            this.totalPrice = totalPrice;
            return this;
        }
        //Return the finally constructed Item object
        public Item build() {
            Item item =  new Item(this);
            validateUserObject(item);
            return item;
        }
        private void validateUserObject(Item item) {
            //Do some basic validations to check 
            //if item object does not break any assumption of system
        }
    }
}

我希望这可以使您清楚地了解如何解决问题。