我正在为练习编写一个简单的库存系统,并且我有一个包含以下值的物料类:
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;
}
有什么办法可以使第二个构造函数中的某些参数成为可选参数,还是非强制性的?
谢谢!
答案 0 :(得分:1)
自然,在这种情况下,我会想到两种可能来获得所需的东西,Constructor Overloading
和Builder 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
}
}
}
我希望这可以使您清楚地了解如何解决问题。