5 ms·
I think beginners should be confronted with OOP very early, but not in the typical way: - DO teach encapsulation of state. - DO NEVER ever try to teach about
by thomasz 13y ago
I think beginners should be confronted with OOP very early, but not in the typical way:
- DO teach encapsulation of state.
- DO NEVER ever try to teach about objects as representations of real-world things. And for the love of god, do not give out modelling assignments where "Human inherits mammal" is an answer.
- DO start with collections: Vector, List, Stack etc. are easy to implement and showcase the virtues of encapsulating.
- DO teach polymorphism, but only in terms of interface inheritance. The collections you have taught before are a good starting point: ICollection, IRandomAccessable etc.
- DO NEVER EVER talk about class inheritance. Do not even use the word inheritance. Call it "is a relation" or something like that.
- When the time comes to teach inheritance, emphasize the Liskov substitution principle.
- cliffbean 13y agoI think I get why some people rage against inheritance, but I don't understand one of your remarks here. Human isa mammal (let's say). Human is a Liskov substitute in any context requiring a mammal. What's the problem here? Is it just the fact that Mammal brings to mind a classification system which happens to be hierarchical, and you're afraid people will become too accustomed to hierarchies?
- Mikera 13y agoThe problem is the design paradigm where you enforce an arbitrary fixed hierarchy on real-world data. This doesn't work for several reasons: * In the real world there are multiple overlapping hierarchies, which have different uses. Human 'isa' SentientBeing as well, which may be a much better heirarchy for modelling communications with aliens and robots. Most OOP languages either don't handle this at all, or handle it badly. * Your hierarchy will almost certainly have to change (you'll be wrong, or new requirements will come along). Frequent major code breakage / refactoring is the likely result. If you also need to persist data across versions, you're in big trouble. Property / prototype based methods are in general much more flexible for real world data.
- mickeyp 13y ago> * In the real world there are multiple overlapping hierarchies, which have different uses. Human 'isa' SentientBeing as well, which may be a much better heirarchy for modelling communications with aliens and robots. Most OOP languages either don't handle this at all, or handle it badly. There may well be overlapping hierarchies, and trying to capture taxonomy with an adequate analogy to explain the concepts of inheritance to somebody is perhaps not the best way. But to say that you must never enforce an arbitrary fixed hierarchy contradicts the very purpose of inheritance in a good design. For your particular example the correct way is to have a separate interface called "ISentient" that captures whatever methods and fields are required for sentient communication. Most OOP languages support that concept. So you can have a Human that inherits from Mammal, but only Human introduces the ISentient interface. Your "Robot" can then inherit from "Machine" and also introduce ISentient. A much better way is to use interfaces for most things: use IMammal then override "procreate" so you can account for specie extrema like the duck-billed platypus class, which is a mammal that lays eggs.
- kazagistar 13y agoCould you elaborate on how prototype based OOP solves overlapping hierarchy and hierarchy modification? It is not clear to me, and it seems actually like multiple inheritance, mixins, interfaces, and/or type-classes would address multiple hierarchies reasonably well, while I am not sure how prototype inheritance does so at all.
- thomasz 13y agoExactly. It fucks everything up: As soon as you teach OO with real world stuff as examples, all they see are inheritance relationships. It is really hard to make 'em stop creating extremely complicated hierarchies in order to solve simple problems.
- Jare 13y agoThat is absolutely NOT my experience. People look at the real world and see concrete types, not hierarchies of abstractions. New programmers will only try to build deep inheritance trees if they are told that's what they're supposed to do.
- dhimes 13y ago- DO NEVER ever try to teach about objects as representations of real-world things. And for the love of god, do not give out modelling assignments where "Human inherits mammal" is an answer I have to disagree with this. I think this is exactly how to think about this. I once explained the shift to OO to an older gent who was familiar, not just with ancient scientific programming, but also with building a house. I told him that the idea was that code was so large and complicated that it was divided up among teams with each team getting specific parameters that their code had to fit. He said, well of course. Then I said it was much like constructing a house. You had to put the frame up, and know where the windows and doors would be, but the details of the windows and doors could be decided later. Every door had to be able to respond to an "open" command and a "close" command, some may have a "lock" command, and so on, but the builder of the door worried about getting that stuff right. All you had to specify were the dimensions and the direction of the door. Now this was a pretty technical person- and perhaps doesn't qualify as a beginner, but I find, in general, real world metaphors to be powerful for teaching.
- oneeyedpigeon 13y ago"I told him that the idea was that code was so large and complicated that it was divided up among teams with each team getting specific parameters that their code had to fit." IMO, this is the first mistake. Code should not be large and complicated; when it is, few things can save you, whether it be the language or paradigm you're programming in, or the structure of the team doing the programming. OOP is a solution to the wrong problem.
- dhimes 13y agoBut how do you avoid it in today's world? How do you actually build an app without a large code base?
- ufo 13y agoThe important things for writing modular code in a big codebase is defining clear interfaces and making "black box" modules. An important thing for this is abstract data types but, unlike what many people seem to say, those are not exclusive to OOP - you can also have abstract datatypes in procedural or functional languages. The core concept of OOP is adding dynamic method-based dispatching to your abstract data types but I would argue that while this is useful a lot of times, its not really fundamental. IN fact, there as many cases when dynamic dispatching will not be able to solve the problem on its oown: a good example is generics in Java and C# - parametric polymorphism helps enforce abstractions but isn't really object oriented.
- js7 13y agoWhy should you never try to teach objects as representations of real world things? Just curious.
- betterunix 13y agoLet's put it this way: you are asked to write a program that simulates the behavior of an LCR circuit. Do you create objects to represent the components of the circuit?
- dhimes 13y agoThat example isn't specified enough to show the problem. It's either too simple or too hard. Since we're talking about a beginner, I'll assume you meant it at too simple. But even then you're assigning it to a person with a reasonably technical background. In which case, the LCR circuit is the object and you are asking for a method.
- betterunix 13y ago"the LCR circuit is the object and you are asking for a method" I think that you still have the wrong abstraction here. If you are looking for a general solution, it should be one that can handle LCR circuits, mass-spring systems, etc., though that is probably too much for an introductory course. My real point is that there is nothing to be gained by modeling circuit components or even circuits as objects -- you do not improve maintainability, you do not encourage code reuse, and you do increase the amount of code that does nothing to solve the problem.
- dhimes 13y agoMy real point is that there is nothing to be gained by modeling circuit components or even circuits as objects Then I still find your point unclear. Why would you choose them as an exercise to introduce classes, which is what we were talking about? I agree, it's odd. Mammals and dogs, however, are a concept people can understand. As are windows and doors.
- Goladus 13y agoDO teach encapsulation of state. I agree, with the caveat that there should be good discussion about when it's important to encapsulate state, rather than a rather blanket "always encapsulate data and methods" which is how it's often presented.
- gruseom 13y ago"Never ever try to teach about objects as representations of real-world things" I hear this from time to time—it seems bizarre. Representing real-world things as objects is a fine design approach for many problems and is well worth teaching. Where on earth did the idea that it isn't get started? SICP, a classic of programming pedagogy if ever there was one, has this to say: One powerful design strategy, which is particularly appropriate to the construction of programs for modeling physical systems, is to base the structure of our programs on the structure of the system being modeled. For each object in the system, we construct a corresponding computational object. For each system action, we define a symbolic operation in our computational model. (p. 217, 2nd ed.) It's true that by "object" they mean something more general than OO. But that doesn't change the basic design approach. It's also true that they are careful to teach more primitive concepts first, so what they do is compatible with the OP's point. But there's a reason why the above passage on real-world representations appears immediately after they mention modularity.
- thomasz 13y agoThe key here is p. 217. Examples and Exercises that come before p. 217 are: - Square Roots by Newton's Method - Testing for Primality - Arithmetic Operations for Rational Numbers - Extended Excercise: Interval Arithmetic - A Picture Language - Symbolic Differentiation - Representing Sets - Huffman Encoding Trees - Symbolic Algebra SICP teaches algorithms and data structures before that quote. And goes on to teach more about data structures without doing any of that awful OO modeling exercises you typically do in a typical Java Programming 101. >But there's a reason why the above passage on real-world representations appears immediately after they mention modularity. After that quote, you return to data structures. Okay, after lists, queues and tables, there is a chapter about simulating digital circuits, which is both a fairly abstract and a well defined thing. Well, we can disagree on how abstract a digital circuit is, but at least we can agree that its no fucking dog that is_a animal and has_a head and has_a leg array and methods like bark(int howManyTimes) { for (int i = 0; i < howManyTimes; i++) println("woof"); } Using OOP to model real world stuff wouldn't be so bad if it would happen in the context of real problems, like simulations where you can show how to use the state pattern to model behavior. What I want to see gone is that stuff like inheritance and composition is explained with examples taken from the physical world, completely detached from the programming practice. If you use File, Directory and FileSystemEntry as examples for a hierarchy, you can demonstrate it's usefulness with concrete examples. With Dog, Frog and Animal, not so much.
- fiatjaf 13y agoWriting complex classes which require inheritance is never a necessity of a begginer. He can only know that objects encapsulate values and methods and that's all. When he needs inheritance he will know about it.