Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More robust version for beverage-machine & Proper distribution of matches for IPL-tournament #3

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,7 @@
import com.tarktech.training.beverage.maker.BeverageMaker;

public class BlackTeaMaker extends BeverageMaker {
public BlackTeaMaker() {
}

public String dispenseBeverage() {
validateBeveragesAreAvailable();
updateBeverageCount();
return "Enjoy your black tea!";
return configBeverage(BeverageType.valueOf("BlackTea"));
}
}
7 changes: 2 additions & 5 deletions beverage-machine/src/com/tarktech/training/beverage/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,11 @@
public class Main {

public static void main(String[] args) {

Runner

BeverageMachine beverageMachine = new BeverageMachine();
Scanner scanner = new Scanner(System.in);

System.out.println("\nWhat beverage do you want (to refresh your morning)?");
System.out.println("Please type Tea, Latte, Mocha, Cappuccino. Enter Done, if you feel refreshed!");
System.out.println("Please type Tea, Latte, Mocha, Cappuccino or BlackTea. Enter Done, if you feel refreshed!");

String userInput = scanner.nextLine();

Expand All @@ -34,7 +31,7 @@ public static void main(String[] args) {
System.out.println("There are " + availableBeverageCount + " more " + beverageType + " available.");

System.out.println("\nWhat beverage do you want (to refresh your morning)?");
System.out.println("Please type Tea, Latte, Mocha, Cappuccino. Enter Done, if you feel refreshed!");
System.out.println("Please type Tea, Latte, Mocha, Cappuccino or BlackTea. Enter Done, if you feel refreshed!");
}
catch (RuntimeException ex){
System.out.println("Error: " + ex.getMessage());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package com.tarktech.training.beverage.maker;

import com.tarktech.training.beverage.BeverageType;

public abstract class BeverageMaker {
private int dispensedBeverageCount;
private int availableBeverageCount;

private String[] msgs= {"Enjoy your Hot Masala Tea!", "Enjoy your Latte with fresh creamy milk!", "Enjoy hot cappuccino made from freshly brewed beans!", "Enjoy your cup of Mocha made from exotic chocolate!", "Enjoy your black tea!"};

public BeverageMaker(){
dispensedBeverageCount = 0;
availableBeverageCount = 5;
Expand All @@ -28,5 +32,11 @@ public void validateBeveragesAreAvailable(){
}
}

public String configBeverage(BeverageType type){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically this is correct solution!
It also meets the constrainsts that we've laid out in the workshop.
So, good effort on this.

However, there is scope to improvize it further, i.e.

  1. As a good design practice, we should follow Single Responsibility principle (as much as we can). Here base class holds all the messages and so in a way, base class knows about different beverage types, which are supported. As per Single Responsibility Principle, we should avoid this.
  2. While adding support for new beverage, we need to implement new class as well as we need to modify the BeverageMaker as well (though just a tiny change about adding new message in the config array). Ideally, while adding support for new Beverage type, there should not be a need to modify BeverageMaker (base) class.

So, let's improvize it further so that the

  1. Beverage message (prepration logic) is inside child classes only, i.e. BeverageMaker will not store these messages.
  2. While adding support for new beverage type, we do not need to modify BeverageMaker as base class.

Hint:
Implementation as of yesterday,

class MochaMaker extens BeverageMaker {
  public String dispenseBeverage() {
        validateBeveragesAreAvailable();
        updateBeverageCount();
        return "Enjoy your cup of Mocha made from exotic chocolate!";
    }
}

Is it possible to modify it like below? Find a pattern and then apply the learnings from yesterday's session to eliminate duplicate code across all BeverageMakers?

class MochaMaker extens BeverageMaker {
  public String dispenseBeverage() {
        validateBeveragesAreAvailable();
        updateBeverageCount();
        return prepareBeverage();
    }
    
   public String prepareBeverage() {
      return "Enjoy your cup of Mocha made from exotic chocolate!";
   }
}

validateBeveragesAreAvailable();
updateBeverageCount();
return msgs[type.ordinal()];
}

public abstract String dispenseBeverage();
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
package com.tarktech.training.beverage.maker;

public class CappuccinoMaker extends BeverageMaker {
public CappuccinoMaker(){
import com.tarktech.training.beverage.BeverageType;

}
public class CappuccinoMaker extends BeverageMaker {
public String dispenseBeverage() {
validateBeveragesAreAvailable();
updateBeverageCount();
return "Enjoy hot cappuccino made from freshly brewed beans!";
return configBeverage(BeverageType.valueOf("Cappuccino"));
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
package com.tarktech.training.beverage.maker;

public class LatteMaker extends BeverageMaker {

public LatteMaker(){
}
import com.tarktech.training.beverage.BeverageType;

public class LatteMaker extends BeverageMaker {
public String dispenseBeverage() {
if(getAvailableBeverageCount() == 0){
throw new RuntimeException("Sorry, Beverage is out of stock!");
}
updateBeverageCount();
return "Enjoy your Latte with fresh creamy milk!";
return configBeverage(BeverageType.valueOf("Latte"));
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
package com.tarktech.training.beverage.maker;

public class MochaMaker extends BeverageMaker {

public MochaMaker() {
}
import com.tarktech.training.beverage.BeverageType;

public class MochaMaker extends BeverageMaker {
public String dispenseBeverage() {
validateBeveragesAreAvailable();
updateBeverageCount();
return "Enjoy your cup of Mocha made from exotic chocolate!";
return configBeverage(BeverageType.valueOf("Mocha"));
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package com.tarktech.training.beverage.maker;


public class TeaMaker extends BeverageMaker {

import com.tarktech.training.beverage.BeverageType;

public class TeaMaker extends BeverageMaker {
public String dispenseBeverage() {
validateBeveragesAreAvailable();
updateBeverageCount();
return "Enjoy your Hot Masala Tea!";
return configBeverage(BeverageType.valueOf("Tea"));
}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,41 @@ public List<CricketMatch> scheduleLeagueRound(List<Team> teams, LocalDate startD

LocalDate matchScheduleDate = startDate;

for (int i = 0; i < teams.size(); ++i) {
for (int j = i + 1; j < teams.size(); ++j) {
CricketMatch cricketMatch = new CricketMatch(teams.get(i), teams.get(j));
cricketMatch.scheduleOn(matchScheduleDate);

scheduledMatches.add(cricketMatch);

matchScheduleDate = matchScheduleDate.plusDays(1);
ArrayList<String> schedule = new ArrayList<>();
int r = 0;
int i = 0;
int j = teams.size()-1;

if (teams.size() % 2 == 0) {
while (r < teams.size() - 1) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This appears to be a correct approach.

However, in each round, we also need to schedule a match between last team in the array and team at array position (n-1)/2, where n is the total team count.

That is the team which is located at top in the polygon and the one at the center.
You may want to refer below link,
https://nrich.maths.org/1443

For example, if team size is 10 (Team-0 to Team-9), the scheduled matches in first round would be,

  • Team 0 - Team 8
  • Team 1 - Team 7
  • Team 2 - Team 6
  • Team 3 - Team 5
  • Team 4 - Team 9 (Team at top of the polygon vs Team at the centre of polygon)

Additionally, using above reference link, also try to implement it for odd number of teams.

At last, try to schedule matches (when team count is >= 10) so that none of the team has to play matches on consecutive days, i.e. each team will get at least one day to rest/practice after playing a match.

while (i < j) {
schedule.add(teams.get(i) + " " + teams.get(j));

CricketMatch cricketMatch = new CricketMatch(teams.get(i), teams.get(j));
cricketMatch.scheduleOn(matchScheduleDate);
scheduledMatches.add(cricketMatch);
matchScheduleDate = matchScheduleDate.plusDays(1);

i++;
j--;
}
i = 0;
j = teams.size() - 1;

//right shifting of teams...
List<Team> temp = new ArrayList<>(teams);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can further simplify the array rotation, using the methods supported by List/ArrayList. This will eliminate the for loop completely.

You may want to look at below documentation and see, which methods could be used to achieve this.
https://docs.oracle.com/javase/8/docs/api/java/util/List.html

teams.set(1, temp.get(temp.size()-1));

for (int k=2; k<temp.size(); k++){
teams.set(k, temp.get(k-1));
}

r++;
}
//System.out.println(schedule);
}

//System.out.println(scheduledMatches);
return scheduledMatches;
}
}