280 likes | 365 Views
Topics in OO, Design Patterns, Reasoning About Program Behavior ... (part 1). Neelam Soundarajan Computer Sc. & Eng. e-mail: neelam@cse. Job Shop Simulation. class Active { private: Active* next; public: void setNext(Active* p) { next = p; } Active* getNext() {return next; }
E N D
Topics in OO, Design Patterns, Reasoning About Program Behavior ...(part 1) Neelam Soundarajan Computer Sc. & Eng. e-mail: neelam@cse
Job Shop Simulation class Active { private: Active* next; public: void setNext(Active* p) { next = p; } Active* getNext() {return next; } virtual void event() = 0; // tells a machine: time to break! // tells an adjuster: you are done fixing this machine! }
Job Shop Simulation (contd.) class Machine: public Active { private: Scheduler* sp; Manager* mp; Boolean isUp; int totUpTime; int upTimeStart; public: Machine( Scheuler* s, Manager* m); virtual void event(); // tells a machine: time to break! void adjusted(); int upTime(); }
Job Shop Simulation (contd.) Machine: Machine(Scheduler* s, Manager* m) { sp = s; mp = m; totUpTime = 0; isUp = true; upTimeStart = sp→time(); sp→Schedule(this, (rand()%20 + 1)); } Machine :: event() { // Break! isUp = false; totUpTime += sp→time() - upTimeStart; mp→requestService(this); }
Job Shop Simulation (contd.) void Machine :: adjusted() { // Fixed, run! isUp = true; upTimeStart = sp→time(); sp→Schedule(this, (rand()%20 + 1)); } int Machine :: upTime() { // stats int t = totUpTime; if (isUp) t += sp→time() - upTimeStart; return (t); }
Job Shop Simulation (contd.) class Adjuster: public Active { private: Scheduler* sp; Manager* mp; Boolean isBusy; int totBusyTime; int busyTimeStart; public: Adjuster( Scheuler* s, Manager* m); virtual void event(); // tells adjuster: you are done with this machine! void adjust(Machine* m); int busyTime(); }
Job Shop Simulation (contd.) Adjuster: Adjuster(Scheduler* s, Manager* m) { sp = s; mp = m; totBusyTime = 0; isBusy = false; workp = mp→ requestWork(this); if (!workp) { isBusy = true; busyTimeStart = sp→time(); sp→Schedule(this, (rand()%45 + 1)); }
Job Shop Simulation (contd.) void Adjuster :: event() { //Done fixing current machine totBusyTime += sp→time() - upTimeStart; workp→adjusted(); isBusy = false; workp = mp→requestWork(this); if (!workp) { isBusy = true; busyTimeStart = sp→time(); sp→Schedule(this, (rand()%45 + 1)); }
Job Shop Simulation (contd.) void Adjuster:: adjust(Machine* m) { // Fix this! workp = m; isBusy = true; busyTimeStart = sp→time(); sp→Schedule(this, (rand()%45 + 1)); } int Adjuster :: busyTime() { // stats int t = totBusyTime; if (isBusy) t += sp→time() - busyTimeStart; return (t); }
Job Shop Simulation (contd.) enum Who {Machines, Adjusters, None}; class Manager { private: Who waiting; Active* first; Active* last; void insertFirst(Active* p) {first=last=p; p→setNext(0); } void insert(Active* p) { last→setNext(p); p→setNext(0); last=p; } void remove() {first=first→getNext(); } public: Manager() {first = last = 0; waiting = None;} void requestService( Machine* p); void requestWork(Adjuster* p); }
Job Shop Simulation (contd.) void Manager:: requestService(Machine* m) { Adjuster* q; switch(waiting) { case Machines: Insert(p); return; case Adjusters: q = (Adjuster*) first; remove(); if (first==0) waiting=None; q→Adjust(p); return; case None: waiting=Machines; InsertFirst(p); return; }
Job Shop Simulation (contd.) Machine* Manager:: requestWork(Adjuster* p) { Machine* q; switch(waiting) { case Adjusters: Insert(p); return 0; case Machines: q = (Machine*) first; remove(); if (first==0) waiting=None; return q; case None: waiting=Adjusters; InsertFirst(p); return 0; }
Job Shop Simulation (contd.) class Scheduler{ private: int clock; int calendarSize; active** calendar; int index; public: Scheduler( int sz ); int time() { return clock; } void schedule( active* p, int delay ); void run( int ticks ); }
Job Shop Simulation (contd.) Scheduler:: Scheduler(int sz) { clock = 0; calendarSize = sz; calendar = new Active*[sz]; for (int i=0; i < sz; i++ ) calendar[i] = 0; index=0; } void Scheduler:: schedule(Active* p, int delay) { // Add p to the right place in the calendar; }
Job Shop Simulation (contd.) void Scheduler:: run( int ticks ) { // the slave driver! Active* p; for (int i=0; i <ticks; i++ ) { while ( (p=calendar[index]) != 0 ) { calendar[index]=p→getNext(); p→Event(); } clock++; index++; if ( index==calendarSize ) index = 0; } }
Job Shop Simulation (contd.) // Main program Manager mngr; Scheduler sch( 50 ); // big enough calendar? Machine** mList = new Machine*[10]; for (i=0; i<10; i++) mList[i] = new Machine( &sch, &mngr); Adjuster** aList = new Adjuster*[20]; for (i=0; i<20; i++) aList[i] = new Adjuster( &sch, &mngr);
Job Shop Simulation (contd.) // Main program contd. sch.run(10000); // get stats from mList→upTime() // and from aList→busyTime() // ...
Types etc. A key question: What is a type? • Original answer: Same as how values are represented; • Better: Focus on what you can do with values of the type; For a client, the operations are what matter. For an implementer, both matter.
Types (contd.) Sometimes you have two or more “types” that are so closely related, most of the time you want to consider them to be the same type. Example: Simple class of arithmetic expressions: <exp> ::= <intExp> | <sumExp> | <prodExp> | ... <intExp> ::= ... <sumExp> ::= <exp> + <exp> <prodExp> ::= <exp> * <exp> ...
Types (contd.) So we think of SumExp, ProdExp, IntExp as subtypes of Exp. class Exp { public: virtual int value() = 0; };
Types (contd.) class SumExp: public Exp { private: Exp* e1, e2; public: int value() { return (e1->value() + e2->value()) ; } }; class ProdExp: public Exp { private: Exp* e1, e2; public: int value() { return (e1->value() * e2->value()) ; } }; class IntExp: public Exp { private: int v; public: int value() { return v; } };
Types (contd.) Important reasoning-related questions: • How do we specify the base type/class? • How do we specify the derived types/classes? • What relations, if any, must hold between these? • ... • In practical systems, we may have circular refs; complications due to such things?
OO Frameworks • Based on discussion in Mastering OO Design, Horstmann(Horstmann presents a couple of other frameworks as well) • An OO framework: • Collection of classes that serve as basis of derivation of a full system; • Non-virtual functions impose an execution order; • Capture the general outline of the class structure and control-flow for that problem domain.
Diagram Editor Framework • A diagram consists of nodes and edges; • Editor provides control buttons used various actions; • Mouse used for drawing and activating buttons;
Move Exit Diagram Editor Framework (contd.) Erase
Diagram Editor Framework (contd.) • If current button is node: clicking places a new nodeat that point; • If current button is edge: dragging from one node to another joins the two by an edge; at that point; • If Move is active: dragging a node moves it; edges are redrawn; • If Erase is active: clicking on edge erases it; on node, erases it and all its edges; • No labels, scrolling, cut-and-paste etc; but these can be added.
Diagram Editor Framework (contd.) • Division of responsibility: • Rendering nodes/edges: Application; • Hit testing: Application; • Drawing icons: Application (but the column drawn by framework).
Reasoning Questions (For implementation of Diagram Editor framework: see Horstmann’s book.) (Maybe consider this a bit later?) • How do we specify the Framework? • What are the conditions to be imposed on the Application implementers? • How do we specify the Application portion? • How do we combine the two to arrive at the behavior of the Application?