Reputation: 11
I'm having trouble figuring out how to organize the constructor.
Is the constructor supposed to take all the variables?
I create an instance of a PizzaOrder by invoking the constructor, and passing it the values in firstName
, pizzaSizeInInches
, pizzaType
, cheeseTopping
, pepperoniTopping
, sausageTopping
, onionTopping
, mushroomTopping
.
public static double calculatePizzaCost() {
double cost = 12.99; //cost of the pizza
String toppings = ""; //list of toppings
int numberOfToppings = 0; //number of toppings
String crust = "";
final double TOPPING_PRICE = 1.25;
if (aPizzaOrder.getHandThinDeep() == 'h' || aPizzaOrder.getHandThinDeep() == 'H') {
crust = "Hand-Tossed";
} else if (aPizzaOrder.getHandThinDeep() == 't' || aPizzaOrder.getHandThinDeep() == 'T') {
crust = "Thin-Crust";
} else if (aPizzaOrder.getHandThinDeep() == 'd' || aPizzaOrder.getHandThinDeep() == 'D') {
crust = "Deep-Pan";
}
if (aPizzaOrder.getCheeseTopping()) {
numberOfToppings += 1;
toppings = toppings + "Additional Cheese ";
}
Upvotes: 1
Views: 92
Reputation: 1549
For such time of problem, we should we some design pattern and here Builder Pattern
is best suited as below. I hope this will help you
package item2;
public class PizzaOrder {
private String firstName;
private int pizzaSizeInInches;
//add other fields
private PizzaOrder(Builder builder){
this.firstName=builder.firstName;
this.pizzaSizeInInches=builder.pizzaSizeInInches;
//set other fields
}
public static class Builder{
private String firstName;
private int pizzaSizeInInches;
//add other fields
public Builder(){
}
public Builder firstName(String firstName){
this.firstName=firstName;
return this;
}
public Builder pizzaSizeInInches(int pizzaSizeInInches) {
this.pizzaSizeInInches = pizzaSizeInInches;
return this;
}
//add other setter method like above
public PizzaOrder build(){
return new PizzaOrder(this);
}
}
public static Builder builder(){
return new Builder();
}
public static void main(String args[]){
PizzaOrder.builder()
.firstName("sanjeev")
.pizzaSizeInInches(10)
.build();
}
}
Upvotes: 0
Reputation: 18812
Basically you can consider three structures, and the combinations of them.
The first one is of course a constructor with a long list of variables :
public class Pizza {
private String firstName, pizzaType;
private String cheeseTopping, pepperoniTopping, sausageTopping;
private int pizzaSizeInInches;
public Pizza(String firstName, String pizzaType, String cheeseTopping, String pepperoniTopping,
String sausageTopping, int pizzaSizeInInches) {
this.firstName = firstName;
this.pizzaType = pizzaType;
this.cheeseTopping = cheeseTopping;
this.pepperoniTopping = pepperoniTopping;
this.sausageTopping = sausageTopping;
this.pizzaSizeInInches = pizzaSizeInInches;
}
}
The second basic structure is using setter
methods for the long list of fields:
public class Pizza {
private String firstName, pizzaType;
private String cheeseTopping, pepperoniTopping, sausageTopping;
private int pizzaSizeInInches;
public Pizza() {};
String getFirstName() { return firstName;}
void setFirstName(String firstName) {this.firstName = firstName;}
String getPizzaType() { return pizzaType; }
void setPizzaType(String pizzaType) { this.pizzaType = pizzaType; }
String getCheeseTopping() { return cheeseTopping; }
void setCheeseTopping(String cheeseTopping) { this.cheeseTopping = cheeseTopping; }
String getPepperoniTopping() {return pepperoniTopping; }
void setPepperoniTopping(String pepperoniTopping) { this.pepperoniTopping = pepperoniTopping; }
String getSausageTopping() { return sausageTopping; }
void setSausageTopping(String sausageTopping) { this.sausageTopping = sausageTopping;}
int getPizzaSizeInInches() {return pizzaSizeInInches; }
void setPizzaSizeInInches(int pizzaSizeInInches) { this.pizzaSizeInInches = pizzaSizeInInches; }
}
A side note : having the setter
methods return this
, for example :
Pizza setCheeseTopping(String cheeseTopping) {
this.cheeseTopping = cheeseTopping;
return this;
}
Pizza setPepperoniTopping(String pepperoniTopping) {
this.pepperoniTopping = pepperoniTopping;
return this;
}
makes it more convenient to invoke long list of setters
by chaining them : pizza.setCheeseTopping("Melt").setPepperoniTopping("Hot");
A reasonable combination of the two above approaches is to have the constructor initialize the essential fields, and use setters
for the optional fields, or those with a default value :
public class Pizza {
private String firstName, pizzaType;
private String cheeseTopping, pepperoniTopping, sausageTopping;
private int pizzaSizeInInches;
public Pizza(String firstName, String pizzaType) {
this.firstName = firstName;
this.pizzaType = pizzaType;
}
String getFirstName() { return firstName;}
String getPizzaType() { return pizzaType;}
String getCheeseTopping() { return cheeseTopping; }
Pizza setCheeseTopping(String cheeseTopping) {
this.cheeseTopping = cheeseTopping;
return this;
}
String getPepperoniTopping() {return pepperoniTopping; }
Pizza setPepperoniTopping(String pepperoniTopping) {
this.pepperoniTopping = pepperoniTopping;
return this;
}
String getSausageTopping() { return sausageTopping; }
Pizza setSausageTopping(String sausageTopping) {
this.sausageTopping = sausageTopping;
return this;
}
int getPizzaSizeInInches() {return pizzaSizeInInches; }
Pizza setPizzaSizeInInches(int pizzaSizeInInches) {
this.pizzaSizeInInches = pizzaSizeInInches;
return this;
}
}
A third approach for initializing long list of variables is to use the Builder Pattern :
public class Pizza {
private String firstName, pizzaType, cheeseTopping, pepperoniTopping, sausageTopping;
private int pizzaSizeInInches;
public Pizza(PizzaBuilder builder) {
this.firstName = builder.firstName;
this.pizzaType = builder.pizzaType;
this.pizzaSizeInInches = builder.pizzaSizeInInches;
this.cheeseTopping = builder.cheeseTopping;
this.pepperoniTopping = builder.pepperoniTopping;
this.sausageTopping = builder.sausageTopping;
}
String getFirstName() { return firstName;}
String getPizzaType() { return pizzaType;}
String getCheeseTopping() { return cheeseTopping; }
String getPepperoniTopping() {return pepperoniTopping; }
String getSausageTopping() { return sausageTopping; }
int getPizzaSizeInInches() {return pizzaSizeInInches; }
static class PizzaBuilder {
private String firstName, pizzaType;
private String cheeseTopping, pepperoniTopping, sausageTopping;
private int pizzaSizeInInches;
PizzaBuilder setFirstName(String firstName) {
this.firstName = firstName;
return this;
}
PizzaBuilder setPizzaType(String pizzaType) {
this.pizzaType = pizzaType;
return this;
}
PizzaBuilder setPizzaSizeInInches(int pizzaSizeInInches) {
this.pizzaSizeInInches = pizzaSizeInInches;
return this;
}
PizzaBuilder setCheeseTopping(String cheeseTopping) {
this.cheeseTopping = cheeseTopping;
return this;
}
PizzaBuilder setPepperoniTopping(String pepperoniTopping) {
this.pepperoniTopping = pepperoniTopping;
return this;
}
PizzaBuilder setSausageTopping(String sausageTopping) {
this.sausageTopping = sausageTopping;
return this;
}
Pizza buid (){
return new Pizza(this);
}
}
//make new Pizza
public static void main(String[] args) {
Pizza pizza = new PizzaBuilder().
setFirstName("Jack").setPizzaType("Annanas").
setPizzaSizeInInches(10).setCheeseTopping("Melt").
setPepperoniTopping("Hot").setSausageTopping("None").
buid();
}
}
Upvotes: 0
Reputation: 3173
The general thumb rule is that the constructor should accept those arguments without which your object has no meaning. For e.g. Car is useless without an Engine. All the other attributes which are nice to have or add more features can be left as properties.
Besides that, you can also create a hierarchy of Classes with each having its own constructor detecting which properties must be mandatorily initialized. E.g. Base class is declared as Pizza which accepts size as an argument in constructor. Then you can have Cheez pizza derived from Pizza class, which accepts mandatory arguments to construct Cheez pizza.
Upvotes: 1