design patterns in eiffel
play

Design Patterns in Eiffel Dr. Till Bay design patterns? [Design - PowerPoint PPT Presentation

Design Patterns in Eiffel Dr. Till Bay design patterns? [Design Patterns] are descriptions of communicating objects and classes that are customized to solve a general design problem in a particular context. Design Patterns,


  1. Design Patterns in Eiffel Dr. Till Bay

  2. design patterns? • “[Design Patterns] are descriptions of communicating objects and classes that are customized to solve a general design problem in a particular context.” • “Design Patterns”, GOF 2 Comerge AG

  3. hierarchy of reuse Library Bottleneck Language Wizard / Tool Design Pattern Documented Solution Communicated Solution (“Cut ʼ n ʼ Paste”) Ad-hoc Solution 3 Comerge AG

  4. reuse and quality Reuse Quality • Reuse increases quality • Only by reuse, the extra effort of quality pays off • “Given enough eyeballs, all bugs are shallow” (Eric Raymond) • Quality increases reuse • Understandable • Trust gained by quality 4 Comerge AG

  5. observer pattern • Loose coupling between caller and call target. • Implement a publish-subscribe and MVC architecture. 5 Comerge AG

  6. observer example observers OBSERVER SUBJECT LIST[OBSERVER] CONCRETE_ CONCRETE_ OBSERVER SUBJECT 6 Comerge AG

  7. observer pattern observers CLICK_ CLICKABLE OBSERVER LIST[OBSERVER] ON_CLICK_ BUTTON ACTION 7 Comerge AG

  8. observer as library Library class event_x SUBJECT EVENT_TYPE subscribers Language feature target PROCEDURE OBSERVER (“agent”) 8 Comerge AG

  9. EVENT _ TYPE class EVENT_TYPE [G -> TUPLE] feature -- Subscription subscribers: LIST [PROCEDURE [ANY, G]] subscribe (an_action: PROCEDURE [ANY, G]) -- Add `an_action ʼ to the subscription list. require not_void: an_action /= Void ensure subscribed: subscribers.has (an_action) feature -- Publish publish (arguments: G) -- Publish event with `arguments ʼ . require not_void: arguments /= Void end 9 Comerge AG

  10. events in MVC class DATABASE ... feature -- Slots remove_customer is ... end ... end class BUTTON ... feature -- Signals clicked: EVENT_TYPE [TUPLE []] ... end gui_remove_button.clicked.subscribe ( agent db.remove_customer) 10 Comerge AG

  11. dropping arguments class DATABASE TUPLE[] ... feature -- Slots remove_customer is ... end ... end class BUTTON TUPLE[INTEGER] ... feature -- Signals clicked: EVENT_TYPE [TUPLE [INTEGER]] ... end gui_remove_button.clicked.subscribe ( agent db.remove_customer) 11 Comerge AG

  12. type system caveat 1 print (what:ANY) PROCEDURE [ANY,TUPLE[INTEGER]] ... clicked: EVENT_TYPE [TUPLE [INTEGER]] not ... clicked.subscribe (print (?)) PROCEDURE [ANY,TUPLE[ANY]] Does not type check! 12 Comerge AG

  13. type system caveat print_integer (v: INTEGER) PROCEDURE ... [ANY,TUPLE[ANY]] network.received: EVENT_TYPE [TUPLE [ANY]] ... PROCEDURE received.subscribe [ANY,TUPLE[INTEGER]] (print_integer (?)) Compiles with type error (CAT call!) 13 Comerge AG

  14. observer: summary • Not needed as pattern • Language powerful enough (agents, generics, tuple) to implement as library • Available library classes: • ACTION_SEQUENCE (used by Vision2) • EVENT_TYPE (early implementation at ETH) • Not yet in GOBO • GOBO did support compilers w. o. agents • will change in the future 14 Comerge AG

  15. factory • Remove create instructions from the code. • Relocate them to a single feature (factory method) or class (abstract factory). • Make it easy to change the dynamic type of objects. 15 Comerge AG

  16. factory method class ET_AST_FACTORY ... feature -- Factory method new_class: (a_name: ET_CLASS_NAME): ET_CLASS is -- New Eiffel class require ... do create Result.make (a_name) ensure ... end end 16 Comerge AG

  17. abstract factory CLIENT WIDGET_FACTORY WINDOW AQUA_WINDOW GDI_WINDOW GDI_W_FACTORY AQUA_W_FACTORY SCROLL_BAR AQUA_SCROLL_B GDI_SCROLL_B 17 Comerge AG

  18. factories and generics ABSTRACT_FACTORY CREATABLE [G -> CREATABLE] default_create GDI_W_FACTORY AQUA_W_FACTORY 18 Comerge AG

  19. factory summary • Remove create instructions from the code. • Relocate them to a single feature (factory method) or class (abstract factory). • Make it easy to change the dynamic type of objects. 19 Comerge AG

  20. singleton • Class that should only have a single, global instance. 20 Comerge AG

  21. reasons for singleton 1.Because some environment constraint makes it necessary: OPERATING_SYSTEM, STANDARD_FILES, COMMAND_LINE_ARGUMENTS 2.To get a stateless functional infrastructure URL_ENCODING, MATH_SUPPORT 3.To access shared data PARSED_AST, DATABASE, SESSION_DATA 21 Comerge AG

  22. singletons in Eiffel class FILE_SYSTEM ... end class SHARED_FILE_SYSTEM feature -- Access File_system: FILE_SYSTEM is -- Operating system file system once create Result ensure not_void: Result /= Void end end 22 Comerge AG

  23. shared data • Using singletons for shared data creates problems with reuse: local application1: MY_APPLICATION application2: MY_APPLICATION do create application1 application1.do_something create application2 application2.do_something_else end Does it work? 23 Comerge AG

  24. universe objects • A “universe object” stores global data for the system. • Positive: fine-grained sharing • Negative: significant extra work and increased “noise” in the code 24 Comerge AG

  25. universe example local u1,u2: MY_UNIVERSE application1: MY_APPLICATION application2: MY_APPLICATION do create u1 create application1.make (u1) application1.do_something create u2 create application2.make (u2) application2.do_something_else end 25 Comerge AG

  26. universe example class MY_APPLICATION feature -- Initialization make (u: MY_UNIVERSE) is -- Initialize application. do universe := u create my_subsystem.make (u) ensure universe_set: universe = u end feature -- Access universe: MY_UNIVERSE -- Shared application resources my_subsystem: MY_SUBSYSTEM -- Subsystem of application end 26 Comerge AG

  27. universe stacks • Idea: use once to reference a stack of universes. class SHARED_UNIVERSE_STACK feature -- Access Universe_stack: LINKED_STACK [MY_UNIVERSE] is -- Global stack of universes. local default_universe: MY_UNIVERSE once create Result create default_universe Result.extend (default_universe) ensure not_void: Result /= Void end 27 Comerge AG

  28. universe stacks feature -- Universe universe: MY_UNIVERSE is Some -- Global stack of universes. contracts do skipped for Result := Universe_stack.item brevity! end push_universe is -- Create a new universe. local new_universe: MY_UNIVERSE once create new_universe Result.extend (new_universe) end pop_universe is -- Return to an old universe. do ... end 28 Comerge AG

  29. universe stack ex. local application1: MY_APPLICATION application2: MY_APPLICATION do create application1.make application1.do_something push_universe create application2.make application2.do_something_else pop_universe end 29 Comerge AG

  30. singleton summary • Identify the reason for the singleton. • Only use singletons for functional libraries and environment constraints . • If it is shared data, reconsider using a universe object. • Important global shared data for a large application creating a lot of noise can benefit from using a universe stack . 30 Comerge AG

  31. flyweight • Reuse existing objects by aliasing the objects during object creation. • Requires an object factory and a shared repository of objects. • Works if the object identity follows from the object value. Value semantics comerge AG

  32. coding flyweight class FLYWEIGHT_FACTORY feature -- Factory make_new_flyweight (a: SOME_ARG): FLYWEIGHT is -- Create a new flyweight, initialized with `a ʼ . do if flyweight_pool.has_index (a) then Result := flyweight_pool.item (a) else create Result.make (a) flyweight_pool.extend (Result, a) end end flyweight_pool: HASH_TABLE [FLYWEIGHT,SOME_ARG] is once ... end end 32 Comerge AG

  33. expanded types • “Expanded types”: Define classes with value semantics • Much improved through ECMA • No explicit instance creation necessary • No recursive data structures • No subtyping • No aliasing: copy semantics • Reference equality (=) becomes value equality (is_equal, ~) comerge AG

  34. flyweight vs. expanded • Expanded classes cover nearly all cases where you would have used flyweight for Java or .NET • Use flyweight only if you need one of the following: • Complex type hierarchy • Unbounded data • Recursive data structure with value semantics comerge AG

  35. flyweight examples Expanded Type Flyweight • characters • string labels • pairs • tokens • currency values • sets • enumeration • (some) units types comerge AG

  36. flyweight summary • Flyweight implements value semantics • Straight forward implementation • Use a once container as flyweight pool • Choose: • Flyweight: Needs hierarchy, unbounded data or recursive data structure • Otherwise use expanded type comerge AG

  37. composite • Tree structure for “whole/part” hierarchies • Abstract tree node type defined • Leaf nodes: • implement abstract tree node type • Non-leaf nodes: implement • implement abstract tree node type • have a number of attributes of tree node type • Nothing special for Eiffel 37 Comerge AG

  38. composite sub_node: NODE * NODE LEAF NON_LEAF 38 Comerge AG

  39. composite example deferred class EXPRESSION end 39 Comerge AG

  40. composite example class INTEGER_EXPRESSION inherit EXPRESSION feature -- Access value: INTEGER -- Representation of expression end 40 Comerge AG

Recommend


More recommend