您可以使用构造函数或生成器模式或生成器模式的变体来解决初始化步骤中字段过多的问题。
我将稍微扩展一下您的示例,以证明我的观点,即为什么这些选项很有用。
了解您的示例:
假设 an 只是 4 个字段的容器类:Offer
public class Offer {
private int price;
private Date dateOfOffer;
private double duration;
private HotelOnly hotelOnly;
// etc. for as many or as few fields as you need
public int getPrice() {
return price;
}
public Date getDateOfOffer() {
return dateOfOffer;
}
// etc.
}
在您的示例中,要为这些字段设置值,请使用 setter:
public void setHotelOnly(HotelOnly hotelOnly) {
this.hotelOnly = hotelOnly;
}
不幸的是,这意味着如果您需要在所有字段中都具有值的报价,则必须执行您拥有的功能:
Offers offers = new Offers();
Offer offer = new Offer();
offer.setPrice(price);
offer.setDateOfOffer(date);
offer.setDuration(duration);
offer.setHotelOnly(hotelOnly);
offers.add(offer);
现在让我们来看看如何改进这一点。
选项 1:构造函数!
默认构造函数以外的构造函数(默认构造函数当前为 )对于初始化类中字段的值很有用。Offer()
使用构造函数的版本将如下所示:Offer
public class Offer {
private int price;
private Date dateOfOffer;
//etc.
// CONSTRUCTOR
public Offer(int price, Date dateOfOffer, double duration, HotelOnly hotelOnly) {
this.price = price;
this.dateOfOffer = dateOfOffer;
//etc.
}
// Your getters and/or setters
}
现在,我们可以在一行中初始化它!
Offers offers = new Offers();
Offer offer = new Offer(price, date, duration, hotelOnly);
offers.add(offer);
更好的是,如果您从不使用那一行以外的其他行:您甚至不需要将其保存在变量中!offer
offers.add(offer);
Offers offers = new Offers();
offers.add( new Offer(price, date, duration, hotelOnly) ); // Works the same as above
选项 2:生成器模式
如果您希望为任何字段提供默认值选项,则生成器模式非常有用。
生成器模式解决的问题是以下混乱的代码:
public class Offer {
private int price;
private Date dateOfOffer;
// etc.
// The original constructor. Sets all the fields to the specified values
public Offer(int price, Date dateOfOffer, double duration, HotelOnly hotelOnly) {
this.price = price;
this.dateOfOffer = dateOfOffer;
// etc.
}
// A constructor that uses default values for all of the fields
public Offer() {
// Calls the top constructor with default values
this(100, new Date("10-13-2015"), 14.5, new HotelOnly());
}
// A constructor that uses default values for all of the fields except price
public Offer(int price) {
// Calls the top constructor with default values, except price
this(price, new Date("10-13-2015"), 14.5, new HotelOnly());
}
// A constructor that uses default values for all of the fields except Date and HotelOnly
public Offer(Date date, HotelOnly hotelOnly) {
this(100, date, 14.5, hotelOnly);
}
// A bunch more constructors of different combinations of default and specified values
}
看看这会变得多么混乱吗?
生成器模式是放在类中的另一个类。
public class Offer {
private int price;
// etc.
public Offer(int price, ...) {
// Same from above
}
public static class OfferBuilder {
private int buildPrice = 100;
private Date buildDate = new Date("10-13-2015");
// etc. Initialize all these new "build" fields with default values
public OfferBuilder setPrice(int price) {
// Overrides the default value
this.buildPrice = price;
// Why this is here will become evident later
return this;
}
public OfferBuilder setDateOfOffer(Date date) {
this.buildDate = date;
return this;
}
// etc. for each field
public Offer build() {
// Builds an offer with whatever values are stored
return new Offer(price, date, duration, hotelOnly);
}
}
}
现在,您不必有那么多构造函数,但仍然能够选择要保留默认值的值以及要初始化的值。
Offers offers = new Offers();
offers.add(new OfferBuilder().setPrice(20).setHotelOnly(hotelOnly).build());
offers.add(new OfferBuilder().setDuration(14.5).setDate(new Date("10-14-2015")).setPrice(200).build());
offers.add(new OfferBuilder().build());
最后一个报价只是具有所有默认值的报价。其他的都是默认值,除了我设置的值。
看看这如何让事情变得更容易?
选项 3:生成器模式的变体
您还可以通过简单地使当前设置者返回相同的 Offer 对象来使用生成器模式。这是完全相同的,除了没有额外的类。OfferBuilder
警告:正如用户 WW 在下面所述,此选项会破坏 JavaBeans - 容器类(如 Offer)的标准编程约定。因此,您不应将其用于专业目的,并且应该限制在自己的实践中使用。
public class Offer {
private int price = 100;
private Date date = new Date("10-13-2015");
// etc. Initialize with default values
// Don't make any constructors
// Have a getter for each field
public int getPrice() {
return price;
}
// Make your setters return the same object
public Offer setPrice(int price) {
// The same structure as in the builder class
this.price = price;
return this;
}
// etc. for each field
// No need for OfferBuilder class or build() method
}
您的新初始化代码是
Offers offers = new Offers();
offers.add(new Offer().setPrice(20).setHotelOnly(hotelOnly));
offers.add(new Offer().setDuration(14.5).setDate(new Date("10-14-2015")).setPrice(200));
offers.add(new Offer());
最后一个报价只是具有所有默认值的报价。其他的都是默认值,除了我设置的值。
因此,虽然工作量很大,但如果要清理初始化步骤,则需要对包含字段的每个类使用其中一个选项。然后使用我在每个方法中包含的初始化方法。
祝你好运!这些是否需要进一步解释?