1 / 59

Principles of Object-Oriented Software Development

Principles of Object-Oriented Software Development. Application Development. Application Development. Introduction The drawtool application Guidelines for design From specification to implementation Summary Q/A Literature. Application Development.

Télécharger la présentation

Principles of Object-Oriented Software Development

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Principles of Object-Oriented Software Development Application Development

  2. Application Development Introduction The drawtool application Guidelines for design From specification to implementation Summary Q/A Literature

  3. Application Development • the drawtool applications • guidelines for design • from specification to implementation Additional keywords and phrases: hush framework, interactive editors, law of Demeter, formal specification in Z, abstract systems

  4. The drawtool application Subsections: A simple drawing canvas in hush The drawtool application

  5. A simple drawing canvas in hush The hush class hierarchy

  6. Drawing canvas

  7. public interface widget { widget public String path(); public void eval(String cmd); public void pack(String s); public void bind(handler h,String s); public void bind(String p, handler h,String s); public void configure(String cmd); public void geometry(int x, int y); public void xscroll(widget w); public void yscroll(widget w); public widget self(); to define compound widgets public void redirect(widget inner); };

  8. import hush.dv.api.event; import hush.dv.widgets.canvas; class draw extends canvas { draw go.java boolean dragging; public draw(String path) { super(path); dragging = false; bind(this); } public void press(event ev) { dragging = true; } public void release(event ev) { dragging = false; } public void motion(event ev) { if (dragging) circle(ev.x(),ev.y(),2,"-fill black"); } };

  9. Drawing canvas

  10. The drawtool application

  11. A (partial) class diagram

  12. path ::= '.' | '.'string | path'.'string Widget containment

  13. An interaction diagram

  14. import hush.dv.api.*; import hush.dv.widgets.frame; public class toolbox extends frame { toolbox tablet tablet; public toolbox(widget w, tablet t) { super(w,"toolbox"); tablet = t; new toolbutton(this,"draw"); new toolbutton(this,"move"); new toolbutton(this,"box"); new toolbutton(this,"circle"); new toolbutton(this,"arrow"); } public int operator() { tablet.mode(_event.arg(1)); reset tablet mode return OK; } };

  15. import hush.dv.api.*; import hush.dv.widgets.button; public class toolbutton extends button { toolbutton public toolbutton(widget w, String name) { super(w,name); text(name); bind(w,name); pack("-side top -fill both -expand 1"); } };

  16. import hush.dv.api.widget; public class menubar extends hush.dv.widgets.menubar { menubar public menubar(widget w, tablet t, toolbox b) { super(w,"bar"); configure("-relief sunken"); new FileMenu(this,t); new EditMenu(this,b); new HelpButton(this); } };

  17. Tablet

  18. import hush.dv.api.*; import hush.dv.widgets.*; public class tablet extends canvas { tablet int _mode; canvas canvas; handler[] handlers; final int DRAW = 0; final int MOVE = 1; final int CIRCLE = 2; final int BOX = 3; final int ARROW = 5;

  19. public tablet(widget w, String name, String options) { super(w,name,"*"); handlers = new handler[12]; init(options); redirect(canvas); // to delegate to canvas bind(this); // to intercept user actions handlers[DRAW] = new DrawHandler(canvas); handlers[MOVE] = new MoveHandler(canvas); handlers[BOX] = new BoxHandler(canvas); handlers[CIRCLE] = new CircleHandler(canvas); handlers[ARROW] = new ArrowHandler(canvas); _mode = 0; // drawmode.draw; }

  20. public int operator() { handlers[_mode].dispatch(_event); return OK; } public int mode(String s) { int m = -1; if ("draw".equals(s)) m = DRAW; if ("move".equals(s)) m = MOVE; if ("box".equals(s)) m = BOX; if ("circle".equals(s)) m = CIRCLE; if ("arrow".equals(s)) m = ARROW; if (m >= 0) _mode = m; return _mode; }

  21. void init(String options) { widget root = new frame(path(),"-class tablet"); canvas = new canvas(root,"canvas",options); canvas.configure("-relief sunken -background white"); canvas.geometry(200,100); scrollbar scrollx = new Scrollbar(root,"scrollx"); scrollx.orient("horizontal"); scrollx.pack("-side bottom -fill x -expand 0"); scrollbar scrolly = new Scrollbar(root,"scrolly"); scrolly.orient("vertical"); scrolly.pack("-side right -fill y -expand 0"); canvas.pack("-side top -fill both -expand 1"); canvas.xscroll(scrollx); scrollx.xview(canvas); canvas.yscroll(scrolly); scrolly.yview(canvas); }

  22. import hush.dv.api.*; import hush.dv.widgets.frame; import hush.dv.widgets.canvas; public class drawtool extends canvas { drawtool widget root; tablet tablet; public drawtool() { System.out.println("meta handler created"); } public drawtool(String p, String options) { super(p,"*"); // create empty tablet init(options); }

  23. public int operator() { System.out.println("Calling drawtool:" + _event.args(0) ); String[] argv = _event.argv(); if ("self".equals(argv[1])) tk.result(self().path()); else if ("drawtool".equals(argv[0])) create(argv[1],_event.args(2)); else if ("path".equals(argv[1])) tk.result(path()); else if ("pack".equals(argv[1])) pack(_event.args(2)); else self().eval( _event.args(1) ); // send through return OK; } void create(String name, String options) { drawtool m = new drawtool(name,options); }

  24. void init(String options) { root = new frame(path(),"-class Meta"); frame frame = new frame(root,"frame"); tablet = new tablet(frame,"tablet",options); toolbox toolbox = new toolbox(frame,tablet); menubar menubar = new menubar(root,tablet,toolbox); toolbox.pack("-side left -fill y -expand 0"); tablet.pack("-side left -fill both -expand 1"); menubar.pack(); frame.pack("-expand 1 -fill both"); redirect( tablet ); // the widget of interest } };

  25. Canvas c = new DrawTool("draw",""); tk.bind("drawtool",c); c.circle(20,20,20,"-fill red"); c.rectangle(30,30,70,70,"-fill blue"); c.pack(); The drawtool application

  26. Guidelines for design Subsections: Individual class design Establishing invariants An objective sense of style

  27. Development process cognitive factors • model -> realize -> refine

  28. Design criteria natural, flexible, reusable • abstraction -- types • modularity -- strong cohesion (class) • structure -- subtyping • information hiding -- narrow interfaces • complexity -- weak coupling

  29. Individual class design

  30. Class design guidelines • only methods public -- information hiding • do not expose implementation details • public members available to all classes -- strong cohesion • as few dependencies as possible -- weak coupling • explicit information passing • root class should be abstract model -- abstraction

  31. Inheritance and invariance

  32. Invariant properties -- algebraic laws class employee { employee public: employee( int n = 0 ) : sal(n) { } employee* salary(int n) { sal = n; return this; } virtual long salary() { return sal; } protected: int sal; }; Invariant k == (e->salary(k))->salary()

  33. Problem -- hidden bonus class manager : public employee { manager public: long salary() { return sal + 1000; } }; Invariant k =?= (m->salary(k))->salary() Violating the invariant

  34. Solution -- explicit bonus class manager : public employee { manager' public: manager* bonus(int n) { sal += n; return this; } }; Invariant -- restored k + n == ((m->salary(k))->bonus(n))->salary() Restoring the invariant

  35. An objective sense of style

  36. Good Object-Oriented Design organize and reduce dependencies between classes Client -- A method m is a client of C if m calls a method of C Supplier -- If m is a client of C then C is a supplier of m Acquaintance -- C is an acquaintance of m if C is a supplier of m but not (the type of) an argument of m or (of) an instance variable of the object of m [] C is a preferred acquaintance of m if an object of C is created in m or C is the type of a global variable [] C is a preferred supplier of m if C is a supplier and C is (the type of) an instance variable, an argument or a preferred acquaintance

  37. Law of Demeter Do not refer to a class C in a method m unless C is (the type of) 1. an instance variable 2. an argument of m 3. an object created in m 4. a global variable ignorance is bliss Minimize the number of acquaintances!

  38. From specification to implementation Subsections: Structure versus behavior Model-based specification Abstract systems

  39. Structural versus behavioralencapsulation Semantic modeling -- constructing types aggregation, grouping by association

  40. Object-oriented modeling • is-a -- inheritance • has-a, uses -- delegation • uses -- templates

  41. Model-based specification

  42. State and operations Change and invariance Verification Model-based specification

  43. State The specification of a Counter in Z

  44. Z Counter Bounded counter

  45. The specification of a Library State

  46. Operations

  47. Abstract systems and events Abstract systems -- design methodology abstract system = abstract data types + protocol Events -- high level glue realization of the interaction protocol

  48. library Exemplary interface p = new person(); b = new book(); p = b->borrower; s = p->books; tf = b->inlibrary(); b->borrow(p); p->allocate(b); p->deallocate(b); b->_return(p); For person* p; book* b; set<book>* s; bool tf;

  49. class book { book public: person* borrower; book() {} void borrow( person* p ) { borrower = p; } void _return( person* p ) { borrower = 0; } bool inlibrary() { return !borrower; } }; class person { person public: person() { books = new set(); } void allocate( book* b ) { books->insert(b); } void deallocate( book* b ) { books->remove(b); } set* books; };

More Related