Ta utgangspunkt i LoyaltyUser-klassen. LoyaltyUser er en klasse som implementerer en bruker som kan samle statuspoeng, og som kan gå opp og ned i status basert på dette. Lojalitetsprogrammet samarbeider med andre og det er derfor ønskelig at andre kan lytte på statusen til en bruker. Grensesnittet for dette er definert i StatusListener. Oppgave A) Fyll ut nødvendige metoder og felt for å støtte lytting i LoyaltyUser klassen, for å gjøre det mulig å lytte på endring i statusen til et brukernavn. Viktig: - En lytter vil kun være interessert i en status, og dersom lytteren registreres på nytt er det en ny status den skal lytte på.
- Selv om lytteren kun er interessert i en status, vil den være interessert i både når brukeren oppnår denne statusen og når den mister den.
Følgende metoder skal endres/implementeres: - checkForStatusUpgrade() - sjekker om brukeren kvalifiserer seg til en endring i statusnivå. Dersom statusen endres bør den si ifra til alle lytterne.
- addListener(StatusListener listener, String status) - Registrerer en lytter som lytter på status.
- removeListener(StatusListener listener) - fjerner lytteren.
- fireStatusChanged(String oldStatus, String newStatus) - Sier ifra til alle lytterne som lytter på enten oldStatus eller newStatus om at statusen er endret.
Expand |
---|
|
Code Block |
---|
| public interface StatusListener {
/**
*
* @param username The username of the user
* @param oldStatus The old status of the user
* @param newStatus The new status of the user
*/
public void statusChanged(String username, String oldStatus, String newStatus);
}
import java.util.Arrays;
import java.util.List;
public class LoyaltyUser {
private String username;
private int points;
private String status;
public static List<String> validStatuses = Arrays.asList("Basic", "Gold", "Silver", "Platinum");
// TODO - Add any extra needed fields here
public LoyaltyUser(String username) {
this.username = username;
this.status = "Basic";
}
public String getUsername() {
return username;
}
public int getPoints() {
return points;
}
public String getStatus() {
return status;
}
/**
* Adds point to this user
* @param points the points to add. Can also be a negative number
*/
public void addPoints(int points) {
this.points += points;
this.checkForStatusUpgrade();
}
/**
* Checks whether the user qualifies for a status upgrade/downgrade.
*
* TODO: If the user qualifies for a new status all observers interested in the new or old
* status should be notified
*/
public void checkForStatusUpgrade() {
if (this.points <= 1000) {
this.status = "Basic";
}
if (this.points > 1000) {
this.status = "Silver";
}
if (this.points > 5000) {
this.status = "Gold";
}
if (this.points > 10000) {
this.status = "Platinum";
}
}
/**
* Adds a listener that listens on when this specific status is obtained or
* lost. If the user has been previously added, the old status should be
* overridden and the listener should listen on the new status
*
* @param listener The listener that will observe
*
* @param status The status the listener will listen to
*
* @throws IllegalArgumentException If the status is not valid
*/
public void addListener(StatusListener listener, String status) {
...
}
/**
* Remove the listener
*
* @param listener The listener to remove
*/
public void removeListener(StatusListener listener) {
...
}
/**
* Updates all listeners that were interested in either the old or the new
* status that the status of the user has changed. Observers should only be
* notified if oldStatus and newStatus is different
*
* @param oldStatus The old status of the user
*
* @param newStatus The new status of the user
*/
private void fireStatusChanged(String oldStatus, String newStatus) {
...
}
}
/* RentalCar listeners listens to changes in Status for all userNames.*/
public class RentalCarListener implements StatusListener {
// TODO - Add any needed fields here
@Override
/**
* Method that should be called when a given userName has updated its status.
*/
public void statusChanged(String username, String oldStatus, String newStatus) {
/// TODO
}
/**
* Get's the discount of a user. Should be a 100 if the user currently has Gold
* status, otherwise should be 0.
*
* @param username The username of the user
*
* @return The discount the user qualifies for.
*/
public int getDiscount(String username) {
// TODO
return 0;
}
} |
|
Expand |
---|
|
Code Block |
---|
| import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class LoyaltyUser {
private String username;
private int points;
private String status;
public static List<String> validStatuses = Arrays.asList("Basic", "Gold", "Silver", "Platinum");
// TODO - Add any extra needed fields here
private Map<StatusListener, String> statusListeners = new HashMap<>();
public LoyaltyUser(String username) {
this.username = username;
this.status = "Basic";
}
public String getUsername() {
return username;
}
public int getPoints() {
return points;
}
public String getStatus() {
return status;
}
/**
* Adds point to this user
* @param points the points to add. Can also be a negative number
*/
public void addPoints(int points) {
this.points += points;
this.checkForStatusUpgrade();
}
/**
* Checks whether the user qualifies for a status upgrade/downgrade.
*
* TODO: If the user qualifies for a new status all observers interested in the new or old
* status should be notified
*/
public void checkForStatusUpgrade() {
String oldStatus = this.status;
if (this.points <= 1000) {
this.status = "Basic";
}
if (this.points > 1000) {
this.status = "Silver";
}
if (this.points > 5000) {
this.status = "Gold";
}
if (this.points > 10000) {
this.status = "Platinum";
}
if (oldStatus != this.status) {
this.fireStatusChanged(oldStatus, this.status);
}
}
private void checkIsValidStatus(String status) {
if (!validStatuses.contains(status)) {
throw new IllegalArgumentException("Invalid status");
}
}
/**
* Adds a listener that listens on when this specific status is obtained or
* lost. If the user has been previously added, the old status should be
* overridden and the listener should listen on the new status
*
* @param listener The listener that will observe
*
* @param status The status the listener will listen to
*
* @throws IllegalArgumentException If the status is not valid
*/
public void addListener(StatusListener listener, String status) {
checkIsValidStatus(status);
this.statusListeners.put(listener, status);
}
/**
* Remove the listener
*
* @param listener The listener to remove
*/
public void removeListener(StatusListener listener) {
this.statusListeners.remove(listener);
}
/**
* Updates all listeners that were interested in either the old or the new
* status that the status of the user has changed. Observers should only be
* notified if oldStatus and newStatus is different
*
* @param oldStatus The old status of the user
*
* @param newStatus The new status of the user
*/
private void fireStatusChanged(String oldStatus, String newStatus) {
for (StatusListener listener: this.statusListeners.keySet()) {
String status = this.statusListeners.get(listener);
if (oldStatus.equals(status) || newStatus.equals(status)) {
listener.statusChanged(this.username, oldStatus, newStatus);
}
}
}
}
|
|
Oppgave b) Implementer RentalCarListener. RentalCarListener lytter på endringer i status til LoyaltyUser i LoyaltyUser for å kunne gi gullmedlemmer rabatt. - statusChanged(String username, String oldStatus, String newStatus) - Registerer endringen i status for et gitt brukernavn.
- getDiscount(String username) Returnerer rabatten til et brukernavn. Skal være 100 hvis brukeren innehar gullnivå, ellers 0.
Code Block |
---|
| import java.util.HashMap;
import java.util.Map;
/* RentalCar listeners listens to changes in Status for all userNames.*/
public class RentalCarListener implements StatusListener {
// TODO - Add any needed fields here
// Many will probably have solved this using a list instead, which is also a good solution
private Map<String, Integer> rebates = new HashMap<>();
private final String GOLD_STATUS = "Gold";
@Override
/**
* Method that should be called when a given userName has updated its status.
*/
public void statusChanged(String username, String oldStatus, String newStatus) {
if (newStatus.equals(GOLD_STATUS)) {
rebates.put(username, 100);
}
else {
rebates.remove(username);
}
}
/**
* Get's the discount of a user. Should be a 100 if the user currently has Gold
* status, otherwise should be 0.
*
* @param username The username of the user
*
* @return The discount the user qualifies for.
*/
public int getDiscount(String username) {
return rebates.getOrDefault(username, 0);
}
}
|
|