UML class diagram for a system.

In summary: Discounts: these depend on the booking time, which is something you can easily control. For instance, if a customer books for two nights at the same time, the hotel gets two discount coupons, one for the first night and one for the second night.* Extras: these are handled by the Room class, which has a "bookingExtra" attribute. This is an enumerated type which can have one of three values: "roomOnly", "fullBoard", or "halfBoard". The Room class then handles calculating the correct amount to add to the customer's bill.4. The Room class has a "rates" attribute which lists the room rates for that hotel. This might be
  • #36
JaAnTr said:
Ok, I've got the first line giving me no errors but the second one still is:

Code:
	        Customer customer = booking.getCustomer();
	        Discount discount = customer.getDiscount();

I can see on my UML diagram that the Discount class is connected to the Customer class by aggregation. So does this mean that the Discount class needs a Customer passed to it in it's constructor and then a getDiscount method or is it the other way around? Because the Discount class is just an interface that looks like this and I know interfaces can't have constructors so how do I connect it to the customer?

Code:
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;public interface Discount {

	public BigDecimal getDiscount(Date date);
	
}

You are right that the Discount is an interface. However, the classes derived from Discount (such as CorporateDiscount) are not, so these are the ones you attach to the Customer. If the customer has no discount, then it just stays null, otherwise [say, in the CorporateCustomer's constructor] you can create a CorporateDiscount and assign it to that customer's discount field (so that getDiscount() returns that).

(you can assign a CorporateDiscount to a Discount because a CorporateDiscount "is" a Discount, i.e. it inherits from it - this is what allows polymorphism)
 
Technology news on Phys.org
  • #37
Bacterius said:
You are right that the Discount is an interface. However, the classes derived from Discount (such as CorporateDiscount) are not, so these are the ones you attach to the Customer. If the customer has no discount, then it just stays null, otherwise [say, in the CorporateCustomer's constructor] you can create a CorporateDiscount and assign it to that customer's discount field (so that getDiscount() returns that).

(you can assign a CorporateDiscount to a Discount because a CorporateDiscount "is" a Discount, i.e. it inherits from it - this is what allows polymorphism)

I'm slightly confused what, for example, the CorporateDiscount class should look like then? I've added a constructor that takes a customer but don't know what you mean when you say "create a CorporateDiscount and assign it to that customer's discount field (so that getDiscount() returns that)."

This is my CorporateDiscount class currently:

Code:
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;

public class CorporateDiscount implements Discount {

	Customer customer;
	
	public CorporateDiscount(Customer customer){
		this.customer = customer;
	}
	
    @Override
    public BigDecimal getDiscount(Date date) {
    	Calendar cal = Calendar.getInstance();
    	cal.setTime(date);
    	if ((Calendar.SATURDAY == cal.get(Calendar.DAY_OF_WEEK)) || (Calendar.SUNDAY == cal.get(Calendar.DAY_OF_WEEK))) {
    		BigDecimal weekend = new BigDecimal(0.5);
            return weekend;
        } else {
        	BigDecimal weekday = new BigDecimal(0.8);
            return weekday;
        }
    }

}
 
  • #38
Something like this (EDITED):

Code:
public class CorporateCustomer implements Customer {
    private CorporateDiscount discount;

    // ...

    public CorporateCustomer(String name, String address, etc..) {
        discount = new CorporateDiscount();
        this.name = name;
        // etc..
    }

    public Discount getDiscount() {
        return discount;
    }

    // etc..
}

And then the CorporateDiscount has no knowledge of the customer class and takes no customer in its constructor (it's the opposite: the customer knows about the type of discount it is entitled to).
 
  • #39
Bacterius said:
Something like this (EDITED):

Code:
public class CorporateCustomer implements Customer {
    private CorporateDiscount discount;

    // ...

    public CorporateCustomer(String name, String address, etc..) {
        discount = new CorporateDiscount();
        this.name = name;
        // etc..
    }

    public Discount getDiscount() {
        return discount;
    }

    // etc..
}

And then the CorporateDiscount has no knowledge of the customer class and takes no customer in its constructor (it's the opposite: the customer knows about the type of discount it is entitled to).
I've changed my CorporateDiscount class to reflect your suggestions:

Code:
import java.text.ParseException;public class CorporateCustomer implements Customer {

	String name;
	Integer phone;
	String address;
	private CorporateDiscount discount;
	HotelBooking hotelBooking;

	public CorporateCustomer(String name, int phone, String address, String dateTo, String dateFrom) throws ParseException{
		this.name = name;
		this.phone = phone;
		this.address = address;
		this.hotelBooking = new HotelBooking(dateTo, dateFrom, null);
		
	}
	
	
	@Override
	public void setName(String newName) {
		name = newName;
	}

	@Override
	public String getName() {
		return name;
	}

	@Override
	public void setPhone(Integer newPhone) {
		phone = newPhone;
	}

	@Override
	public Integer getPhone() {
		return phone;
	}

	@Override
	public void setAddress(String newAddress) {
		address = newAddress;
	}

	@Override
	public String getAddress() {
		return address;
	}
	
	public Discount getDiscount() {
	    return discount;
	}

}

But I'm still getting an error on this line in HotelBooking:

Code:
Discount discount = customer.getDiscount();

With the error "The method getDiscount() is undefined for the type Customer".
 
  • #40
You probably haven't added the getDiscount() method to the Customer interface.
 
  • #41
Bacterius said:
You probably haven't added the getDiscount() method to the Customer interface.

Got it working (with slight issues, haha)! :D

Basically I've got it working for a CorporateCustomer now, however no discount is being applied to him at all. I've been looking and tinkering but I just can't get a discount to be taken off.

I'll post the relevant code if you don't mind having a look, I'm sure it's reasonably obvious but I can't see it. I've had to do some conversion between Calendars and Dates but aside from that not changed it much.

I know that I haven't used the HotelBillingSystem class to calculate it, but I'm just testing it at the moment.

CorporateCustomer
Code:
import java.text.ParseException;public class CorporateCustomer implements Customer {

	String name;
	Integer phone;
	String address;
	private CorporateDiscount discount;	public CorporateCustomer(String name, int phone, String address, String dateTo, String dateFrom) throws ParseException{
		this.name = name;
		this.phone = phone;
		this.address = address;
	}
	
	
	@Override
	public void setName(String newName) {
		name = newName;
	}

	@Override
	public String getName() {
		return name;
	}

	@Override
	public void setPhone(Integer newPhone) {
		phone = newPhone;
	}

	@Override
	public Integer getPhone() {
		return phone;
	}

	@Override
	public void setAddress(String newAddress) {
		address = newAddress;
	}

	@Override
	public String getAddress() {
		return address;
	}
	
	public Discount getDiscount() {
	    return discount;
	}

}

CorporateDiscount
Code:
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;

public class CorporateDiscount implements Discount {

	Customer customer;
	
	public CorporateDiscount(Customer customer){
		this.customer = customer;
	}
	
    @Override
    public BigDecimal getDiscount(Date date) {
    	Calendar cal = Calendar.getInstance();
    	cal.setTime(date);
    	if ((Calendar.SATURDAY == cal.get(Calendar.DAY_OF_WEEK)) || (Calendar.SUNDAY == cal.get(Calendar.DAY_OF_WEEK))) {
    		BigDecimal weekend = new BigDecimal(0.5);
            return weekend;
        } else {
        	BigDecimal weekday = new BigDecimal(0.8);
            return weekday;
        }
    }

}

HotelBooking
Code:
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Currency;
import java.util.Date;
import java.util.concurrent.TimeUnit;public class HotelBooking {
	
	Date dateFrom;
	Date dateTo;
	long stayLength;
	long weekends;
	private Integer flatRate = 100;
	private BigDecimal totalBill;
	Customer customer;	public HotelBooking(String dateFrom, String dateTo, Customer customer) throws ParseException{
		this.dateFrom = new SimpleDateFormat( "yyyy MM dd" ).parse(dateFrom);
		this.dateTo = new SimpleDateFormat( "yyyy MM dd" ).parse(dateTo);
		this.customer = customer;
	}
	
	public void setDateFrom(String newDate) throws ParseException{
		dateFrom = new SimpleDateFormat( "yyyy MM dd" ).parse(newDate);
	}
	
	public Date getDateFrom(){
		return dateFrom;
	}
	
	public void setDateTo(String newDate) throws ParseException{
		dateTo = new SimpleDateFormat( "yyyy MM dd" ).parse(newDate);
	}
	
	public Date getDateTo(){
		return dateTo;
	}
	
	public long calculateStayLength(){
		long diff = dateTo.getTime() - dateFrom.getTime();
	    stayLength = TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS);
	    return stayLength;
	}
	
	public Customer getCustomer(){
		return this.customer;
	}
	
	public BigDecimal calculateBill(HotelBooking booking) {
	    Calendar cal1 = Calendar.getInstance();
	    Calendar cal2 = Calendar.getInstance();
	    cal1.setTime(booking.getDateFrom());
	    cal2.setTime(booking.getDateTo());

	    BigDecimal totalBill =  new BigDecimal(0.0);
	    while (cal1.before(cal2)) {
	        // for each day of the stay for this booking... (here day = cal1)
	    	Date dateCal1 = cal1.getTime();
	        BigDecimal billForThisDay = new BigDecimal(flatRate);

	        // work out the discount...
	        Customer customer = booking.getCustomer();
	        Discount discount = customer.getDiscount();
	        
	        //Discount discount = booking.getCustomer().getDiscount();

	        if (discount != null) { // has discount?
	            // what is the discount for this day?
	        	System.out.println(discount.getDiscount(dateCal1));
	            billForThisDay = billForThisDay.multiply(discount.getDiscount(dateCal1));
	        }

	        // same thing for extra charge and anything else needed to bill...

	        totalBill = totalBill.add(billForThisDay);

	        cal1.add(Calendar.DATE,1); // go to the next day
	}
	    System.out.println(totalBill);
	    return totalBill;
	}
	
}

Main
Code:
import java.text.ParseException;public class Main {

	public static void main(String[] args) throws ParseException {
		CorporateCustomer myCorporateCustomer = new CorporateCustomer("James", 01633, "5 King Edward Road", "2015 02 19", "2015 02 27");		
		HotelBooking hb = new HotelBooking("2015 02 19", "2015 02 26" , myCorporateCustomer);
		hb.calculateBill(hb);

	}

}

Cheers :DEDIT:

Done some more debugging, and it turns out that this loop,

Code:
	        if (discount != null) { // has discount?
	            // what is the discount for this day?
	        	System.out.println("TEST TO SEE IF THIS GETS EXECUTED");
	        	System.out.println(discount.getDiscount(dateCal1));
	            billForThisDay = billForThisDay.multiply(discount.getDiscount(dateCal1));
	        }

never gets executed, so discount must be null. Why is this?
 
Last edited:
  • #42
The discount is null because you never created the discount (assigned an actual CorporateDiscount to the customer's discount field) in the CorporateCustomer's constructor. :)
 
  • #43
Bacterius said:
The discount is null because you never created the discount (assigned an actual CorporateDiscount to the customer's discount field) in the CorporateCustomer's constructor. :)

Oh of course, thought it was because a discount was never made. This might be stupid but the CorporateDiscount class takes a customer as a parameter, so when I'm creating it the CorporateCustomer's constructor what do I put as the parameter since shouldn't it be the CorporateCustomer itself, if that makes sense.

Code:
CorporateDiscount discount = new CorporateDiscount(What goes in here?);
 
  • #44
JaAnTr said:
Oh of course, thought it was because a discount was never made. This might be stupid but the CorporateDiscount class takes a customer as a parameter, so when I'm creating it the CorporateCustomer's constructor what do I put as the parameter since shouldn't it be the CorporateCustomer itself, if that makes sense.

Code:
CorporateDiscount discount = new CorporateDiscount(What goes in here?);

Technically it can (it's the famous "this" keyword) but if you look closely at your CorporateDiscount class you will find it doesn't actually need the customer anyway :D
 
  • #45
Bacterius said:
Technically it can (it's the famous "this" keyword) but if you look closely at your CorporateDiscount class you will find it doesn't actually need the customer anyway :D

Perfect! It's working now, just got to do the other types of customers but that should be straight forward, hopefully won't have any more issues. Thanks! :D
 
  • #46
Ok, I've finished doing the other customer types and it's all working. Just going back through the spec and I read this.

"The main focus of your implementation should concentrate upon manipulating a list (or array/vector) of customers."

I'm not sure exactly what this means, but this is what I've done in my main class.

Code:
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;public class Main {

	public static void main(String[] args) throws ParseException {
		
		HotelBillingSystem hbs = new HotelBillingSystem();
		
		CorporateCustomer myCorporateCustomer = new CorporateCustomer("James", 01633, "5 King Edward Road");		
		HotelBooking hb = new HotelBooking("2015 02 19", "2015 03 02" , myCorporateCustomer);
		hbs.calculateBill(hb);
		
		
		IndividualCustomer myIndividualCustomer = new IndividualCustomer("John", 01633, "15 Court Crescent");
		HotelBooking hb2 = new HotelBooking("2015 02 22", "2015 02 28", myIndividualCustomer);
		hbs.calculateBill(hb2);
		
		
		GroupCustomer myGroupCustomer = new GroupCustomer("Jane", 01633, "24 Western Avenue", 10);
		HotelBooking hb3 = new HotelBooking("2015 02 22", "2015 02 28", myGroupCustomer);
		hbs.calculateBill(hb3);
		
		
		List<Customer> customer = new ArrayList<Customer>();
		customer.add(myCorporateCustomer);
		customer.add(myIndividualCustomer);
		customer.add(myGroupCustomer);
	}

}

As you can see at the bottom I've added the 3 customers that I have created to an ArrayList which holds customers. What is the advantage/point of doing this?

Cheers :D
 
  • #47
The main advantage is that you can loop over it to get the hotel billing system to calculate the bill for each customer automatically, I think. For instance you might load them into a list from a database and need to be able to operate your billing system no matter how many customers there are, in the real world you won't just have three customers hardcoded into your main function ;)

Of course with your design it probably makes more sense to put hotel bookings in a list instead, since that's what the hotel billing system operates on - so you might have a list of customers in the system (or a map from customer name to Customer class, for convenience) and then a list of hotel bookings that reference the customers from that list [as a parameter to their constructor] and finally the hotel booking system iterates over that list of hotel bookings and generates bills for each. Right?
 
  • #48
Bacterius said:
The main advantage is that you can loop over it to get the hotel billing system to calculate the bill for each customer automatically, I think. For instance you might load them into a list from a database and need to be able to operate your billing system no matter how many customers there are, in the real world you won't just have three customers hardcoded into your main function ;)

Of course with your design it probably makes more sense to put hotel bookings in a list instead, since that's what the hotel billing system operates on - so you might have a list of customers in the system (or a map from customer name to Customer class, for convenience) and then a list of hotel bookings that reference the customers from that list [as a parameter to their constructor] and finally the hotel booking system iterates over that list of hotel bookings and generates bills for each. Right?

Oh ok that makes sense. Just one quick question, I'm curious as to why the Customer class that I've used is an interface as opposed to an abstract class? Seeing as there are some methods which some customer classes essentially don't use, like IndividualCustomer returning null for discount and extra charge. If this was an abstract class then am I right in saying those methods would just not need to be implemented at all?
 
  • #49
JaAnTr said:
Oh ok that makes sense. Just one quick question, I'm curious as to why the Customer class that I've used is an interface as opposed to an abstract class? Seeing as there are some methods which some customer classes essentially don't use, like IndividualCustomer returning null for discount and extra charge. If this was an abstract class then am I right in saying those methods would just not need to be implemented at all?

You are absolutely right that Customer would be better suited to be an abstract class than an interface, the reason being that all Customer derived classes have exactly the same functionality and only differ in the data they contain (the discounts, charges and name/address/etc). This is made obvious by the fact that the only difference between the different types of customers is their constructor.
 

Similar threads

Replies
12
Views
964
  • Programming and Computer Science
Replies
4
Views
3K
  • Engineering and Comp Sci Homework Help
Replies
7
Views
9K
  • Programming and Computer Science
Replies
6
Views
1K
Replies
14
Views
2K
Replies
1
Views
7K
  • Programming and Computer Science
Replies
2
Views
2K
  • Programming and Computer Science
Replies
1
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
2
Views
3K
Back
Top