Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Expand
titleDel 3 - Objektsamhandling (30 poeng)

Denne delen handler om samhandling mellom Table-klassen og en ny Kitchen-klasse.

Code Block
public class Table {
 
    ...
 
    /**
     * Sets the Kitchen that should be notified when items are added.
     * Note that this method may be called several times with different Kitchen objects.
     * @param kitchen
     */
    public void setKitchen(Kitchen kitchen) {
        ... what should be done here? ...
    }
 
    ...
}
 
/**
 * Interface for classes that want to know when Courses have been produced by a Kitchen.
 */
public interface KitchenListener {
    public void courseReady(Table table, Course course);
}
 
/**
 * Manages a queue of courses to produce, based on what is requested by Tables.
 */
public class Kitchen {
 
    // for each Table that has requested Courses,
    // there is a Collection of the thoseCourses that are yet to be made
    private Map<Table, Collection<Course>> courseQueue = new HashMap<Table, Collection<Course>>();
    
    /**
     * Enqueues a Course in the production queue, that is part of the provided Table.
     * @param table
     * @param course
     */
    private void produceCourse(Table table, Course course) {
        Collection<Course> courses = courseQueue.get(table);
        ... what should be done the first time a Table requests a Course? ...
        courses.add(course);
        courseQueue.put(table, courses);
    }
 
    /**
     * Internal methods that must be called when a Course of a Table has been produced.
     * Notifies registered listeners about the event.
     * @param table
     * @param course
     */
    private void courseProduced(Table table, Course course) {
        Collection<Course> courses = courseQueue.get(table);
        courses.remove(course);
        ... what should be done here, to support observers? ...
    }
 
    /**
     * Should be called when a MenuItem is added to a Table,
     * so the corresponding Courses can be produced.
     * @param table
     * @param item
     */
    public void menuItemAdded(Table table, MenuItem item) {
        ... handle cases when item is a Course or a Meal ...
    }
 
    //
    
    ... fields and methods for supporting observers ...
}
(10p) Oppgave a) Kobling fra Table til Kitchen

Bestilling av mat henger sammen med laging av mat, og nå skal det innføres en Kitchen-klasse (se utgitt kode), som har en dobbel kobling til Table-klassen. Denne deloppgaven handler om den første koblingen, nemlig at et Table-objekt skal kunne ha en kobling til ett Kitchen-objekt, som skal få beskjed når en ny rett (Course) eller et nytt måltid (Meal) legges til i lista over bestillinger. Tenk på det som en bestilling fra kelneren som betjener bordet til kjøkkenet om hvilke retter som skal lages.

Fullfør Table-klassen med det som trengs for å håndtere en kobling til Kitchen og gi beskjed til Kitchen-objektet om retter og måltider som bestilles.

Expand
titleLF

Vi trenger et felt for Kitchen og en setter (oppgitt i koden). Vi må også si fra til Kitchen-objektet om nye bestillinger i addItem-metoden.

Code Block
private Kitchen kitchen;


// setter
public void setKitchen(Kitchen kitchen) {
	... her kommer det mere siden ...
	this.kitchen = kitchen;
	... her kommer det mere siden ...
}

// må si fra til kjøkkenet (hvis satt) når noe bestilles
public void addItem(MenuItem item) {
	this.items.add(item);
	if (kitchen != null) {
		kitchen.menuItemAdded(this, item);
	}
}
(10p) Oppgave b) Kobling fra Kitchen til Table og andre klasser.

Table-objektene representerer bordene, og de må få beskjed når en rett er ferdiglaget av kjøkkenet. Derfor må Kitchen-klassen være kodet for å støtte en slik varsling. For å gjøre koden mer generell, så brukes observert-observatør-teknikken (se utgitt kode). Fullfør Kitchen-klassen, så den kan fungere som en observert og Table-klassen som observatør vha. KitchenListener-grensesnittet.

Expand
titleLF

 Dette er standard bruk av observatør-observert-teknikken, altså må en ha felt med liste av lyttere, metoder for å legge til og fjerne lyttere og helst en hjelpemetode for å varsle dem.

Code Block
public class Kitchen {
 
	...
 
	private Collection<KitchenListener> kitchenListeners = new ArrayList<KitchenListener>();

	public void addKitchenListener(KitchenListener listener) {
		kitchenListeners.add(listener);
	}

	public void removeKitchenListener(KitchenListener listener) {
		kitchenListeners.remove(listener);
	}

	private void fireCourseReady(Table table, Course course) {
		for (KitchenListener listener : kitchenListeners) {
			listener.courseReady(table, course);
		}
	}
}

Table må implementere lyttergrensesnittet og dermed også varslingsmetoden(e), og en må huske å registrere den når Kitchen-objektet settes. Dette kompliserer setteren, siden den både må avregistrere seg fra det forrige Kitchen-objektet og registrere seg på det nye.

Code Block
public class Table implements KitchenListener {
 
	...
 
	public void setKitchen(Kitchen kitchen) {
		if (this.kitchen != null) {
			this.kitchen.removeKitchenListener(this);
		}
		this.kitchen = kitchen;
		if (this.kitchen != null) {
			this.kitchen.addKitchenListener(this);
		}		
	}
 
	@Override
	public void courseReady(Table table, Course course) {
		// reaksjon på varslingen
	}
}
(10p) Oppgave c) Kitchen sin Course-kø

Kitchen-klassen (se utgitt kode) håndterer en kø av retter, organisert etter hvilket bord (Table) som har bestilt den. Logikken er bare delvis implementert, fullfør koden for metodene produceCourse, courseProduced og menuItemAdded så køen håndteres riktig, ved å fylle inn der det er angitt med ...

Expand
titleLF
Code Block
private void produceCourse(Table table, Course course) {
	Collection<Course> courses = courseQueue.get(table);
	if (courses == null) {
		courses = new ArrayList<Course>();
		courseQueue.put(table, courses);
	}
	courses.add(course);
}

private void courseProduced(Table table, Course course) {
	Collection<Course> courses = courseQueue.get(table);
	if (courses != null) {
		courses.remove(course);
		fireCourseReady(table, course);
	}
}

public void menuItemAdded(Table table, MenuItem item) {
	if (item instanceof Course) {
		produceCourse(table, (Course) item);
	} else if (item instanceof Meal) {
		for (Course course : (Meal) item) {
			produceCourse(table, course);
		}			
	}
}

Koden finnes på github, se del 3 av konten 2017

 

...