Developing Software that Matters (condensed)

2,036 views

Published on

This presentation belongs to the course "Developing Software that Matters". This course is being given by Franco Gasperoni to the second year students of the ENST in Paris. Distributed under the GFDL.

These are the condensed slides if you have to do the presentatin in 3 hours.

https://libre.adacore.com/Software_Matters/

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,036
On SlideShare
0
From Embeds
0
Number of Embeds
28
Actions
Shares
0
Downloads
64
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Developing Software that Matters (condensed)

  1. 1. OOP: Why? Franco Gasperoni gasperoni@adacore.com http://www.adacore.com/ http://libre.adacore.com/ www.adacore.com
  2. 2. Slides Home page • http://libre.adacore.com/Software_Matters All the course slides are there (PDF and PowerPoint) Slide 2
  3. 3. Copyright Notice • © AdaCore under the GNU Free Documentation License • Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; provided its original author is mentioned and the link to http://libre.adacore.com/ is kept. A copy of the license is included in available at: • http://www.fsf.org/licenses/fdl.html Slide 3
  4. 4. Objectives Why OOP Comparing ways to structure software – Functionality-oriented Functionality- – Object-oriented Object- – Structural problems with both approaches Slide 4
  5. 5. Interesting Book • Programming in Ada 2005 – by John Barnes (Addison Wesley) Slide 5
  6. 6. Why OOP? • What are OOP’s benefits? • What problem does OOP solve? Slide 6
  7. 7. Side Note on Software Construction Processes www.adacore.com
  8. 8. Software Development Phases Slide 8
  9. 9. Software Processes • A Software Process is – A set of activities (e.g. requirements, analysis, design, coding, testing) combined and sequenced in a particular fashion to produce software • Recent trend: Agile Software Development – Customer needs evolve with time – Satisfying customers at delivery time (rather than at project initiation) is more important than conforming to initial customer requirements Slide 9
  10. 10. Example of Software Processes Waterfall Iterative eXtreme Programming (XP) Requirements Requirements Analysis Testing Coding Design Requirements Analysis Design Requirements Analysis Testing Coding Design Coding Analysis Testing Requirements Analysis Testing Coding Requirements Design Time Analysis Design Requirements Design Analysis Testing Coding Design Coding Testing Requirements Coding Analysis Testing Coding Requirements Design Analysis Design Requirements Analysis Testing Coding Design Testing Coding Testing Scope (customer needs) Slide 10
  11. 11. • This course is independent of • Particular software construction methodology Slide 11
  12. 12. Software Structure www.adacore.com
  13. 13. Need to Structure and Organize Organization / Structure is fundamental to: • Engineering activities – Buildings, software, planes, ... • Many human endeavours – Music, books, business corporations, ... • Nature is structured – Human body, plants, the universe, ... Slide 13
  14. 14. Why do we Need to Structure & Organize Software? • Divide the work among groups of people • Helping people to understand the software • Make software fixes possible • Make software evolution possible •… Slide 14
  15. 15. Properties of an Ideal Software Architecture • Loose coupling between components of the software – Division of labor – Components re-use • No functionality/code duplication • Code changes minimized when software evolves • Code re-testing minimized when software evolves Slide 15
  16. 16. Structuring Elements of Software When creating a new system you identify its: • Data types – Kind of data that will be manipulated • Operations – Manipulations on the data Slide 16
  17. 17. OOP vs SP Two dimensions around which to organize software: • Around its operations – Structured Programming (SP) • Around its Data Types – Object-Oriented Programming (OOP) Slide 17
  18. 18. Example operations related types op1() op2() op3() op4() op5() X X X A X X X B X X X C Slide 18
  19. 19. SP: A centralized view of Software operations related types op1() op2() op3() op4() op5() X X X A X X X B X X X C Slide 19
  20. 20. OOP: A distributed view of Software operations related types op1() op2() op3() op4() op5() X X X A X X X B X X X C Slide 20
  21. 21. SP vs OOP: Where Differences Are Significant The key discriminator between SP and OOP is change • Change in operations – What happens when new operations need to be added to an SP or an OOP program? • Change in data types – What happens when new data types need to be added to an SP or an OOP program? Slide 21
  22. 22. New Operation operations related types op1() op2() op3() op4() op5() new() X X X A X X X X B X X X X C Slide 22
  23. 23. New Operation: SP – a Good Choice operations related types op1() op2() op3() op4() op5() new() X X X A X X X X B X X X X C Slide 23
  24. 24. New Operation: OOP – A Poor Choice operations related types op1() op2() op3() op4() op5() new() X X X A X X X X B X X X X C Slide 24
  25. 25. New Data Type operations related types op1() op2() op3() op4() op5() X X X A X X X B X X X C X X X NEW Slide 25
  26. 26. New Data Type: SP - A Poor Choice operations related types op1() op2() op3() op4() op5() X X X A X X X B X X X C X X X NEW Slide 26
  27. 27. New Data Type: OOP - A Good Choice operations related types op1() op2() op3() op4() op5() X X X A X X X B X X X C X X X NEW Slide 27
  28. 28. New functionalities can be  factored in few tagged types Summary Data type changes ?? Use Object Use Oriented Object Oriented use Functionality‐Oriented Functionality changes Slide 28
  29. 29. Ada 2005 www.adacore.com
  30. 30. Programming Language Design Goals •C – A portable, higher-level assembly language – No safety or security concerns • C++ – An object-oriented language upwardly compatible with C – No safety or security concerns • Java – Fix C++ insecurity problems (i.e. cannot create a virus in Java) – No safety concerns Slide 30
  31. 31. Ada Industrial-strength version of Pascal designed to build: • Safe software • Secure software • Software that needs to evolve • Mixed-language software • Language designed by an international team – 1983: First version of the language – 1995: Major revision (adds OOP, …) – 2005: Latest revision Slide 31
  32. 32. Some Industrial Applications in Ada • Business-critical – Canal+ Technologies: Pay-per-view, access control – BNP: Trading Language – Philips: Semiconductor assembly equipment – Helsinki radiotelescope • Mission-critical – Astree: European-wide railroad signaling – Weirton Steel - process controller – Mondex electronic money – Scanning Electron microscope • Safety-critical – Airbus A340 – Boeing 777 Slide 32
  33. 33. Ziegler’s Study: Comparing C & Ada • 1995 VADS study – 60 engineers, from 1984 ..1994 with MS degrees in computer science – All knew C at hire. All programmed in both C and Ada. • VADS – About 4.5 million lines of code, 22000 files, cost >$28m over 10 years 2500000 2000000 1500000 ll in s AL e 1000000 500000 0 C Code Ada Code Make Scripts Miscellany Slide 33
  34. 34. Costs Per Feature During Implementation cost/feature: $350 $300 $250 $200 $150 $100 $50 $0 C C, including Makefiles ADA Slide 34
  35. 35. Post-Delivery (User-Reported) Defects 1200 1000 800 C 600 Ad a 400 200 0 Critical De fects Seve re Defe cts Minor d efects T o ta l Defects Slide 35
  36. 36. Summary • Developing software in Ada is 60% cheaper than in C • Code developed in Ada has 9 times less bugs than in C • Was Ada consistently better? *YES* – Over different subsets of VADS – For experienced AND inexperienced programmers – For both C experts AND Ada experts – For the highest AND lowest rated programmers • Was Ada harder to learn? *No* • Was Ada code more reliable? *YES* http://www.adaic.com/whyada/ada-vs-c/cada_art.html Slide 36
  37. 37. From an Education Perspective • Ada is a good language to teach good software practice – Reliability, safety, security • Ada allows to design SP and OOP software • Free Software high-quality Ada environment available – http://libre.adacore.com – GNAT GPL Edition (Ada 2005) – Linux, Mac OS, Windows Slide 37
  38. 38. • Programming in the Large – specification & implementation – privacy 38 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  39. 39. Separate Compilation T C H O object Compiler D E E P L i C R executable O n object Compiler D k O E e B r L E C O object Compiler M D libraries E 39 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  40. 40. Problem with this approach C C C O O O D D D E E C E O C D O E D E • No structure • To write your own code – YOU MUST understand everybody else’s code 40 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  41. 41. Idea: Specify the Services SPECIFY  the Services provided by each module 41 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  42. 42. • SPEC = list of services provided • BODY = implementation of the services (hidden) Service_1 Service_2 Service_3 Service_1 implementation Service_2 implementation Service_3 implementation Software module 42 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  43. 43. SPECIFICATION ? 43 BODY http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  44. 44. Example • Create a Queue module that can – Add an Integer to the Queue – See the First integer in the Queue – Get the first integer in the Queue – Test whether the Queue is Empty 44 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  45. 45. queue.ads queue.ads package Queue is package Queue is procedure Add (Element ::Integer); procedure Add (Element Integer); function First return Integer; function First return Integer; function Get return Integer; function Get return Integer; function Empty return Boolean; function Empty return Boolean; end Queue; end Queue; 45 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  46. 46. To write Client only need to look at queue.ads queue.ads package Queue is package Queue is procedure Add (Element : :Integer); procedure Add (Element Integer); function First return Integer; function First return Integer; function Get return Integer; function Get return Integer; function Empty return Boolean; function Empty return Boolean; end Queue; end Queue; ? package Queue 46 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  47. 47. Using package Queue client.adb with Queue; procedure Client is Queue_Error : exception; X : Integer; begin Queue.Add (3); Queue.Add (4); if not Queue.Empty then X := Queue.Get; else raise Queue_Error; end if; end Client; 47 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  48. 48. Specifications Reduce Complexity SPEC SPEC SPEC SPEC SPEC SPEC SPEC SPEC • To write your own code – only need to understand specs for the services you need 48 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  49. 49. Aside: use clause with Queue; use Queue; procedure Client is Queue_Error : exception; X : Integer; begin Queue. Add (3); Queue. Add (4); if not Queue. Empty then X := Queue. Get; else raise Queue_Error; end if; end Client; 49 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  50. 50. A Spec can have several implementations queue.ads queue.ads package Queue is package Queue is (Element : Integer); procedure Add procedure Add (Element : Integer); function First return Integer; function First return Integer; function Get return Integer; function Get return Integer; function Empty return Boolean; function Empty return Boolean; end Queue; end Queue; • Can change implementation second second first implement. first implement. • WITHOUT having to change implement. implement. ANY of the client’s code 50 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  51. 51. One Possible Implementation: Circular Buffer Q 0 1 Max_Size - 1 Q_First Q_Last 51 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  52. 52. Another Possible Implementation: Linked List Q_First Q_Last 52 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  53. 53. In Ada • Spec always checked against implementation • Must with the specs that you are going to use (not in C) • Packages provide multiple name spaces 53 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  54. 54. Spec is checked against its body package Queue is package Queue is procedure Add (Element ::Integer); procedure Add (Element Integer); ... ... end Queue; end Queue; Compilation Error if no procedure Add (Element : Integer) is … package body Queue is begin package body Queue is … ... ... end Add; ... ... end Queue; end Queue; 54 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  55. 55. Must with Specs used with Queue; procedure Client is Compilation ... error begin Queue.Add (3); ... end Client; 55 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  56. 56. Multiple Name Spaces package Set is package Queue is package Set is package Queue is procedure Add (E ::Integer); procedure Add (E Integer); procedure Add (E ::Integer); procedure Add (E Integer); ... ... ... ... end Set; end Queue; end Set; end Queue; with Queue; with Set; procedure Client is begin Queue.Add (3); Set.Add (99); end Client; 56 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  57. 57. Use Clause and Ambiguities package Set is package Queue is package Set is package Queue is procedure Add (E ::Integer); procedure Add (E Integer); procedure Add (E ::Integer); procedure Add (E Integer); ... ... ... ... end Set; end Queue; end Set; end Queue; with Queue; use Queue; with Set; use Set; Compilation procedure Client is error begin ambiguity Add (123); end Client; 57 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  58. 58. And … Ada has overloading package Queue is package Queue is procedure Add (E ::Integer); procedure Add (E Integer); procedure Add (E ::Float); procedure Add (E Float); ... ... end Queue; end Queue; with Queue; use Queue; procedure Client is begin Add (123); Add (3.141); end Client; 58 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  59. 59. • Programming in the Large – specification & implementation – privacy 59 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  60. 60. Having Several Queues package Queues is package Queues is type Queue is …; type Queue is …; procedure Add (Q ::Queue; Element ::Integer); procedure Add (Q Queue; Element Integer); function First (Q ::Queue) return Integer; function First (Q Queue) return Integer; function Get (Q ::Queue) return Integer; function Get (Q Queue) return Integer; function Empty (Q ::Queue) return Boolean; function Empty (Q Queue) return Boolean; end Queues; end Queues; 60 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  61. 61. Using Several Queues with Queues; use Queues; procedure Client is Q1 : Queue; Q2 : Queue; begin Add (Q1, 123); Add (Q2, 3); Add (Q2, Get (Q1)); end Client; 61 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  62. 62. One possible implementation ... type Element is record type Element is record Val    : Integer; Val    : Integer; Next : access Element; Next : access Element; end record; end record; type Queue is record type Queue is record First : access Element; First : access Element; Last : access Element; Last : access Element; end record; end record; package Queues is type Queue is …; procedure Add (Q : Queue; Element : Integer); function First (Q : Queue) return Integer; function Get (Q : Queue) return Integer; function Empty (Q : Queue) return Boolean; end Queues; 62 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  63. 63. Client code allowed to depend on the implementation ! with Queues; use Queues; procedure Client is Q1 : Queue; Q2 : Queue; begin Add (Q1, 123); Add (Q2, 3); OK Q2.Last := null; end Client; 63 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  64. 64. Another implementation ... type Table (Natural range <>) of Integer; type Table (Natural range <>) of Integer; type Queue (Max: Natural) is record type Queue (Max: Natural) is record Q  : Table (0 .. Max); Q  : Table (0 .. Max); First : Natural; First : Natural; Last : Natural; Last : Natural; Size : Natural; Size : Natural; package Queues is end record;  end record;  type Queue is …; procedure Add (Q : Queue; Element : Integer); function First (Q : Queue) return Integer; function Get (Q : Queue) return Integer; function Empty (Q : Queue) return Boolean; end Queues; 64 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  65. 65. … breaks client code ! with Queues; use Queues; procedure Client is Q1 : Queue; Q2 : Queue; begin Add (Q1, 123); Add (Q2, 3); Compilation error Q2.Last := null; end Client; 65 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  66. 66. Even without changing the implementation there is a PROBLEM with Queues; use Queues; procedure Client is Q1 : Queue; Q2 : Queue; begin Add (Q1, 123); Q2: 3 3 Q2 is in an Add (Q2, 3); inconsistent First state Last Q2.Last := null; null 66 end Client; http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  67. 67. You need PRIVACY • Exposing your data structures is risky – Client code may manipulate the structures directly without using your own services – Client code is hard to change – Creates strong coupling 67 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  68. 68. • If there is a bug concerning a Queue, you may have to look at 1000s of packages to find the bug • If you change the implementation you may have to update 1000s of packages 68 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  69. 69. Private types package Queues is package Queues is type Queue is private; type Queue is private; procedure Add (Q ::Queue; Element ::Integer); procedure Add (Q Queue; Element Integer); function First (Q ::Queue) return Integer; function First (Q Queue) return Integer; function Get (Q ::Queue) return Integer; function Get (Q Queue) return Integer; function Empty (Q ::Queue) return Boolean; function Empty (Q Queue) return Boolean; private private type Queue is …; type Queue is …; end Queues; end Queues; 69 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  70. 70. In any implementation ... package Queues is type Queue is private; procedure Add (Q : Queue; Element : Integer); function First (Q : Queue) return Integer; function Get (Q : Queue) return Integer; function Empty (Q : Queue) return Boolean; private type Element is record Val : Integer; Next : access Element; end record; type Queue is record First : access Element; Last : access Element; end record; end Queues; 70 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  71. 71. … private types are PRIVATE with Queues; use Queues; procedure Client is Q1 : Queue; Q2 : Queue; begin Add (Q1, 123); Add (Q2, 3); Compilation error Q2.Last := null; end Client; 71 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  72. 72. Advantages of private types • Enforces the contract of a specification • No client code can corrupt your data structures • Can change implementation without changing client code 72 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  73. 73. Why is the private part in the spec ? package Queues is type Queue is private; procedure Add (Q : Queue; Element : Integer); function First (Q : Queue) return Integer; function Get (Q : Queue) return Integer; function Empty (Q : Queue) return Boolean; private type Element is record Val : Integer; Next : access Element; end record; type Queue is record First : access Element; Last : access Element; end record; end Queues; 73 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  74. 74. … because we still need to compile the clients code with Queues; use Queues; procedure Client is Q1 : Queue; begin Add (Q1, 123); end Client; 74 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  75. 75. … but you can make a private type quite private package Queues is type Queue is private; procedure Add (Q : Queue; Element : Integer); function First (Q : Queue) return Integer; function Get (Q : Queue) return Integer; function Empty (Q : Queue) return Boolean; private type Queue_Info; type Queue is access Queue_Info; end Queues; 75 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  76. 76. package body Queues is type Element is record Val : Integer; Next : access Element; end record; type Queue_Info is record First : access Element; Last : access Element; end record; ... end Queues; 76 http://libre.adacore.com © AdaCore under the GNU Free Documentation License
  77. 77. • Structured Programming – variant programming – modifying an SP system – when to use SP 77 © AdaCore
  78. 78. When creating a new system you must identify its ... • Data types (what kind of data will be manipulated) • Functionalities (what kind of manipulations are allowed) 78 © AdaCore
  79. 79. Software System Organization • Around its functionalities (structured programming) • around its data types (object-oriented programming) 79 © AdaCore
  80. 80. Design an alert system for an industrial plant • log all the incoming alerts • handle an alert (inform right people, etc.) 80 © AdaCore
  81. 81. alerts.ads alerts.ads with Calendar; with Calendar; package Alerts is package Alerts is type Alert is private; type Alert is private; procedure Handle (A ::in out Alert); procedure Handle (A in out Alert); procedure Log (A ::Alert); (A Alert); procedure Log private private type Alert is record type Alert is record Time_Of_Arrival ::Calendar.Time; Time_Of_Arrival Calendar.Time; Cause ::String (1 .. 200); String (1 .. 200); Cause end record; end record; end Alerts; end Alerts; 81 © AdaCore
  82. 82. Having several kind of alerts • Low • Medium – dispatch a technician • High – dispatch an engineer – if problem not fixed within a delay ring an alarm 82 © AdaCore
  83. 83. with Calendar; use Calendar; with Persons; use Persons; package Alerts is type Priority is (Low, Medium, High); type Alert (P : Priority) is private; procedure Handle (A : in out Alert); procedure Log (A : Alert); procedure Set_Alarm (A : in out Alert; Wait : Duration); private type Alert (P : Priority) is record ... end record; end Alerts; 83 © AdaCore
  84. 84. private type Alert (P : Priority) is record Time_Of_Arrival : Time; Cause : String (1 .. 100); case P is when Low => null; when Medium => Technician : Person; when High => Engineer : Person; Ring_Alarm_At : Time; end case; end record; 84 end Alerts; © AdaCore
  85. 85. • Structured Programming – variant programming – modifying an SP system – when to use SP 85 © AdaCore
  86. 86. Variant Programming procedure Handle (A : in out Alert) is begin A.Time_Of_Arrival := Calendar.Clock; A.Cause := Get_Cause (A); Log (A); case A.P is when Low => null; when Medium => A.Technician := Assign_Technician; when High => A.Engineer := Assign_Engineer; Set_Alarm (A, Wait => 1800); end case; 86 end Handle; © AdaCore
  87. 87. Typical Routine for Alert Objects (version 1) procedure Some_Routine (A : in out Alert) is begin ... case A.P is when Low => ... when Medium => ... when High => ... end case; end Some_Routine; 87 © AdaCore
  88. 88. Typical Routine for Alert Objects (version 2) procedure Some_Routine (A : in out Alert) is begin ... if A.P = Low then ... elsif A.P = Medium then ... elsif A.P = High then ... else raise Internal_Error; -- defensive programming end if; end Some_Routine; 88 © AdaCore
  89. 89. Variant Programming is checked procedure Set_Alarm (A : in out Alert; Wait : Duration) is begin A.Ring_Alarm_At := A.Time_Of_Arrival + Wait; end Handle; Constraint_Error raised if A.Priority /= High 89 © AdaCore
  90. 90. Handling an Alert • You have a Get_Alert routine • Connected to the sensors in the factory • Collects the alerts with Alerts; use Alerts; with Alerts; use Alerts; function Get_Alert return Alert; Returns an function Get_Alert return Alert; unconstrained Alert the discriminant value is not known at compile time 90 © AdaCore
  91. 91. with Alerts; use Alerts; with Alerts; use Alerts; with Get_Alert; with Get_Alert; procedure Process_Alerts is procedure Process_Alerts is begin begin Probably a loop -- infinite loop loop -- infinite loop blocking call declare declare A ::Alert := Get_Alert; A Alert := Get_Alert; begin begin Handle (A); -- could have written Handle (Get_Alert); Handle (A); -- could have written Handle (Get_Alert); end; end; end loop; end loop; end Process_Alerts; end Process_Alerts; • The case inside Handle selects the right to execute depending on the discriminant • Handling code centralized in Handle 91 © AdaCore
  92. 92. • Structured Programming – variant programming – modifying an SP system – when to use SP 92 © AdaCore
  93. 93. To add functionality ... function Last (Q : Queue) return Integer; package Queues is type Queue is private; procedure Add (Q : Queue; Element : Integer); function First (Q : Queue) return Integer; function Get (Q : Queue) return Integer; function Empty (Q : Queue) return Boolean; function Last (Q : Queue) return Integer; private type Queue is …; end Queues; 93 © AdaCore
  94. 94. But ... • Every time you change a spec you must recompile all its clients • Every time you change a module you must RETEST the whole module 94 © AdaCore
  95. 95. Solution: use child units queues.ads package Queues is type Queue is private; procedure Add (Q : Queue; Element : Integer); function First (Q : Queue) return Integer; function Get (Q : Queue) return Integer; function Empty (Q : Queue) return Boolean; private type Queue is …; Child end Queues; subprogram queues-last.ads function Queues . Last (Q : Queue) return Integer; 95 © AdaCore
  96. 96. Child Units Rules • The body or private part of a child unit can see the private part of all of its parents • The spec of a child unit does NOT 96 © AdaCore
  97. 97. Using a child unit with Queues; use Queues; with Queues.Last; procedure Client is Q : Queue; X : Integer; begin Add (Q, 123); Add (Q, 3); X := Queues.Last (Q); end Client; 97 © AdaCore
  98. 98. queues.ads package Queues is type Queue is private; procedure Add (Q : Queue; Element : Integer); function First (Q : Queue) return Integer; function Get (Q : Queue) return Integer; function Empty (Q : Queue) return Boolean; private type Queue is …; end Queues; Child package queues-new_functionality.ads package Queues . New_Functionality is function Last (Q : Queue) return Integer; end Queues . New_Functionality 98 © AdaCore
  99. 99. with Queues; use Queues; with Queues.New_Functionality; procedure Client is Q : Queue; X : Integer; begin Add (Q, 123); Add (Q, 3); X := Queues.New_Functionality.Last (Q); end Client; 99 © AdaCore
  100. 100. Back to our Alerts example 100 © AdaCore
  101. 101. Adding NEW Functionality... • Do not modify what is working already – No need to retest what you already did since you do not need to touch it • Just add the functionality in a separate child unit (subprogram or package) 101 © AdaCore
  102. 102. Adding new functionality It’s simple: Use child subprograms/packages simple procedure Alerts.New_Functionality (A : in out Alert) is begin ... case A.P is when Low => ... when Medium => ... when High => ... end case; end Alerts.New_Functionality; 102 © AdaCore
  103. 103. Adding a NEW Data Variant... • You have to modify the spec containing your data type • have to modify all the routines that manipulate the data type to process new variant – Error Prone & labor intensive – need to retest everything for regressions 103 © AdaCore
  104. 104. Adding a data type Much more work: need to modify the spec... work package Alerts is ... private type Alert (P : Priority) is record ... case P is when Low => . . . when Medium => . . . when High => . . . when Emergency => . . . end case; end record; end Alerts; 104 © AdaCore
  105. 105. … as well as ALL the routines using Alert procedure Some_Routine (A : in out Alert) is begin ... case A.P is when Low => ... when Medium => ... when High => ... when Emergency => ... end case; end Some_Routine; 105 © AdaCore
  106. 106. ... ALL the routines ! procedure Some_Routine (A : in out Alert) is begin ... if A.P = Low then ... elsif A.P = Medium then ... elsif A.P = High then ... elsif A.P = Emergency then ... else raise Internal_Error; -- defensive programming end if; end Some_Routine; 106 © AdaCore
  107. 107. Important Remark • For either type of change client routines such as Process_Alerts do not need modifications with Alerts; use Alerts; with Alerts; use Alerts; with Get_Alert; with Get_Alert; procedure Process_Alerts is procedure Process_Alerts is begin begin loop -- infinite loop loop -- infinite loop Handle (Get_Alert); Handle (Get_Alert); end loop; end loop; end Process_Alerts; end Process_Alerts; 107 © AdaCore
  108. 108. • Structured Programming – variant programming – modifying an SP system – when to use SP 108 © AdaCore
  109. 109. • Data types are well known before starting the design • Adding new data variants will happen infrequently • Will add lots of new functionalities on existing data types over the life time of the system 109 © AdaCore
  110. 110. Data type changes use Functionality-Oriented 110 Functionality changes © AdaCore
  111. 111. • Object-Oriented Organization inheritance – – polymorphism – abstract types & subprograms – modifying an OO system – when to use OO organization 111 © AdaCore
  112. 112. When creating a new system you must identify its ... • Data types (what kind of data will be manipulated) • Functionalities (what kind of manipulations are allowed) 112 © AdaCore
  113. 113. Software System Organization • Around its functionalities – (functionality-oriented / structured programming) • around its data types – (object-oriented programming) 113 © AdaCore
  114. 114. • Object-Oriented Organization inheritance (simple) – – polymorphism – abstract types & subprograms – modifying an OO system – when to use OO organization 114 © AdaCore
  115. 115. Often types have some but not all properties in common... • Create completely different types • Use variant programming to factor commonalties • Use inheritance 115 © AdaCore
  116. 116. Alert Alert Time_Of_Arrival Time_Of_Arrival Cause Cause Handle () Handle () Log () Log () Medium_Alert High_Alert Medium_Alert High_Alert Low_Alert Low_Alert Time_Of_Arrival Time_Of_Arrival Time_Of_Arrival Time_Of_Arrival Time_Of_Arrival Time_Of_Arrival Cause Cause Cause Cause Cause Cause Handle () Handle () Log () Handle () Log () Handle () Handle () Handle () Log () Log () Log () Log () inherited 116 © AdaCore
  117. 117. Alert Alert Time_Of_Arrival Time_Of_Arrival Cause Cause Handle () Handle () Log () Log () Medium_Alert High_Alert Medium_Alert High_Alert Low_Alert Low_Alert Time_Of_Arrival Time_Of_Arrival Time_Of_Arrival Time_Of_Arrival Time_Of_Arrival Time_Of_Arrival Cause Cause Cause Cause Cause Cause Handle () Handle () Log () Log () Handle () Handle () Handle () Handle () Log () Log () Log () Log () 117 redefined © AdaCore
  118. 118. Alert Alert Time_Of_Arrival Time_Of_Arrival Cause Cause Handle () Handle () Log () Log () Medium_Alert High_Alert Medium_Alert High_Alert Low_Alert Low_Alert Time_Of_Arrival Time_Of_Arrival Time_Of_Arrival Time_Of_Arrival Time_Of_Arrival Time_Of_Arrival Cause Cause Cause Cause Cause Cause Engineer Technician Engineer Technician Handle () Ring_Alarm_At Handle () Ring_Alarm_At Log () Handle () Log () Handle () Handle () Handle () Log () Log () Log () Log () Set_Alarm Set_Alarm 118 added © AdaCore
  119. 119. • Alert • Low_Alert • Medium_Alert • High_Alert Are 4 Different Types 119 © AdaCore
  120. 120. with …; Alert is a tagged type package Alerts is type Alert is tagged record Time_Of_Arrival : Calendar.Time; Cause : String (1 .. 200); end record; procedure Handle (A : in out Alert); procedure Log (A : Alert); Primitive ... operations end Alerts; (methods) 120 © AdaCore
  121. 121. package Alerts is type Alert is tagged record Time_Of_Arrival : Calendar.Time; Cause : String (1 .. 200); inherited end record; procedure Handle (A : in out Alert); procedure Log (A : Alert); type Low_Alert is new Alert with null record; ... end Alerts; Derived type inherits everything by default 121 © AdaCore
  122. 122. package Alerts is type Alert is tagged record Time_Of_Arrival : Calendar.Time; Cause : String (1 .. 200); inherited end record; procedure Handle (A : in out Alert); procedure Log (A : Alert); type Medium_Alert is new Alert with record Technician : Person; added end record; procedure Handle (A : in out Medium_Alert); redefined ... 122 end Alerts; © AdaCore
  123. 123. package Alerts is type Alert is tagged record Time_Of_Arrival : Calendar.Time; Cause : String (1 .. 200); end record; inherited procedure Handle (A : in out Alert); procedure Log (A : Alert); type High_Alert is new Alert with record Engineer : Person; added Ring_Alarm_At : Calendar.Time; end record; procedure Set_Alarm (A : in out High_Alert; Wait : Duration); procedure Handle (A : in out High_Alert); redefined end Alerts; 123 © AdaCore
  124. 124. Record Fields • Are always inherited • Can never be redefined or deleted • You can add new attributes 124 © AdaCore
  125. 125. Inherited Fields with Alerts; use Alerts; procedure Client is A : Alert; A_L : Low_Alert; A_M : Medium_Alert; A_H : High_Alert; begin A . Time_Of_Arrival := …; OK A_L . Time_Of_Arrival := …; A_M . Time_Of_Arrival := …; A_H . Time_Of_Arrival := …; end Client; 125 © AdaCore
  126. 126. Inherited Fields with Alerts; use Alerts; procedure Client is A : Alert; A_L : Low_Alert; A_M : Medium_Alert; Compilation A_H : High_Alert; Error Engineer begin defined only A . Engineer := …; for A_L . Engineer := …; High_Alert A_M . Engineer := …; A_H . Engineer := …; end Client; 126 © AdaCore
  127. 127. Operations (methods) • Inherited operation has exactly the same code as the original • Redefined (or overridden) operations have new code (can never delete an operation) • Added operations are new operations 127 © AdaCore
  128. 128. Inherited & with Alerts; use Alerts; with Alerts; use Alerts; procedure Client is procedure Client is Redefined A ::Alert; Alert; A Operations A_L ::Low_Alert; A_L Low_Alert; A_M ::Medium_Alert; A_M Medium_Alert; A_H ::High_Alert; A_H High_Alert; begin begin type Alert is tagged record ... end record; type Alert is tagged record ... end record; Handle (A); procedure Handle (A ::in out Alert); procedure Handle (A in out Alert); Handle (A); type Low_Alert is new Alert with ... end record; type Low_Alert is new Alert with ... end record; Handle (A_L); Handle (A_L); type Medium_Alert is new Alert with ... end record; type Medium_Alert is new Alert with ... end record; Handle (A_M); procedure Handle (A ::in out Medium_Alert); procedure Handle (A in out Medium_Alert); Handle (A_M); type High_Alert is new Alert with ... end record; type High_Alert is new Alert with ... end record; A_H.Handle; Ada 2005 A_H.Handle; ‐‐‐‐Ada 2005 procedure Handle (A ::in out High_Alert); procedure Handle (A in out High_Alert); 128 end Client; end Client; © AdaCore
  129. 129. Added Operations with Alerts; use Alerts; procedure Client is A : Alert; A_L : Low_Alert; A_M : Medium_Alert; Compilation A_H : High_Alert; Error begin Set_Alarm Set_Alarm (A, 1800); defined only Set_Alarm (A_L, 1800); for Set_Alarm (A_M, 1800); High_Alert A_H.Set_Alarm (1800); end Client; 129 © AdaCore
  130. 130. Variant Programming procedure Handle (A : in out Alert) is begin A.Time_Of_Arrival := Calendar.Clock; A.Cause := Get_Cause (A); Log (A); case A.P is when Low => null; when Medium => A.Technician := Assign_Technician; when High => A.Engineer := Assign_Engineer; Set_Alarm (A, Wait => 1800); end case; 130 end Handle; © AdaCore
  131. 131. Programming with Inheritance procedure Handle (…) is procedure Handle (…) is begin begin procedure Handle (A : in out Alert) is A.Time_Of_Arrival := …; A.Time_Of_Arrival := …; A.Cause := …; A.Cause := …; begin Log (A); Log (A); A.Time_Of_Arrival := Calendar.Clock; case A.P is case A.P is A.Cause := Get_Cause (A); when Low => => when Low null; null; Log (A); when Medium => when Medium => A.Technician := …; end Handle; A.Technician := …; when High => when High => A.Engineer := …; A.Engineer := …; Set_Alarm (A, ...); Set_Alarm (A, ...); procedure Handle (A : in out Medium_Alert) is end case; end case; end Handle; begin end Handle; Handle (Alert (A)); -- First handle as plain Alert A.Technician := Assign_Technician; end Handle; 131 © AdaCore
  132. 132. procedure Handle (…) is procedure Handle (…) is begin begin procedure Handle (A : in out Alert) is A.Time_Of_Arrival := …; A.Time_Of_Arrival := …; A.Cause := …; A.Cause := …; begin Log (A); Log (A); A.Time_Of_Arrival := Calendar.Clock; case A.P is case A.P is A.Cause := Get_Cause (A); when Low => => when Low null; null; Log (A); when Medium => when Medium => A.Technician := …; end Handle; A.Technician := …; when High => when High => A.Engineer := …; A.Engineer := …; Set_Alarm (A, ...); Set_Alarm (A, ...); procedure Handle (A : in out High_Alert) is end case; end case; end Handle; begin end Handle; Handle (Alert (A)); -- First handle as plain Alert A.Engineer := Assign_Engineer; Set_Alarm (A, Wait => 1800); 132 end Handle; © AdaCore
  133. 133. Centralized vs Distributed Code • The code which is centralized in the same routine in the functionality-oriented version • is now distributed across 3 different routines in the object-oriented version 133 © AdaCore
  134. 134. • Object-Oriented Organization – inheritance (simple) • encapsulation & inheritance – polymorphism – abstract types & subprograms – modifying an OO system – when to use OO organization 134 © AdaCore
  135. 135. with …; package Alerts is type Alert is tagged private; procedure Handle (A : in out Alert); procedure Log (A : Alert); private type Alert is tagged record Time_Of_Arrival : Calendar.Time; Cause : String (1 .. 200); end record; end Alerts; 135 © AdaCore
  136. 136. Child Package with Alerts; use Alerts; with Alerts; use Alerts; with …; with …; package Alerts.Medium is package Alerts.Medium is type Medium_Alert is new Alert with private; type Medium_Alert is new Alert with private; procedure Handle (A :: in out Medium_Alert); procedure Handle (A in out Medium_Alert); private private type Medium_Alert is new Alert with record type Medium_Alert is new Alert with record Technician ::Person; Technician Person; end record; end record; end Alerts.Medium; end Alerts.Medium; 136 © AdaCore
  137. 137. Important Remark • Adding a new type derived from Alert – No need to modify what is working already – No need to retest what you did already • Just add the data type in a separate package (regular or child package) 137 © AdaCore
  138. 138. • Object-Oriented Organization – inheritance (simple) polymorphism – – abstract types & subprograms – modifying an OO system – when to use OO organization 138 © AdaCore
  139. 139. Handling an Alert • You have a Get_Alert routine • Connected to the sensors in the factory • Collects the alerts with Alerts; use Alerts; with Alerts; use Alerts; function Get_Alert return ???; function Get_Alert return ???; 139 © AdaCore
  140. 140. Objective • Be able to mimic the code used in the variant programming case with Alerts; use Alerts; with Alerts; use Alerts; with Get_Alert; with Get_Alert; procedure Process_Alerts is procedure Process_Alerts is begin begin loop -- infinite loop loop -- infinite loop Handle (Get_Alert); Handle (Get_Alert); end loop; end loop; end Process_Alerts; end Process_Alerts; 140 © AdaCore
  141. 141. Medium_Alert High_Alert Low_Alert Handle() Handle() Handle() Log() Log() Log() Private Private Set_Alarm() stuff stuff Private stuff The exact same interface because they all derive from type Alert 141 © AdaCore
  142. 142. Inheritance & Interfaces • All type T derived from Alert must implement or inherit: – procedure Handle (A : in out T); – procedure Log (A : T); • Cannot remove inherited operations, you can only redefine their implementation 142 © AdaCore
  143. 143. Idea: select the operation dynamically Obj ::some unknown type derived from Alert; Obj some unknown type derived from Alert; Handle (Obj); Handle (Obj); Handle() Handle() ? ? 143 © AdaCore
  144. 144. Generally Speaking ... For any tagged type T T’Class denotes ANY type D derived from T 144 © AdaCore
  145. 145. Inheritance Theorem For all type D For all type D derived from derived from T T ⊆ set of operations set of operations set of operations set of operations implemented implemented implemented implemented for objects of type for objects of type for objects of type for objects of type D T D T 145 © AdaCore
  146. 146. • Object-Oriented Organization – inheritance (simple) – polymorphism • dynamic dispatching • Using access parameters • redispatching – abstract types & subprograms – modifying an OO system – when to use OO organization 146 © AdaCore
  147. 147. Handling an Alert • You have a Get_Alert routine • Connected to the sensors in the factory • Collects the alerts with Alerts; use Alerts; with Alerts; use Alerts; function Get_Alert return Alert’Class; function Get_Alert return Alert’Class; 147 © AdaCore
  148. 148. Dynamic Dispatching with Alerts; use Alerts; with Alerts; use Alerts; with Get_Alert; with Get_Alert; procedure Process_Alerts is procedure Process_Alerts is begin begin loop -- infinite loop loop -- infinite loop declare declare A ::Alert’Class := Get_Alert; A Alert’Class := Get_Alert; begin begin Handle (A); -- could have written Handle (Get_Alert); Handle (A); -- could have written Handle (Get_Alert); end; end; end loop; end loop; end Process_Alerts; end Process_Alerts; Dispatching Call 148 © AdaCore
  149. 149. Where is the magic ? A ::Alert’Class := Get_Alert; A Alert’Class := Get_Alert; Handle (A); Handle (A); Dynamic Binding ? ? Handle() Handle() Low_Alert High_Alert 149 © AdaCore
  150. 150. Tables of pointers to primitive operations 1 1 Handle Handle Handle 1 2 2 2 Log 3 Set_Alarm ’Tag is a pointer ’Tag ’Tag ’Tag Time_Of_Arrival Time_Of_Arrival Time_Of_Arrival Cause Cause Cause Engineer Technician Ring_Alarm_At High_Alert Medium_Alert Low_Alert 150 © AdaCore
  151. 151. How do you know if call Op (V, …) is dispatching ? - Type of V is T’Class for some tagged type T - Op is a primitive operation of T type T is … end record; procedure Op (P : T; …) (or function) procedure Op (P : in out T; …) procedure Op (P : access T; …) (or function) 151 © AdaCore
  152. 152. Static vs Dynamic Binding STATIC BINDING = call known at compile time DYNAMIC BINDING = call known only at run time 152 © AdaCore
  153. 153. AL ::Low_Alert; AL Low_Alert; Handle (AL); Handle (AL); Static A ::Alert’Class := Get_Alert; A Alert’Class := Get_Alert; Binding Handle (A); Handle (A); Dynamic Binding A ::High_Alert’Class := …; A High_Alert’Class := …; Handle (A); Handle (A); Dynamic Binding 153 © AdaCore
  154. 154. • Object-Oriented Organization – inheritance (simple) – polymorphism • dynamic dispatching • redispatching – abstract types & subprograms – modifying an OO system – when to use OO organization 154 © AdaCore
  155. 155. procedure Handle (A : in out Alert) is begin A.Time_Of_Arrival := Calendar.Clock; A.Cause := Get_Cause (A); Log (A); Static always calls: procedure Log (A : Alert); end Handle; Binding procedure Handle (A : in out Medium_Alert) is begin Handle (Alert (A)); -- First handle as plain Alert A.Technician := Assign_Technician; end Handle; 155 © AdaCore
  156. 156. What if … … we override Log package Alerts is type Alert is tagged private; procedure Handle (A : in out Alert); procedure Log (A : Alert); type Medium_Alert is new Alert with private; procedure Handle (A : in out Medium_Alert); procedure Log (A : Medium_Alert); private …. end Alerts; 156 © AdaCore
  157. 157. procedure Handle (A : in out Alert) is begin A.Time_Of_Arrival := Calendar.Clock; A.Cause := Get_Cause (A); Log (Alert’Class (A)); Dynamic Binding end Handle; Redispatching procedure Handle (A : in out Medium_Alert) is begin Handle (Alert (A)); -- First handle as plain Alert A.Technician := Assign_Technician; end Handle; 157 © AdaCore
  158. 158. Dispatching Philosophy • Ada: – All primitive operations are potentially dispatching – Decide when to have a dispatching call • C++: – Decide which methods are dispatching (virtual methods) – All calls to these functions are dispatching by default • Java: – All primitive operations are dispatching – all calls are dispatching 158 © AdaCore
  159. 159. • Object-Oriented Organization – inheritance (simple) – polymorphism abstract types & subprograms – – modifying an OO system – when to use OO organization 159 © AdaCore
  160. 160. In the Alert example ... • One could create objects of type Alert rather than – Low_Alert, Medium_Alert, High_Alert • Undesirable if plain Alert has no significance but is used only to transmit: – Fields: Time_Of_Arrival & Cause – Methods: Handle & Log 160 © AdaCore
  161. 161. Make Alert an abstract type package Alerts is type Alert is abstract tagged private; procedure Handle (A : in out Alert); procedure Log (A : Alert); private type Alert is tagged record Time_Of_Arrival : Calendar.Time; Cause : String (1 .. 200); end record; end Alerts; 161 © AdaCore
  162. 162. Cannot create objects of an abstract type type Alert is abstract tagged private; A : Alert; Compilation error Alert is an abstract type 162 © AdaCore
  163. 163. Can have abstract operations package Alerts is type Alert is abstract tagged private; procedure Handle (A : in out Alert); procedure Log (A : Alert) is abstract; private type Alert is tagged record Time_Of_Arrival : Calendar.Time; Cause : String (1 .. 200); end record; end Alerts; 163 © AdaCore
  164. 164. • Object-Oriented Organization – inheritance (simple) – polymorphism – abstract types & subprograms modifying an OO system – – when to use OO organization 164 © AdaCore
  165. 165. Adding a NEW Type... • Do not modify what is working already – No need to retest what you already did since you do not need to touch it • Just add the data type in a separate package (regular or child package) 165 © AdaCore
  166. 166. package Alerts is package Alerts is type Alert is abstract tagged private; type Alert is abstract tagged private; procedure Handle (A :: in out Alert); procedure Handle (A in out Alert); procedure Log (A ::Alert); (A Alert); procedure Log private private ...... end Alerts; end Alerts; with Alerts; use Alerts; with Alerts; use Alerts; package Alerts.Medium is package Alerts.Medium is type Medium_Alert is new Alert with private; type Medium_Alert is new Alert with private; procedure Handle (A :: in out Alert); procedure Handle (A in out Alert); procedure Log (A ::Alert); (A Alert); procedure Log private private ...... end Alerts.Medium; end Alerts.Medium; 166 © AdaCore
  167. 167. Adding NEW Functionality... • Have to modify the spec containing tagged type T to which we add the functionality • Have to modify all the packages containing types derived from T to implement the new functionality – Error Prone & labor intensive – need to retest everything for regressions 167 © AdaCore
  168. 168. Example • Suppose you want to add a new functionality • that behaves DIFFERENTLY for all alert types 168 © AdaCore
  169. 169. package Alerts is package Alerts is type Alert is abstract tagged private; type Alert is abstract tagged private; procedure New_Functionality (A ::Alert); procedure New_Functionality (A Alert); ...... with Alerts; use Alerts; with Alerts; use Alerts; package Alerts.Medium is package Alerts.Medium is type Medium_Alert is new Alert with private; type Medium_Alert is new Alert with private; procedure New_Functionality (A ::Medium_Alert); procedure New_Functionality (A Medium_Alert); ...... with Alerts; use Alerts; with Alerts; use Alerts; package Alerts.High is package Alerts.High is type High_Alert is new Alert with private; type High_Alert is new Alert with private; procedure New_Functionality (A ::High_Alert); procedure New_Functionality (A High_Alert); ...... 169 © AdaCore
  170. 170. • Object-Oriented Organization – inheritance (simple) – polymorphism – abstract types & subprograms – modifying an OO system when to use OO organization – 170 © AdaCore
  171. 171. • System Functionalities are well understood before starting the design • Adding new functionality will happen infrequently • Will add lots of new data types with the same functionality over the life time of the system 171 © AdaCore
  172. 172. New functionalities can be factored in few tagged types Data type changes ?? Use Object Use Oriented Object Oriented use Functionality-Oriented 172 Functionality changes © AdaCore
  173. 173. 173 http://libre.adacore.com © AdaCore under the GNU Free Documentation License

×