Download presentation
Presentation is loading. Please wait.
1
Chair of Software Engineering 1 Introduction to Programming Tuples and Agents Exercise Session 1 and 2 December 2008
2
Chair of Software Engineering 2 This week Tuples Agents Observer Pattern (revisited)
3
Chair of Software Engineering Tuples A tuple of type TUPLE [A, B, C] is a sequence of at least three values, first of type A, second of type B, third of type C. In this case possible tuple values that conform are: [a 1, b 1, c 1 ], [a 1, b 1, c 1, x 1 ],... where a i is of type A, b i of type B, c i of type C and x i of some type X Tuple types (for any types A, B, C,... ): TUPLE TUPLE [A] TUPLE [A, B] TUPLE [A, B, C]...
4
Chair of Software Engineering Labeled Tuples Tuples may be declared with labeled arguments: tuple: TUPLE [food: STRING; quantity: INTEGER] Same as an unlabeled tuple: TUPLE [STRING, INTEGER] but provides easier (and safer!) access to its elements: May use io.print (tuple.food) instead of io.print (tuple.item(1))
5
Chair of Software Engineering tuple_safety_test local t1: TUPLE [STRING, INTEGER] t2: TUPLE [food: STRING; quantity: INTEGER] s : STRING do t1 := [“chicken”, 66] t2 := [“chicken”, 66] s := t1.item(1) s := t2.item(1) s := t2.food end Labeled vs. unlabeled tuples Hands-On
6
Chair of Software Engineering Tuple type inheritance TUPLE [A, B] TUPLE [A] TUPLE
7
Chair of Software Engineering tuple_conformance local t0: TUPLE t2: TUPLE [INTEGER, INTEGER] do create t2 t2 := [10, 20] t0 := t2 print (t0.item (1).out + "%N") print (t0.item (3).out) end Tuple conformance Compiles, but precondition violation at runtime Hands-On Not necessary in this case Implicit creation
8
Chair of Software Engineering What are agents in Eiffel? Objects that represent operations Can be seen as operation wrappers Similar to delegates in C#, closures in Java, functors in C++
9
Chair of Software Engineering Agent definition Every agent has an associated routine, the one that the agent wraps and is able to invoke To get an agent, use the agent keyword e.g. an_agent := agent my_routine This is called agent definition What’s the type of an_agent?
10
Chair of Software Engineering EiffelBase classes representing agents ROUTINE PROCEDURE FUNCTION call deferred effective item PREDICATE
11
Chair of Software Engineering Open and closed agent arguments An agent can have both “closed” and “open” arguments: closed arguments set at agent definition time open arguments set at agent call time. To keep an argument open, replace it by a question mark u := agent a0.f (a1, a2, a3) -- All closed w := agent a0.f (a1, a2, ?) x := agent a0.f (a1, ?, a3) y := agent a0.f (a1, ?, ?) z := agent a0.f (?, ?, ?) -- All open
12
Chair of Software Engineering An agent invokes its routine using feature “call” f (x1: T1; x2: T2; x3: T3) -- defined in class C with --a0: C; a1: T1; a2: T2; a3: T3 u := agent a0.f (a1, a2, a3) Agent calls v := agent a0.f (a1, a2, ?) u.call ([]) v.call ([a3]) w := agent a0.f (a1, ?, a3) w.call ([a2]) x := agent a0.f (a1, ?, ?) x.call ([a2, a3]) y := agent a0.f (?, ?, ?) y.call ([a1, a2, a3])
13
Chair of Software Engineering Agent declaration p: PROCEDURE [ANY, TUPLE] -- Agent representing a procedure belonging to a -- class that conforms to ANY. At least 0 open -- arguments q: PROCEDURE [C, TUPLE [X, Y, Z]] -- Agent representing a procedure belonging to a --class that conforms to C. At least 3 open arguments f: FUNCTION [ANY, TUPLE [X, Y], RES] -- Agent representing a function belonging to a class -- that conforms to ANY. At least 2 open arguments, -- result of type RES
14
Chair of Software Engineering Example class ANIMAL create make feature {NONE} -- Initialization make (s: STRING) -- Create a new animal with name `s'. do name := s end feature -- Access name: STRING feature -- Basic operations eat (food: STRING; quantity: INTEGER) -- Eat `quantity' of `food'. do print (name + " eats " + quantity.out + " " + food + ".%N") end... See next page end
15
Chair of Software Engineering Eating with an agent Fill in the blanks, so that when eat_wrapper is called on an animal called “Mew”, the text “Mew eats 5 grass” is printed. class ANIMAL... (same as before) eat_wrapper -- Call `eat' with an agent. local a: do a := a.call (["grass", 5]) end Hands-On agent eat (?,?) PROCEDURE [ANIMAL, TUPLE [STRING, INTEGER]]
16
Chair of Software Engineering Eating with an agent (2) Fill in the blanks again, so that the text “Mew eats 5 grass” is printed. class C feature r local a: ANIMAL an_agent: do create a.make (“Mew") an_agent := an_agent.call (["grass", 5]) end Hands-On PROCEDURE [ANIMAL, TUPLE [STRING, INTEGER]] agent a.eat
17
Chair of Software Engineering Eating with an agent (3) class C feature r local a: ANIMAL an_agent: PROCEDURE [ANIMAL, TUPLE] do create a.make (“Mew") an_agent := an_agent. end Hands-On agent a.eat (“grass”, 5) call ([])
18
Chair of Software Engineering Eating with an agent (4) class C feature f do r (“grass”, 5) end r (s: STRING; i: INTEGER) local an_agent: PROCEDURE [ANIMAL, TUPLE [STRING, INTEGER]] a: ANIMAL do create a.make (“Mew") an_agent := an_agent. end Hands-On agent a.eat (?, ?) call ([s, i])
19
Chair of Software Engineering Open targets It is also possible to leave the target of an agent call open, to increase flexibility This is done at agent definition an_agent := {MY_TYPE} agent my_routine MY_TYPE is the type to which my_routine belongs
20
Chair of Software Engineering Eating with an agent (5) class C feature f local a: ANIMAL do create a.make (“Mew”) r (a, “grass”, 5) end r (a: ANIMAL; s: STRING; i: INTEGER) local an_agent: PROCEDURE [ANIMAL, TUPLE [ANIMAL, STRING, INTEGER]] do an_agent := an_agent. end Hands-On agent {ANIMAL}.eat (?, ?) call ([a, s, i])
21
Chair of Software Engineering Why do we need agents anyway? Suppose that depending on a certain event that may happen, you have to call one routine out of many Suppose you don’t know exactly which routine to invoke, because you have to (or want to) leave the choice to your clients
22
Chair of Software Engineering Another example Consider you are designing a GUI. When a button in the GUI is pressed, several other classes may be interested in this event. However, you shouldn’t hard-code in the BUTTON class which routines of which classes will be called when the button is pressed. Rather, you should let any classes interested in this event register one of their routines to be called when the button is pressed. These routines will be passed to the BUTTON class as agents and will be called when the button is pressed. And this brings us to the Publish-Subscribe Pattern…
23
Chair of Software Engineering The Publish-Subscribe Pattern PUBLISHER * PUB_1 SUBSCRIBER * SUB_1 update* update + Deferred (abstract) Effective (implemented) * + Inherits from Client (uses) subscribe + unsubscribe + subscribed: LIST […] attach detach + + SUB_2 … PUB_2 … 23 trigger
24
Chair of Software Engineering The Publish-Subscribe pattern Publisher keeps a list of observers: subscribed: LINKED_LIST [SUBSCRIBER] To register itself, an observer may execute subscribe (some_publisher) where subscribe is defined in SUBSCRIBER: subscribe (p: PUBLISHER) -- Make current object observe p. require publisher_exists: p /= Void do p. attach (Current) end
25
Chair of Software Engineering Attaching an subscriber In class PUBLISHER: attach (s: SUBSCRIBER) -- Register s as subscriber to current publisher. require subscriber_exists: s /= Void do subscribed. extend (s) end The invariant of PUBLISHER includes the clause subscribed /= Void (List subscribed is created by creation procedures of PUBLISHER)
26
Chair of Software Engineering trigger -- Ask all observers to -- react to current event. do from subscribed.start until subscribed.after loop subscribed.item. subscribed.forth end end Each descendant of SUBSCRIBER defines its own version of update Triggering an event update PUBLISHER * GUI_CLASS attach detach SUBSCRIBER * APP_CLASS update* update+
27
Chair of Software Engineering Limitations of the pattern Each publisher object knows about its observers There is only one update procedure in SUBSCRIBER: At most one operation Not reusable — must be coded anew for each application 27
28
Chair of Software Engineering Exercise Write a program that handles a GUI with 2 buttons. When the first button is pressed, a counter gets increased, while when the second button is pressed, the same counter gets decreased. The value of the counter is printed in both cases to the console. Provide 2 solutions, one that does not use the agents and one that uses them. Discuss the differences Hands-On 28
29
Chair of Software Engineering 29 Backup slides
30
Chair of Software Engineering Exercise: a news agency Consider you must create an application which allows a news agency to dispatch news to various papers, radio and TV stations, etc. How would you design and implement this application? Hands-On
31
Chair of Software Engineering Exercise You are given a working program with 1 effective publisher: BUTTON 3 effective subscribers: PRINTER, COUNTER, and RANDOM_NUM subscribers react on (simulated) button clicks Your task is to merge 3 subscribers into one class: BUTTON_LISTENER keep update features separate (rename them) pass the renamed update features as agents to publisher Hands-On 31
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.