home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #16 / NN_1992_16.iso / spool / comp / lang / cplus / 11358 < prev    next >
Encoding:
Internet Message Format  |  1992-07-22  |  8.4 KB

  1. Path: sparky!uunet!mcsun!fuug!demos!kiae!glas!demos!ucc.su.oz!extro.ucc.su.OZ.AU!maxtal
  2. From: maxtal@extro.ucc.su.OZ.AU
  3. Newsgroups: comp.lang.c++
  4. Date: 18 Jul 92 10:19 MDT
  5. Subject: Re: many set/get member functions in a 
  6. Sender: Notesfile to Usenet Gateway <notes@glas.apc.org>
  7. Message-ID: <1992Jul18.061906.29676@ucc.su.oz>
  8. References: <1992Jul08.121838.13948@jho.com>
  9. Nf-ID: #R:1992Jul08.121838.13948@jho.com:2043735141:1992Jul18.061906.29676@ucc.su.oz:-850869296:001:8090
  10. Nf-From: extro.ucc.su.OZ.AU!maxtal    Jul 18 10:19:00 1992
  11. Lines: 219
  12.  
  13.  
  14. In article <rmartin.711379395@thor> rmartin@thor.Rational.COM (Bob Martin) writes:
  15. >maxtal@extro.ucc.su.OZ.AU (John (MAX) Skaller) writes:
  16. >
  17. >
  18. >|If, however, the SEMANTICS 
  19. >|that there be an unconstrained 'variable' in the class,
  20. >|then making a public variable or function returning a reference
  21. >|ensures AT COMPILE time that this contract is kept by the
  22. >|class. 
  23. >
  24. >It seems very unlikely to me that any properly thought through
  25. >abstraction would demand that a variable be exposed through its
  26. >interface.  
  27.  
  28.     Yes. And no.
  29.  
  30.     Yes: when I think up abstractions, they're usually
  31.     of the form that has no unsconstrained variables.
  32.  
  33.     No: in practical programming, many things are 
  34.     quite concrete, and the program might be a one-off.
  35.     So a simple struct is often the easiest way.
  36.     Sometimes *I* claim, it is correct too.
  37.  
  38. >
  39. >An object is an encapsulation of state and behavior, exposed through
  40. >an interface.  The interface has the task of insuring that the
  41. >invariants of state are maintained.  If internal variables can be
  42. >manipulated from the outside, these invariants may be violated without
  43. >the object's knowledge, leaving the object in an invalid state.
  44.  
  45.     I do not disagree with this philosophy, although I
  46. never think in terms of 'behaviours'.
  47.  
  48.     The interface is but ONE aspect of the semantics.
  49. The semantics, including the interface, should be immutable.
  50. If I could also specify a class invariant, or even better,
  51. some axioms, THAT would be the semantics and it would be
  52. immutable.
  53.  
  54. >
  55. >"But", you say, "I have a variable which has no invariants, so it is safe
  56. >to expose this variable to my clients."
  57.  
  58.     No, I don't say "it is safe". On the contrary, I say
  59. its exposure in C++ is one of the few ways that one can also
  60. specify semantics completely and get a guarrantee that
  61. the semantics cannot be violated.
  62.  
  63. >
  64. >Is it indeed?  Let me tell you a little story.
  65. >
  66. >I once wrote an object oriented application for manipulating icons on
  67. >a screen.  I created a "Point" class which encapuslated a single
  68. >cartesian coordinate.  In my naivete I thought, as you think now, that
  69. >I should expose the 'x' and 'y' variables.  
  70.  
  71.     Hold on, dont jump to conclusions! I would NEVER advocate
  72. that the x and y coordinates of a point be exposed publically.
  73. I would ALSO say set_x and set_y functions were naughty.
  74. I would require you to set BOTH coordinates simultaneously.
  75.  
  76. >After all, I did not want
  77. >to have to write a set of accessor functions, that was too much work!
  78. >Little did I know!
  79.  
  80.     I agree you did it wrong: but NOT for the reasons you
  81. outline below. I will explain why.
  82. >
  83. >Much later, when the project was nearly complete, I decided to add the
  84. >concept of a constraining grid to the screen.  I am sure you have seen
  85. >constraining grids, they separate the screen into a grid with a
  86. >spacing of 5-10 pixels or so, and force any positional change of any
  87. >object on the screen to align to this grid.  This makes it easy for
  88. >the user to line up his icons in staight horizontal or vertical rows.
  89. >
  90. >Anyway, I realized that this would be remarkably simple to do, if I
  91. >created the concept of a ConstrainedPoint, derived from Point.  This
  92. >new abstraction would automatically adjust its coordinates to the
  93. >grid.  The rest of the application could remain blissfully ignorant of
  94. >the contraining grid. But alas, it was not to be.  All through my code
  95. >there were direct accesses to the x and y variables of class Point.
  96. >THere was no way for me to insert the constraint in a single place.  
  97.  
  98.     But there is. You just didn't think of it.
  99.  
  100.     class ConstrainedPoint : private Point {
  101.         ContstrainedPoint(int x, int y);
  102.     };
  103.  
  104. >
  105. >Thus, I created bad situtation for myself.  I had to search through
  106. >the code, finding every use of x and y, and apply the contraint
  107. >locally.  Worse, I created a maintenance nightmare for the company,
  108. >since now the maintainer must always remember that when they
  109. >manipulate an x or x they must check for, and apply, the contraint.
  110.  
  111.     Absolutely necessary for you to do this running through
  112. the code. No way out. You HAVE to change you program
  113. to use constrained points where desired. Here's why:
  114.  
  115.     I also used your point class.
  116.  
  117.     I dont ALWAYS want constrained points.
  118.  
  119.     I have rectangles: (ICONS for example) and have
  120.     cached all 4 corners.
  121.  
  122.     Now assume you had use set_x and set_y.
  123.  
  124.     Suddenly, my corners are all wrong. (Only the left
  125. corner of an icon snaps to the grid, the others can't because
  126. the sieze of the icon is fixed).
  127.  
  128.     But if you used the public variables YOU COULD NOT
  129. DO THIS NAUGHTY CHANGE TO THE SEMANTICS AND DESTROY MY CODE.
  130. >
  131. >Blech!
  132. >
  133. >I don't want to hear that the semantics of Constrained_Point were
  134. >different than the semantics of Point, and so the application should
  135. >have been changed at every place which used Point.  
  136.  
  137.     Well, that is exactly what I am telling you must be done.
  138.  
  139. >That argument is
  140. >absurd.  I didnt want the rest of the application to know about
  141. >Constrained_Point.  
  142.  
  143.     But I have shown you that SOME parts of the application
  144. RELY ON THE POINTS NOT BEING CONSTRAINED.
  145.  
  146.     Your idea that you can magically change the semantics 
  147. by using polymorphism is absurd. 
  148.  
  149. >I wanted the semantics of contrainment to be
  150. >hidden.
  151.  
  152.     I'm glad you used a public variable because that 
  153. PREVENTED YOU HIDING THE SEMANTICS and stuffing up MY
  154. piece of code.
  155. >
  156. >Also, I don't want to hear that I should have anticipated the need for
  157. >contrainment.  That is a useless argument too.  If OOP forces me to
  158. >think of everything in advance, then it is a worthless concept.
  159.  
  160.     Yes, I agree. In class based languages like C++
  161. the requirement is alleviated: you MUST GET THE SEMANTICS
  162. EXACTLY CORRECT AND NOT DEVIATE FROM THEM, and then if
  163. you obey the above rule you are allowed to derive
  164. new classes.
  165.  
  166.     IF YOU CHANGE THE SEMANTICS (just like if
  167. you change the interface) THEN YOU MUST REEXAMINE EVERY
  168. USE. It is best to add a NEW unrelated class sometimes,
  169. since that leaves all existing code working, esepcially
  170. MY piece of code that relied on points having unconstrained
  171. coordinates.
  172. >
  173. >But fortunately, when properly applied, OOP does not force you to
  174. >anticpate every need of the application.  By hiding semantics, you can
  175. >create a system which is flexible enough to withstand many
  176. >unanticipated changes.
  177. >
  178.  
  179.     NO. You hide the IMPLEMENTATION. 
  180.     You hide irrelevant detail.
  181.  
  182.  
  183.     Constrained points are NOT semantically equivalent
  184. to unconstrained ones.
  185.  
  186.     HAD you used Constrained points FIRST and then derived
  187. Unconstrained ones from them as a special case, you would
  188. have had no problem.
  189.  
  190.     Since you did not have the foresight to do this,
  191. you had to rework your code. This is as it should be,
  192. indeed, as it must be, and the fact that it ISNT in practical
  193. languages is a DISADVANTAGE of the language.
  194.  
  195.     In short: OOP rewards foresight.
  196.  
  197.     In C++ especially, you really MUST get the design
  198. exactly right and stick to it. In C++ there is a
  199. MASSIVE shift of effort from programming to design.
  200. Your reward for working under such stringent constraints
  201. is run-time correctness.
  202.  
  203. Each weakening of the constraints leads to  decreased
  204. ability of the compiler to provide guarrantees.
  205.  
  206. Thus, in smalltalk, you can design anything, but only
  207. your customers know if it works. At least in C++
  208. the COMPILER knows something, when a program
  209. has been compiled *I* have some sense of security
  210. I could never have in sta.
  211.  
  212. I would like to see better language support for
  213. semantics: Eiffel has shown one way.
  214.  
  215. Then my cached points would have invariants:
  216. "Distance between two top points equal width of rectangle"
  217. and I could detect at run-time that you broke your
  218. contract with me to provide unconstrained points
  219. EVEN if you had set_x and set_y methods.
  220.  
  221. As it happens, a public variable would provide that very
  222. guarrantee even better (although I would not utilise
  223. that feature in the case of a point)
  224.  
  225.  
  226. -- 
  227. ;----------------------------------------------------------------------
  228.         JOHN (MAX) SKALLER,         maxtal@extro.ucc.su.oz.au
  229.     Maxtal Pty Ltd, 6 MacKay St ASHFIELD, NSW 2131, AUSTRALIA
  230. ;--------------- SCIENTIFIC AND ENGINEERING SOFTWARE ------------------
  231.  
  232.