320 likes | 470 Views
Object-Oriented Software Construction. Bertrand Meyer. Lecture 19: Agents and event-driven design. Agenda for today. Scope of this development Applications The mechanism. Scope. Starting from an object-oriented basis, add a new kind of objects representing potential computations.
E N D
Object-Oriented Software Construction Bertrand Meyer OOSC - Summer Semester 2004
Lecture 19: Agents and event-driven design OOSC - Summer Semester 2004
Agenda for today • Scope of this development • Applications • The mechanism OOSC - Summer Semester 2004
Scope • Starting from an object-oriented basis, add a new kind of objects representing potential computations. • Such objects are called “agents”. • Earlier names: • Delayed calls • Routine objects • Similar to: • “Closures” • Delegates (C#) • Blocks (Smalltalk) • Lambda expressions OOSC - Summer Semester 2004
Compare to… • ... “Functional” style of programming, e.g. Haskell • Conjecture: Haskell should be an Eiffel library (Eifskell?) OOSC - Summer Semester 2004
Traditional input scheme from open_file until end_of_file loop read_next process (last_item) end OOSC - Summer Semester 2004
The starting idea of object-technology • Organize software architecture around data types. • Agents: Can an object represent an action? Action Object Processor OOSC - Summer Semester 2004
Event-driven programming PUBLISHERS SUBSCRIBERS trigger events handle events ROUTINE EVENTS ROUTINE ROUTINE OOSC - Summer Semester 2004
Applications of agents • Iteration • High-level contracts • Numerical programming • Introspection • High-level functionals, type-safe OOSC - Summer Semester 2004
Integration example (1) b my_function (x) dx a my_integrator.integral (agentmy_function, a, b) OOSC - Summer Semester 2004
Integration example (2) b your_function (x, u, v) dx a my_integrator.integral (agentyour_function (?, u, v), a, b) • In the first example (one argument), the notation agentmy_function • is a synonym for agentmy_function (?) OOSC - Summer Semester 2004
Open and closed arguments agentyour_function (?, u, v) • Closed: set at the time of the agent’s definition • Open: set at the time of any call to the agent Open Closed OOSC - Summer Semester 2004
Using a routine from another class agentsome_object.some_routine (?, u, v) Target OOSC - Summer Semester 2004
Iteration • Consider my_integer_list: LIST [INTEGER] • in a class C that has the functionis_positive (x: INTEGER): BOOLEANis-- Is x positive?doResult := (x > 0)end • To test that all integers in a list are positive: all_positive := my_integer_list.for_all (agentis_positive) OOSC - Summer Semester 2004
Iteration (cont’d) • Consider my_employee_list: LIST [EMPLOYEE] • where class EMPLOYEE has the featureis_married: BOOLEAN-- Does this object represent a -- married employee? • To test that all employees in a list are married: all_married := my_employee_list.for_all (agent {EMPLOYEE}.is_married) OOSC - Summer Semester 2004
Target or argument open • Compare the two examples (both in a class C): my_integer_list: LIST [INTEGER]my_employee_list: LIST [EMPLOYEE] is_positive (x: INTEGER): BOOLEAN-- In class Cis_married: BOOLEAN-- In class EMPLOYEE -- Abbreviated as -- my_integer_list.for_all (agent is_positive):my_integer_list.for_all (agentis_positive (?)) my_employee_list.for_all (agent {EMPLOYEE}.is_married) Open OOSC - Summer Semester 2004
An EiffelBase contract (class HASH_TABLE) extend (new: G; key: H) -- Assuming there is no item of key key, -- insert new with key; set inserted. require not_key_present: nothas (key) ensure insertion_done: item (key) = new key_present: has (key) inserted: inserted one_more: count = oldcount + 1 OOSC - Summer Semester 2004
Agents’ potential for contracts • Express general properties such as “none of the elements from positions 1 to count – 1 have been changed”. OOSC - Summer Semester 2004
Event-driven programming PUBLISHERS SUBSCRIBERS trigger events handle events ROUTINE EVENTS ROUTINE ROUTINE OOSC - Summer Semester 2004
Event Library • Class EVENT_TYPE • Publisher side, e.g. GUI library: • (Once) declare event type: click: EVENT_TYPE [TUPLE [INTEGER, INTEGER]] • (Once) create event type object: createclick • Each time the event occurs: click.publish ([x_coordinate, y_coordinate]) • Subscriber side: click.subscribe (agentmy_procedure) OOSC - Summer Semester 2004
Subscriber variants click.subscribe (agentmy_procedure) my_button.click.subscribe (agentmy_procedure) click.subscribe (agentyour_procedure (a, ?, ?, b)) click.subscribe(agentother_object.other_procedure) OOSC - Summer Semester 2004
EiffelVision style my_button.click.action_list.extend (agentmy_procedure) OOSC - Summer Semester 2004
* * SUBSCRIBER PUBLISHER LIBCLASS APPCLASS Observer pattern (C++, Java) update* attach detach update+ * Deferred (abstract) Inherits from + Effective (implemented) Client (uses) OOSC - Summer Semester 2004
Observer pattern • Publishers know about subscribers • Subscriber may subscribe to at most one publisher • May subscribe at most one operation • Not reusable — must be coded anew for each application OOSC - Summer Semester 2004
Event library • Publisher, e.g. GUI library: • Declare and create: click: EVENT_TYPE [TUPLE [INTEGER, INTEGER]] • Trigger each event with arguments.click.publish ([x, y]) • Subscriber (to subscribe a routine r): my_button.click.subscribe (agentr) OOSC - Summer Semester 2004
.NET event-delegate mechanism • Publisher or subscriber: • Introduce descendant ClickArgs of EventArgs repeating types of arguments of myProcedure. (Adds a class.) public classClickArgs { int x, y;... } • Declare delegate type ClickDelegate based on that class. (Adds a type.) publicvoiddelegateClickDelegate (Object sender,ClickArgse); D1 D2 OOSC - Summer Semester 2004
.NET delegates (2): publisher • Declare new event type Click based on the type ClickDelegate. (Adds a type.) public eventClickDelegate Click; • Write procedure OnClick to wrap handling. (Adds a routine.) protectedvoidOnClick (ClickArgs e) { if (Click != null) Click (this, e); } • For every event occurrence, create instance of ClickArgs, passing arg values to constructor. (Adds a run-time object.) ClickArgsmyClickArgs = newClickArgs (h, v); • For every occurrence, trigger event OnClick (myClickArgs); D3 D4 D5 D6 OOSC - Summer Semester 2004
.NET delegates (3): subscriber • To subscribe a routine myProcedure: • Declare a delegate myDelegate of type ClickDelegate. (Can be combined with following step as shown next.) • Instantiate it with myProcedure as constructor’s argument. ClickDelegatemyDelegate= newClickDelegate(myProcedure) • Add it to the delegate list for the event. yourButton.Click += myDelegate D7 D8 D9 OOSC - Summer Semester 2004
.NET delegates (4) • event is a keyword of the language (special features of a class). But event types should be treated as ordinary objects. • Cannot have closed arguments: for equivalent of r (a, ?, ?, b) must write routine wrapper to be used for delegate. • Cannot have open target: for equivalent of {TYPE}.r (...) must write routine wrapper. OOSC - Summer Semester 2004
Lessons • Avoid magic: what’s available to the language designer should be available to the programmer • Role of language mechanisms: genericity, constrained genericity, tuples • Importance of choosing the right abstractions • Observer Pattern: PUBLISHER, SUBSCRIBER • .NET: event, delegate, event type, delegate type? • Eiffel Event Library: EVENT_TYPE OOSC - Summer Semester 2004
Observer pattern (C++, Java) * * update* SUBSCRIBER PUBLISHER attach detach LIBCLASS update+ APPCLASS * Deferred (abstract) Inherits from + Effective (implemented) Client (uses) OOSC - Summer Semester 2004
End of lecture 19 OOSC - Summer Semester 2004