Skip to content

Instantly share code, notes, and snippets.

@jack-is
Last active May 31, 2017 17:54
Show Gist options
  • Save jack-is/ba9f1b6e141db2323041addd408f3fb3 to your computer and use it in GitHub Desktop.
Save jack-is/ba9f1b6e141db2323041addd408f3fb3 to your computer and use it in GitHub Desktop.
Restaurant (Observer pattern)
package com.javarush.test.level27.lesson15.big01.ad;
public class Advertisement {
private Object content;
private String name;
private long initialAmount;
private int hits;
private int duration;
private long amountPerOneDisplaying;
public Advertisement(Object content, String name, long initialAmount, int hits, int duration) {
this.content = content;
this.name = name;
this.initialAmount = initialAmount;
this.hits = hits;
this.duration = duration;
amountPerOneDisplaying = initialAmount / hits;
}
public String getName() {
return name;
}
public int getDuration() {
return duration;
}
public int getHits() {
return hits;
}
public long getAmountPerOneDisplaying() {
return amountPerOneDisplaying;
}
public void revalidate() {
if (hits <= 0) throw new UnsupportedOperationException();
hits--;
if (hits == 1) amountPerOneDisplaying += initialAmount % amountPerOneDisplaying;
}
}
package com.javarush.test.level27.lesson15.big01.ad;
import com.javarush.test.level27.lesson15.big01.ConsoleHelper;
import com.javarush.test.level27.lesson15.big01.statistic.StatisticEventManager;
import com.javarush.test.level27.lesson15.big01.statistic.event.VideoSelectedEventDataRow;
import java.util.*;
public class AdvertisementManager {
private final AdvertisementStorage storage = AdvertisementStorage.getInstance();
private int timeSeconds;
public AdvertisementManager(int timeSeconds) {
this.timeSeconds = timeSeconds;
}
public void processVideos() {
List<Advertisement> videos = OptimalVideoList(powerLists(storage.list()));
Collections.sort(videos, new Comparator<Advertisement>() {
@Override
public int compare(Advertisement o1, Advertisement o2) {
int result = Long.compare(o1.getAmountPerOneDisplaying(), o2.getAmountPerOneDisplaying());
if (result != 0) return -result;
else {
long oneSecondCost1 = o1.getAmountPerOneDisplaying() * 1000 / o1.getDuration();
long oneSecondCost2 = o2.getAmountPerOneDisplaying() * 1000 / o2.getDuration();
return Long.compare(oneSecondCost1, oneSecondCost2);
}
}
});
StatisticEventManager.getInstance().register(new VideoSelectedEventDataRow(videos, getTotalAmount(videos), getTotalTime(videos)));
for (Advertisement advertisement : videos) {
ConsoleHelper.writeMessage(advertisement.getName() + " is displaying... "
+ advertisement.getAmountPerOneDisplaying() + ", "
+ advertisement.getAmountPerOneDisplaying() * 1000 / advertisement.getDuration());
advertisement.revalidate();
}
if(videos.isEmpty()){
throw new NoVideoAvailableException();
}
}
public List<Advertisement> OptimalVideoList(List<List<Advertisement>> list){
List<Advertisement> optimal = new ArrayList<>();
Iterator A = list.iterator();
while (A.hasNext()){ // Перебор наборов видео
List<Advertisement> checkList = (ArrayList<Advertisement>) A.next();
int timeOfVideoSet=0;
boolean removeSet=false;
for (Advertisement a:checkList){ // Перебор= видео в наборе
timeOfVideoSet+=a.getDuration();
if(a.getHits()<=0){removeSet=true;}
}
if(timeOfVideoSet>timeSeconds){removeSet=true;}
if(removeSet){
A.remove();
}
}
Comparator comparator = new Comparator<List<Advertisement>>() {
@Override
public int compare(List<Advertisement> o1, List<Advertisement> o2) {
long profit1=0, profit2 =0;
int durationOfVideoSet1=0, durationOfVideoSet2=0;
for (Advertisement a:o1){
profit1+=a.getAmountPerOneDisplaying();
durationOfVideoSet1+=a.getDuration();
}
for (Advertisement a:o2){
profit2+=a.getAmountPerOneDisplaying();
durationOfVideoSet2+=a.getDuration();
}
if (profit1 != profit2) return Long.compare(profit2, profit1); // первичная по прибыли от показа (по убыванию)
if (durationOfVideoSet1 != durationOfVideoSet2) return Integer.compare(durationOfVideoSet2, durationOfVideoSet1); // вторичная по длительности (по убыванию)
else return Integer.compare(o1.size(), o2.size()); // по размеру списка (по возрастанию)
}
};
Collections.sort(list,comparator);
optimal=list.get(0); // выбираем первый элемент(найболее подходящий)
return optimal;
}
private <Advertisement> List<List<Advertisement>> powerLists(List<Advertisement> originalSet) {
List<List<Advertisement>> lists = new ArrayList<>();
if (originalSet.isEmpty()) {
lists.add(new ArrayList<Advertisement>());
return lists;
}
List<Advertisement> list = new ArrayList<>(originalSet);
Advertisement head = list.get(0);
List<Advertisement> rest = new ArrayList<>(list.subList(1, list.size()));
for (List<Advertisement> aList : powerLists(rest)) {
List<Advertisement> newList = new ArrayList<>();
newList.add(head);
newList.addAll(aList);
lists.add(newList);
lists.add(aList);
}
return lists;
}
private long getTotalAmount(List<Advertisement> ad) {
long totalAmount = 0;
if (ad == null) return totalAmount;
for (Advertisement a : ad) {
totalAmount += a.getAmountPerOneDisplaying();
}
return totalAmount;
}
private int getTotalTime(List<Advertisement> ad) {
int totalTime = 0;
if (ad == null) return totalTime;
for (Advertisement a : ad) {
totalTime += a.getDuration();
}
return totalTime;
}
}
package com.javarush.test.level27.lesson15.big01.ad;
import java.util.ArrayList;
import java.util.List;
class AdvertisementStorage {
private static AdvertisementStorage instance;
private final List<Advertisement> videos = new ArrayList<>();
private AdvertisementStorage() {
Object someContent = new Object();
videos.add(new Advertisement(someContent, "First Video", 5000, 100, 3 * 60)); // 3 min
videos.add(new Advertisement(someContent, "Second Video", 100, 10, 15 * 60)); //15 min
videos.add(new Advertisement(someContent, "Third Video", 400, 2, 10 * 60)); //10 min
}
public static AdvertisementStorage getInstance() {
if (instance == null) instance = new AdvertisementStorage();
return instance;
}
public List<Advertisement> list() {
return videos;
}
public void add(Advertisement advertisement) {
videos.add(advertisement);
}
}
package com.javarush.test.level27.lesson15.big01;
import com.javarush.test.level27.lesson15.big01.kitchen.Dish;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class ConsoleHelper {
private static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
public static void writeMessage(String message) {
System.out.println(message);
}
public static String readString() throws IOException {
return reader.readLine();
}
public static List<Dish> getAllDishesForOrder() throws IOException {
List<Dish> orderedDishes = new ArrayList<>();
writeMessage("Choice a dish: ");
writeMessage(Dish.allDishesToString());
String nextDish;
while (!"exit".equalsIgnoreCase(nextDish = readString())) {
try {
orderedDishes.add(Dish.valueOf(nextDish));
} catch (IllegalArgumentException e) {
ConsoleHelper.writeMessage(nextDish + " is not detected");
}
}
return orderedDishes;
}
}
package com.javarush.test.level27.lesson15.big01.kitchen;
import com.javarush.test.level27.lesson15.big01.statistic.StatisticEventManager;
import com.javarush.test.level27.lesson15.big01.statistic.event.CookedOrderEventDataRow;
import java.util.Observable;
import java.util.concurrent.LinkedBlockingQueue;
public class Cook extends Observable implements Runnable {
private String name;
private volatile boolean busy;
private LinkedBlockingQueue<Order> queue;
public Cook(String name) {
this.name = name;
}
public boolean isBusy() {
return busy;
}
public void setQueue(LinkedBlockingQueue<Order> queue) {
this.queue = queue;
}
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
startCookingOrder(queue.take());
Thread.sleep(10);
} catch (InterruptedException e) {
return;
}
}
}
@Override
public String toString() {
return name;
}
public void startCookingOrder(Order order) {
busy = true;
System.out.println("Start cooking - " + order + ", cooking time " + order.getTotalCookingTime() + "min");
StatisticEventManager.getInstance().register(new CookedOrderEventDataRow(order.getTablet().toString(), name, order.getTotalCookingTime() * 60, order.getDishes()));
setChanged();
notifyObservers(order);
try {
Thread.sleep(order.getTotalCookingTime() * 10);
} catch (InterruptedException e) {}
busy = false;
}
}
package com.javarush.test.level27.lesson15.big01.statistic.event;
import com.javarush.test.level27.lesson15.big01.kitchen.Dish;
import java.util.Date;
import java.util.List;
public class CookedOrderEventDataRow implements EventDataRow {
private String tabletName;
private String cookName;
private int cookingTimeSeconds;
private List<Dish> cookingDishs;
private Date currentDate;
public CookedOrderEventDataRow(String tabletName, String cookName, int cookingTimeSeconds, List<Dish> cookingDishs) {
this.tabletName = tabletName;
this.cookName = cookName;
this.cookingTimeSeconds = cookingTimeSeconds;
this.cookingDishs = cookingDishs;
currentDate = new Date();
}
@Override
public EventType getType() {
return EventType.COOKED_ORDER;
}
@Override
public Date getDate() {
return currentDate;
}
@Override
public int getTime() {
return cookingTimeSeconds;
}
public String getCookName() {
return cookName;
}
}
package com.javarush.test.level27.lesson15.big01;
import com.javarush.test.level27.lesson15.big01.ad.StatisticAdvertisementManager;
import com.javarush.test.level27.lesson15.big01.statistic.StatisticEventManager;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.TreeMap;
public class DirectorTablet {
private SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MMM-yyyy");
public void printAdvertisementProfit() {
double total = 0;
for (Map.Entry<Date,Long> pair : StatisticEventManager.getInstance().dailyAdIncome().entrySet()) {
double am = pair.getValue()/100.0;
ConsoleHelper.writeMessage(String.format("%s - %.2f", dateFormat.format(pair.getKey()), am));
total+=am;
}
ConsoleHelper.writeMessage(String.format("Total - %.2f", total));
}
public void printCookWorkloading() {
for(Map.Entry<Date, TreeMap<String,Integer>> pair : StatisticEventManager.getInstance().cookWork().entrySet()) {
ConsoleHelper.writeMessage(dateFormat.format(pair.getKey()));
for(Map.Entry<String,Integer> dailyCock: pair.getValue().entrySet()){
ConsoleHelper.writeMessage(String.format("%s - %d min%n", dailyCock.getKey(),dailyCock.getValue()));
}
}
}
public void printActiveVideoSet() {
Map<String, Integer> map = StatisticAdvertisementManager.getInstance().getActiveVideos();
for (Map.Entry<String, Integer> pair : map.entrySet()) {
ConsoleHelper.writeMessage(pair.getKey() + " - " + pair.getValue());
}
}
public void printArchivedVideoSet() {
Map<String, Integer> map = StatisticAdvertisementManager.getInstance().getArchivedVideos();
for (String key : map.keySet()) {
ConsoleHelper.writeMessage(key);
}
}
}
package com.javarush.test.level27.lesson15.big01.kitchen;
public enum Dish {
Fish(25),
Steak(30),
Soup(15),
Juice(5),
Water(3);
private int duration;
Dish(int duration) {
this.duration = duration;
}
public int getDuration() {
return duration;
}
public static String allDishesToString() {
StringBuilder sb = new StringBuilder(values()[0].toString());
for (int i = 1; i < values().length; i++) {
sb.append(", ").append(values()[i]);
}
return sb.toString();
}
}
package com.javarush.test.level27.lesson15.big01.statistic.event;
import java.util.Date;
public interface EventDataRow {
EventType getType();
Date getDate();
int getTime();
}
package com.javarush.test.level27.lesson15.big01.statistic.event;
public enum EventType {
COOKED_ORDER,
SELECTED_VIDEOS,
NO_AVAILABLE_VIDEO;
}
package com.javarush.test.level27.lesson15.big01.statistic.event;
import java.util.Date;
public class NoAvailableVideoEventDataRow implements EventDataRow {
private int totalDuration;
private Date currentDate;
public NoAvailableVideoEventDataRow(int totalDuration) {
this.totalDuration = totalDuration;
currentDate = new Date();
}
@Override
public EventType getType() {
return EventType.NO_AVAILABLE_VIDEO;
}
@Override
public int getTime() {
return totalDuration;
}
@Override
public Date getDate() {
return currentDate;
}
}
package com.javarush.test.level27.lesson15.big01.ad;
public class NoVideoAvailableException extends RuntimeException {
}
package com.javarush.test.level27.lesson15.big01.kitchen;
import com.javarush.test.level27.lesson15.big01.ConsoleHelper;
import com.javarush.test.level27.lesson15.big01.Tablet;
import java.io.IOException;
import java.util.List;
public class Order {
private Tablet tablet;
protected List<Dish> dishes;
public Order(Tablet tablet) throws IOException {
this.tablet = tablet;
initDishes();
}
public int getTotalCookingTime() {
int totalTime = 0;
for (Dish dish : dishes) {
totalTime += dish.getDuration();
}
return totalTime;
}
protected void initDishes() throws IOException {
dishes = ConsoleHelper.getAllDishesForOrder();
}
public List<Dish> getDishes() {
return dishes;
}
public Tablet getTablet() {
return tablet;
}
@Override
public String toString() {
return dishes.isEmpty() ? "" : String.format("Your order: %s of %s", dishes, tablet);
}
public boolean isEmpty() {
return dishes.isEmpty();
}
}
package com.javarush.test.level27.lesson15.big01;
import java.util.ArrayList;
import java.util.List;
public class RandomOrderGeneratorTask implements Runnable {
private List<Tablet> tablets = new ArrayList<>();
private int interval;
public RandomOrderGeneratorTask(List<Tablet> tablets, int interval) {
this.tablets = tablets;
this.interval = interval;
}
@Override
public void run() {
if (tablets.isEmpty()) return;
try {
while (!Thread.currentThread().isInterrupted()) {
Tablet tablet = tablets.get((int)(Math.random() * tablets.size()));
tablet.createTestOrder();
Thread.sleep(interval);
}
} catch (InterruptedException e) {
}
}
}
package com.javarush.test.level27.lesson15.big01;
import com.javarush.test.level27.lesson15.big01.kitchen.Cook;
import com.javarush.test.level27.lesson15.big01.kitchen.Order;
import com.javarush.test.level27.lesson15.big01.kitchen.Waiter;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.LinkedBlockingQueue;
public class Restaurant {
private static final int ORDER_CREATING_INTERVAL = 100;
private static final LinkedBlockingQueue<Order> QUEUE = new LinkedBlockingQueue<>();
public static void main(String[] args) throws InterruptedException {
Locale.setDefault(Locale.ENGLISH);
Cook cook1 = new Cook("Jamie Oliver");
cook1.setQueue(QUEUE);
Cook cook2 = new Cook("I am");
cook2.setQueue(QUEUE);
Waiter waiter = new Waiter();
cook1.addObserver(waiter);
cook2.addObserver(waiter);
List<Tablet> tablets = new ArrayList<>();
for(int i = 0;i < 5; i++){
Tablet tablet = new Tablet(i + 1);
tablet.setQueue(QUEUE);
tablets.add(tablet);
}
Thread cook1Thread = new Thread(cook1);
cook1Thread.start();
Thread cook2Thread = new Thread(cook2);
cook2Thread.start();
Thread randomOrderGeneratorTaskThread = new Thread(new RandomOrderGeneratorTask(tablets, ORDER_CREATING_INTERVAL));
randomOrderGeneratorTaskThread.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
randomOrderGeneratorTaskThread.interrupt();
while (!QUEUE.isEmpty()){
Thread.sleep(1);
}
while ((cook1.isBusy())||(cook2.isBusy())) { Thread.sleep(1);}
cook1Thread.interrupt();
cook2Thread.interrupt();
DirectorTablet directorTablet = new DirectorTablet();
directorTablet.printAdvertisementProfit();
directorTablet.printCookWorkloading();
directorTablet.printActiveVideoSet();
directorTablet.printArchivedVideoSet();
}
}
package com.javarush.test.level27.lesson15.big01.ad;
import java.util.*;
public class StatisticAdvertisementManager {
private static StatisticAdvertisementManager instance= new StatisticAdvertisementManager();
private AdvertisementStorage advertisementStorage = AdvertisementStorage.getInstance();
private StatisticAdvertisementManager() {}
public static StatisticAdvertisementManager getInstance() {
return instance;
}
public Map<String, Integer> getActiveVideos() {
Map<String, Integer> activeVideos = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
for (Advertisement advertisement : advertisementStorage.list()) {
if (advertisement.getHits() > 0) activeVideos.put(advertisement.getName(), advertisement.getHits());
}
return activeVideos;
}
public Map<String, Integer> getArchivedVideos() {
Map<String, Integer> archivedVideos = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
for (Advertisement advertisement : advertisementStorage.list()) {
if (advertisement.getHits() < 1) archivedVideos.put(advertisement.getName(), advertisement.getHits());
}
return archivedVideos;
}
}
package com.javarush.test.level27.lesson15.big01.statistic;
import com.javarush.test.level27.lesson15.big01.statistic.event.CookedOrderEventDataRow;
import com.javarush.test.level27.lesson15.big01.statistic.event.EventDataRow;
import com.javarush.test.level27.lesson15.big01.statistic.event.EventType;
import com.javarush.test.level27.lesson15.big01.statistic.event.VideoSelectedEventDataRow;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
public class StatisticEventManager {
private static StatisticEventManager instanceSM = new StatisticEventManager();
private StatisticStorage storage = new StatisticStorage();
private SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy");
private StatisticEventManager() {}
public static StatisticEventManager getInstance() {
return instanceSM;
}
public void register(EventDataRow data) {
storage.put(data);
}
public TreeMap<Date,Long> dailyAdIncome() {
TreeMap<Date,Long> map = new TreeMap<>(Collections.reverseOrder());
List<EventDataRow> videos = storage.getEvents(EventType.SELECTED_VIDEOS);
for(EventDataRow eventDataRow: videos) {
Date date = null;
try {
date = format.parse(format.format(eventDataRow.getDate()));
} catch (ParseException e){
e.printStackTrace();
}
if (map.containsKey(date)) {
map.put(date,map.get(date)+((VideoSelectedEventDataRow)eventDataRow).getAmount());
} else
map.put(date,((VideoSelectedEventDataRow)eventDataRow).getAmount());
}
return map;
}
public TreeMap<Date, TreeMap<String,Integer>> cookWork() {
TreeMap<Date, TreeMap<String,Integer>> map= new TreeMap<>(Collections.reverseOrder());
List<EventDataRow> list = storage.getEvents(EventType.COOKED_ORDER);
for(EventDataRow eventDataRow: list) {
Date date = null;
try {
date = format.parse(format.format(eventDataRow.getDate())); // дата без времени
} catch (ParseException e){
e.printStackTrace();
}
String cookName = ((CookedOrderEventDataRow) eventDataRow).getCookName(); // имя повара
int time = (int)Math.ceil(eventDataRow.getTime()/60.0); // время в минутах
if(map.containsKey(date)) {
if(map.get(date).containsKey(cookName))
map.get(date).put(cookName, map.get(date).get(cookName) + time);
else map.get(date).put(cookName, time);
}
else {
TreeMap<String, Integer> tempMap = new TreeMap<>();
tempMap.put(cookName,time);
map.put(date, tempMap);
}
}
return map;
}
private class StatisticStorage {
private Map<EventType, List<EventDataRow>> statisticStorage;
private StatisticStorage() {
statisticStorage = new HashMap<>();
for (EventType eventType : EventType.values())
statisticStorage.put(eventType, new ArrayList<EventDataRow>());
}
private void put(EventDataRow data) {
statisticStorage.get(data.getType()).add(data);
}
private List<EventDataRow> getEvents(EventType eventType) {
return statisticStorage.get(eventType);
}
}
}
package com.javarush.test.level27.lesson15.big01;
import com.javarush.test.level27.lesson15.big01.ad.AdvertisementManager;
import com.javarush.test.level27.lesson15.big01.ad.NoVideoAvailableException;
import com.javarush.test.level27.lesson15.big01.kitchen.Order;
import com.javarush.test.level27.lesson15.big01.kitchen.TestOrder;
import com.javarush.test.level27.lesson15.big01.statistic.StatisticEventManager;
import com.javarush.test.level27.lesson15.big01.statistic.event.NoAvailableVideoEventDataRow;
import java.io.IOException;
import java.util.Observable;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Tablet {
public static Logger logger = Logger.getLogger(Tablet.class.getName());
final int number;
private LinkedBlockingQueue<Order> queue;
public Tablet(int number) {
this.number = number;
}
public void setQueue(LinkedBlockingQueue<Order> queue) {
this.queue = queue;
}
public void createOrder() {
try {
final Order newOrder = new Order(this);
insideOrder(newOrder);
} catch (IOException e) {
logger.log(Level.SEVERE, "Console is unavailable.");
return;
}
}
private void insideOrder(Order newOrder) throws IOException {
if (newOrder.isEmpty()) return;
ConsoleHelper.writeMessage(newOrder.toString());
try {
queue.put(newOrder);
} catch (InterruptedException e) {
return;
}
try {
new AdvertisementManager(newOrder.getTotalCookingTime() * 60).processVideos();
} catch (NoVideoAvailableException e) {
StatisticEventManager.getInstance().register(new NoAvailableVideoEventDataRow(newOrder.getTotalCookingTime()*60));
logger.log(Level.INFO, "No video is available for the order " + newOrder);
}
}
public void createTestOrder() {
try {
final Order newOrder = new TestOrder(this);
insideOrder(newOrder);
} catch (IOException e) {
logger.log(Level.SEVERE, "Console is unavailable.");
}
}
public int getNumber() {
return number;
}
@Override
public String toString() {
return "Tablet{number=" + number + '}';
}
}
package com.javarush.test.level27.lesson15.big01.kitchen;
import com.javarush.test.level27.lesson15.big01.Tablet;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.concurrent.ThreadLocalRandom;
public class TestOrder extends Order {
public TestOrder(Tablet tablet) throws IOException {
super(tablet);
}
@Override
protected void initDishes() throws IOException {
dishes = new ArrayList<>();
dishes.addAll(Arrays.asList(Dish.values()));
int randDishCount = (int)(ThreadLocalRandom.current().nextDouble(1) * Dish.values().length) + 1;
int countOfDishToDelete = dishes.size() - randDishCount;
for (int i = 0; i < countOfDishToDelete; i++) {
dishes.remove((int)(ThreadLocalRandom.current().nextDouble(1) * dishes.size()));
}
}
}
package com.javarush.test.level27.lesson15.big01.statistic.event;
import com.javarush.test.level27.lesson15.big01.ad.Advertisement;
import java.util.Date;
import java.util.List;
public class VideoSelectedEventDataRow implements EventDataRow {
private List<Advertisement> optimalVideoSet;
private long amount;
private int totalDuration;
private Date currentDate;
public VideoSelectedEventDataRow(List<Advertisement> optimalVideoSet, long amount, int totalDuration) {
this.optimalVideoSet = optimalVideoSet;
this.amount = amount;
this.totalDuration = totalDuration;
currentDate = new Date();
}
@Override
public EventType getType() {
return EventType.SELECTED_VIDEOS;
}
@Override
public int getTime() {
return totalDuration;
}
@Override
public Date getDate() {
return currentDate;
}
public long getAmount() {
return amount;
}
}
package com.javarush.test.level27.lesson15.big01.kitchen;
import com.javarush.test.level27.lesson15.big01.ConsoleHelper;
import java.util.Observable;
import java.util.Observer;
public class Waiter implements Observer {
@Override
public void update(Observable cook, Object order) {
ConsoleHelper.writeMessage(order + " was cooked by " + cook);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment