Objektorienterad modellering och design (EDAF5) Föreläsning Återstår av kursen Agenda Projekt XL UML Tillståndsdiagram Designmönster (State pattern) Grafer Nätverk Ford Fulkersons algoritm Labb 5 redovisas på fredag :e maj XL-projekt Redovisning :e maj och 7:e maj Sem 3 tisdag 5:e maj F9 (Repetition och övning inför tentan) ti maj Tenta on 3:e maj EDAF5 (F) VT / 9 Repetition Model/VIew/Control-arkitektur EDAF5 (F) VT / 9 Projekt XL Klassen Gui JFrame ger ett eget fönster på skärmen. View Visar modellens tillstånd Berättar om förändringen Användare Efterfrågar en förändring Förändrar modellens tillstånd Controller import javax.swing.jframe; import java.awt.borderlayout; public class Gui extends JFrame { public Gui(int count) { super("untitled-" + count); setlayout(new BorderLayout()); // omissions pack(); setvisible(true); Model EDAF5 (F) VT 3 / 9 EDAF5 (F) VT / 9
Projekt XL BorderLayout Projekt XL Layout EDAF5 (F) VT 5 / 9 Projekt XL Layout Status area: EDAF5 (F) VT / 9 Projekt XL Editor JTextField används för textinmatning. public class Editor extends JTextField implements ActionListener { public Editor() { setbackground(color.white); addactionlistener(this); public void actionperformed(actionevent event) { // activated by Return key // contents returned by gettext() EDAF5 (F) VT 7 / 9 EDAF5 (F) VT / 9
Projekt XL WindowMenu Projekt XL WindowMenuItem class WindowMenuItem extends JMenuItem implements ActionListener { private XL xl; public WindowMenuItem(XL xl) { super(xl.gettitle()); this.xl = xl; addactionlistener(this); public void actionperformed(actionevent event) { xl.tofront(); EDAF5 (F) VT 9 / 9 Projekt XL JMenu EDAF5 (F) VT / 9 Projekt XL GuiList public class WindowMenu extends JMenu implements Observer { private XLList xllist; public WindowMenu(XLList xllist) { super("window"); this.xllist = xllist; xllist.addobserver(this); update(null, null); public void update(observable observable, Object object) { removeall(); for (XL xl : xllist) { add(new WindowMenuItem(xl)); public class XLList extends Observable implements Iterable<XL> { private List<XL> list = new ArrayList<XL>(); public void add(xl xl) { list.add(xl); setchanged(); notifyobservers(); public boolean isempty() { return list.isempty(); public Iterator<XL> iterator() { return list.iterator(); EDAF5 (F) VT / 9 EDAF5 (F) VT / 9
Projekt XL MouseListener Projekt XL MouseAdapter Några swing-komponenter kan ha en ActionListener, t ex: JButton, JMenuItem, JTextField. Alla komponenter kan ha en MouseListener. Den läggs till med: public void addmouselistener(mouselistener listener); public interface MouseListener { void mouseclicked(mouseevent event); void mouseentered(mouseevent event); void mouseexited(mouseevent event); void mousepressed(mouseevent event); void mousereleased(mouseevent event); I regel vill man bara reagera på en av händelserna. Då är det bekvämt med: public abstract class MouseAdapter { public void mouseclicked(mouseevent event){ public void mouseentered(mouseevent event){ public void mouseexited(mouseevent event){ public void mousepressed(mouseevent event){ public void mousereleased(mouseevent event){ EDAF5 (F) VT 3 / 9 Projekt XL MouseListenerLabel EDAF5 (F) VT / 9 Felhantering public class MouseListenerLabel extends JLabel { private class ClickListener extends MouseAdapter { public void mouseclicked(mouseevent event) { setbackground(color.yellow); public MouseListenerLabel() { setbackground(color.white); addmouselistener(new ClickListener()); EDAF5 (F) VT 5 / 9 EDAF5 (F) VT / 9
Felhantering Feldetektering public class XLException extends RuntimeException { public XLException(String message) { super(message); class Div extends BinaryExpr { Div(Expr expr, Expr expr) { super(expr, expr); precedence = ; precedence = ; public double op(double op, double op) { if (op!= ) return op / op; else throw new XLException("division by zero"); EDAF5 (F) VT 7 / 9 Syntaxanalys EDAF5 (F) VT / 9 Syntaxanalys Syntax för aritmetiska uttryck: Ett uttryck består av en eller flera termer separerade av enkla pluseller minus-tecken. En term består i sin tur av en eller flera faktorer separerade av enkla multiplikations- eller divisionstecken. En faktor är ett tal, en variabel eller ett uttryck inom parenteser. Ett tal består av en eller flera siffror och får inledas med ett minustecken. En variabel består av en eller flera bokstäver bland a z. Konkret grammatik BNF: Expr ::= term (addop term)* Term ::= factor (mulop factor)* Factor ::= number name ( expr ) Addop::= + - Mulop ::= * / number ::= unsignednumber - unsignednumber unsignednumber ::= digit (digit)* digit ::= 3 5 7 9 name ::= letter (letter)* letter ::= a b... z EDAF5 (F) VT 9 / 9 EDAF5 (F) VT / 9
Syntaxanalys Syntaxanalys Abstrakt representation abstrakt grammatik «interface» Expr Variable Int BinOp Add Sub Mul Java.io.StreamTokenizer: public class StreamTokenizer { public double nval; public String sval; public int ttype = -; public static final int TT_EOF = -, TT_EOL =, TT_NUMBER = -, TT_WORD = -3 public StreamTokenizer(Reader r) public int nexttoken() throws IOException public void ordinarychar(int ch) \\ omissions EDAF5 (F) VT / 9 Syntaxanalys EDAF5 (F) VT / 9 Syntaxanalys Java.io.StreamTokenizer: public class ExprParser { private int token; private StreamTokenizer tokenizer; public Expr build(reader reader) throws IOException { tokenizer = new StreamTokenizer(reader); tokenizer.ordinarychar( - ); tokenizer.ordinarychar( / ); token = tokenizer.nexttoken(); Expr e = expr(); if (token == StreamTokenizer.TT_EOF) return e; else throw new XLException("trailing garbage"); Analys av faktorer: private Expr factor() { Expr e; switch (token) { case ( : token = nexttoken(); e = expr(); token = nexttoken(); return e; case TT NUMBER: double x = nval; token = nexttoken(); return new Num(x); case TT WORD: String s = sval; token = nexttoken(); return new Variable(s); EDAF5 (F) VT 3 / 9 EDAF5 (F) VT / 9
Syntaxanalys UML Tillståndsdiagram Analys av termer: private Expr term() { Expr result, factor; result = factor(); while (token == * token == / ) { int op = token; token = nexttoken(); factor = factor(); switch (op) { case * : result = new Mul(result, factor); break; case / : result = new Div(result, factor); break; return result; Sleep EDAF5 (F) VT 5 / 9 UML Tillståndsdiagram EDAF5 (F) VT / 9 Designmönster Implementering av tillståndsmaskin final static int DISPLAY = ; final static int SET_HOURS = ; final static int SET_MINUTES = ; int state = DISPLAY; change mode increment display EDAF5 (F) VT 7 / 9 EDAF5 (F) VT / 9
Designmönster Implementering av tillståndsmaskin Designmönster Tillståndsmönstret (State pattern) final static int DISPLAY = ; final static int SET_HOURS = ; final static int SET_MINUTES = ; int state = DISPLAY; public void changemode() { if (state == DISPLAY) { state = SET_HOURS; displayhours(); else if (state == SET_HOURS) { state = SET_MINUTES; displayminutes(); else if (state == SET_MINUTES) { state = DISPLAY; displaytime(); change mode increment display State pattern... Definiera ett tillståndsinterface som innehåller en metod för varje åtgärd i den digitala klockan Implementera en klass för varje tillstånd i tillståndsdiagrammet. 3 Skippa all villkorad kod och delegera till tillståndsklassen att göra arbetet. EDAF5 (F) VT 9 / 9 Designmönster Tillståndsmönstret (State pattern) EDAF5 (F) VT 3 / 9 Designpatterns State pattern public class SetHourState implements DigitalClockState { DigitalClock digitalclock; public SetHourState(DigitalClock digitalclock) { this.digitalclock = digitalclock; public void changemode() { digitalclock.displayhours(); digitalclock.setstate(digitalclock.getsetminutesstate()); public void increment(){ digitalclock.incrementhours(); public class digitalclock{ DigitalClockState displaystate; DigitalClockState sethoursstate; DigitalClockState setminutesstate; DigitalClockState state; Time time; public DigitalClock(Time time){ displaystate = new DisplayState(this); sethoursstate = new SetHoursState(this); setminutesstate = new SetMinutesState(this); state = displaystate; this.time = time; public void changemode(){ state.changemode(); public void increment(){ state.increment(); and more... EDAF5 (F) VT 3 / 9 EDAF5 (F) VT 3 / 9
Designpatterns State pattern Grafer Flödesnätverk Context + request() * «interface» State + handle() 3 state.handle() StateA StateB Source 3 Sink Grafer Flödesnätverk EDAF5 (F) VT 33 / 9 Grafer Flödesnätverk EDAF5 (F) VT 3 / 9 Flöde Flödet via en båge kan inte överstiga dess kapacitet. Alla noder utom källan och sänkan har lika stort inflöde som utflöde. Flödesnätverk Ett flödesnätverk är en riktad graf där varje båge har en kapacitet och kan ta emot ett flöde. En nod i nätverket är en källa d.v.s. har bara utgående bågar. En nod i nätverket är en sänka d.v.s. har bara inkommande bågar. / 3/3 / Source / /3 Sink / EDAF5 (F) VT 35 / 9 EDAF5 (F) VT 3 / 9
Flödesnätverk Flödesnätverk : Sök ett flöde med maximalt värde. : Sök ett flöde med maximalt värde. / / / / / /9 f= / / / Girig algoritm: Sätt flödet = för alla bågar Sök en väg p där varje båge har en resterande kapacitet större än flödet f Öka med flödet f längs vägen p Upprepa tills du inte hittar fler sådana vägar EDAF5 (F) VT 37 / 9 Girig algoritm EDAF5 (F) VT 3 / 9 Girig algoritm / f= / f=++ / / / / / / / / / / / /9 / / /9 / / f=+ / f=+++ / / +/ / / / / / / / / /9 / / +/9 +/ EDAF5 (F) VT 39 / 9 EDAF5 (F) VT / 9
Girig algoritm Den giriga algoritmen hittar inte maximalt flöde / / / / / /9 totalt flöde = / / / Vi definierar en ny graf som hjälper oss att hålla reda på möjligheten att ändra flödet. Residualgraf Givet grafen G med ett flöde f definierar vi residualgrafen Gf så att: Gf har samma noder som G. Vi behöver en bättre algoritm Alla bågar som finns i G finns även i Gf. Kapaciteten för en båge i Gf motsvarar resterande kapacitet för motsvarande båge i G. / / 3/ 7/ / 9/ maximalt flöde = 9 För alla bågar i G som har ett flöde fe större än noll finns också motsvarande bågar i omvänd riktning i Gf. Kapaciteten för dessa bågar är lika stort som fe. 9/ 9/9 / EDAF5 (F) VT / 9 EDAF5 (F) VT / 9 Utökande väg EDAF5 (F) VT 3 / 9 EDAF5 (F) VT / 9
Sätt startflödet till för alla bågar. Sök en utökande väg i residualgrafen. Utöka flödet längs den vägen. Upprepa tills det inte går att hitta en utökande väg. + / +/ +/ / -/ /9 totalt flöde = + +/ / / - + - + - - + EDAF5 (F) VT 5 / 9 EDAF5 (F) VT / 9 Flöde och snitt +/ totalt flöde = +=9 Flödet är lika stort i varje snitt i grafen. Ett flöde är maximalt om det inte finns någon utökande väg. Värdet av ett maximalt flöde = Kapaciteten för det minsta snittet. / +/ / -/ / +/ +/9 / EDAF5 (F) VT 7 / 9 EDAF5 (F) VT / 9
Flöde och snitt Uppgift.3 (Modellering, state pattern) Uppgift.5 (PA-frågor mönster) EDAF5 (F) VT 9 / 9