Re: Existence Based Polymorphism
Richard Fabian <[email protected]>
| Newsgroups | gmane.games.devel.sweng |
|---|---|
| Message-ID | <[email protected]> |
I read those pages, and you clips and have now moved on to this site: http://www.artima.com/articles/dci_vision.html <http://www.artima.com/articles/dci_vision.html>This stuff is gold. Thanks. Also, I'm glad to say that a lot of the Role oriented approach actually sits well with the way I'm thinking about how data works. First glance and probably wrongly, I'm thinking of the idea of Interactions on Contexts as being very similar to building sql queries (build a Context via JOINs and WHEREs) on which transforms operated (Interaction as a MODIFY query). The mapping of decision tables to the parameter production processes in order to produce transform request tables almost seems as happy sitting in DCI as it does replacing C++ OO. I'm not finished reading yet, but I'm already glad I've started. On 3 June 2010 02:33, Bill Kelly <[email protected]> wrote: > > > On Wed, Jun 2, 2010 at 4:03 AM, Richard Fabian <[email protected]> wrote: > >> I've been thinking about this a lot over the last few months, and come > to > >> think that if OOP was not "bad", then there wouldn't be so many > "effective > >> C++" or "C++ gotchas" like books out there. How many "pitfalls of > procedural > >> development" books have you seen? > > On the other hand, as Alan Kay remarked: > > Actually I made up the term "object-oriented", and I can tell you > I did not have C++ in mind. > > ;) > > > Phill Djonov wrote: > > I've also been thinking about this recently. Ignoring the specific > > failings of C++, I'd say the biggest issue is that there seem to be a > > couple of very common misconceptions. > > > > The first is that a lot of people seem to implicitly think that > > inheritance is the engine of reuse, so everything becomes an > > "AbstractBaseObject" or some other nonsense, as though typing > > colon-public-base-class-name somehow magically causes reusability to > > rain down from the sky, washing half of your engineering work off into > > some gutter. Obviously this doesn't work, but people stick with it > > until you've got a 20-level hierarchy and nobody can remember what > > level foo() was declared at and whether it is (or why it is) virtual. > > At that point, things get worse, since the fact that nobody is clearly > > reasoning about what the code really is causes people to treat it like > > some sort of magic black box, invoking functions and setting > > properties in specific "sacred" orders at preordained times, and > > generally entrenching the details of the design so far into the > > codebase that it's near-impossible to fix things later. > > > > The second (and someone recently linked to some article or something > > that also brought this up) is that people have this "the class should > > reflect the thing we're modelling" notion stuck in their heads. Two > > problems with this. First off, that's usually neither a clear nor > > efficient interpretation of your concept into code. Second, it leads > > to thinking of base classes as abstractions in a very human sense, > > which is just *wrong* since ideas like "vehicle" and "four-seater" are > > circles in a Venn-diagram, and *not at all* nodes in a graph (let > > alone directed acyclic graph). Fine, a car is a ground vehicle which > > is a vehicle. Where do you stick the engine object? Does it belong > > anywhere in that hierarchy (what about bicycles)? Do you use multiple > > inheritance (making things even worse once the hierarchy has gotten > > deep)? At any rate, too many people blunder on through it without > > recognizing the fundamental mismatch between what they want and what > > their tool is capable of, making the mess bigger and bigger (and now > > we've added hasGasTank next to gasTank in order to accommodate > > Bicycle...) Etc. > > > > The most effective use of OOP I've ever seen (or achieved myself) is > > cases where objects are less "models of the real world" and more "Lego > > blocks" - because *that* is how you get reusable code. They should, > > IMO, be tiny little things designed to do one thing really well (the > > best metric I've found for whether it's small enough is mode-type > > properties - you should be down to no more than two bools or a small > > enum) and be assembled together into bigger constructs on an ad-hoc > > basis. > > Much of what you've said above reminded me of some recent posts > by James Coplien on the ruby-talk mailing list. > > http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/357461 > http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/357539 > http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/357705 > > I don't yet grasp Coplien's Data, Context and Interaction (DCI) ideas > at all well enough to attempt to summarize them. But I've excerpted > some paragraphs from the posts linked above, in the hopes that some > may find them interesting and perhaps relevant to the current thread. > > > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > The general approach to DCI is that objects should be pretty dumb. They > are just-barely-smart data, and are usually primitive. Over the years we > have been taught that objects should be smart and that their APIs should > reflect what goes on in the use cases. That creates several problems. > One problem is that rapidly changing use-case level logic is mixed in > the same interface with slowly-changing domain interfaces. Another is > that classes don't provide natural boundaries for the delineation of > mental models of algorithms (as DCI used to call them when it was DCA) > or interactions. > > An account is a collection of use cases. It is in the "I" part of DCI, > not in the "D" part. If you look at real banking software, the real > objects are transaction logs and audit trails. They become re-configured > in interactions on every use case, where the use cases are at the level > of a Context object called an account. Except for its housekeeping > references that set up the current role / instance binding at the audit > trail and transaction level, the account is stateless. Your bank account > is not a number sitting in memory or sitting on a disk somewhere, > anymore than your money is sitting in a bag on a shelf in a bank > somewhere. It is a computation: a use case. In DCI, we encapsulate those > in Contexts. > > ... > > The problem is that objects became really popular in the industry in > about 1990 and now everything that is a Thing has to be an object. The > naiveté was fueled by early methodologists who told us a number of silly > things: everything is an object; objects should be created in isolation; > objects are the nouns in your requirements document; and so forth. > > I think that's what got this thread started: I described a solution to a > problem that is more complex than people can conceptualize using their > grandfather's object-oriented programming, and understanding broke down. > I think that people fail to understand it's a paradigm shift — but > that's maybe a liability of taking one's understanding from a few hours > of videotapes. > > ... > > Another set of > immature foundations can be found in the Agile world where we are > supposed to be focused on the customer. And most of the naive claims > about accounts here come from that perspective. I can just read the user > stories and use those to drive my design, using TDD or something else. > Just find all the elements of all the interfaces and just organize them. > > The fact is that most of the computation in a bank has nothing to do > with someone who has an account, but who is in the back office managing > investments or doing analyses. They're called actuaries in English. > Actuaries care little about the status of your bank account. They care > about the transactions. > > There are many other sets of users who are looking at these data: > auditors, tellers, ATM machines, other banks, the national bank, > investors, loan officers, bank executives. All you need to do is to take > all the responsibilities of all those stakeholders and divide them up > into nice interfaces that give you nice objects that have nice coupling > and cohesion. It's intractably complex. > > DDD has recently drawn attention to the importance of unearthing domain > concepts that are stable over time. They have little to do with the > requirements of the stakeholders. Very few people understand that. The > "dumb" data objects of DCI come from this domain analysis; they are > often the model objects one finds in MVC. The intelligence that serves > the actuaries, the accountants, the loan officers and everyone else play > out in use cases that are defined in terms of roles — roles that are > mapped onto the right domain objects at the right time by the right > context. > > The essence of an object-oriented system is that the mappings from roles > to objects changes thousands or millions of times a second. Your > grandfather's OO simulated a very weak version of that called inclusion > polymorphism. The DCI mapping brings these dynamics to the surface. > > ... > > Do the following experiment. Go to someone who has recently done a money > transfer in their bank. Ask them to give you a general user story for > it. Inevitably, I find people saying, "I decide on an amount, and then I > withdraw that money from one account and put it into another account." If > they speak more precisely they will use terms like "source account" and > "destination account." A "source account" is not an object. It is a role > that something can play (like a savings account). > > For the time being we can pretend that savings account is a class whose > objects can play the role of "source account." That fits the simple > Kantian model of the world, where most things must be objects. But if we > go more deeply, to the level of that domain (in the sense of DDD) we > find that it is not an object — certainly not in the "D" sense of "Data" > in DCI. It is a collection of use cases, of behaviors. That makes it a > DCI context. An account is a context (like an account number) in which > we can carry out algorithms (like transferring money) with other > concepts (like other accounts, or transaction logs, or audit trails). > > Where I think you are confused is that you take these elements of your > mental model and call them objects. That was also what Kant does. To do > so is at least not useful, and probably isn't even right. Also part of > your mental model is the mapping from the roles "source account" and > "destination account" onto their respective accounts (my savings account > #O991540 and my investment account #393497654). Also part of your mental > model is those things called accounts, and you think of them as objects. > The problem is that the people who implement those systems don't > implement them as objects, but as something else — the objects are at a > much lower level. That's the real world of real financial software > today. Really. At least in my example — which I think is representative. > If you have a different example where an account can be an object in > memory, I find that interesting, but I don't think it's germane to this > discussion. > > One reason I can justify DCI as a paradigm shift is that it differently > translates the mental models of end users and programmers into code. > Something called object-oriented programming was one way of doing it in > the 1980s. This is another way of doing it, with different elements of > the model. And these elements don't come out of thin air. Rebecca > Wirfs-Brock and Trygve were having a discussion on the Hurtigruten about > ten years ago as I was listening, and they concluded that objects don't > have responsibilities — roles do. That is the essence of CRC cards. Most > people think that CRC stands for "Class, Responsibility, and > Collaborator." It does not. Rebecca wanted to call them RRR cards > (Roles, Responsibilities and Relationships) but the C really stuck. What > it really means is "candidate object," and it's a role. (I just verified > this with her when she and I went together to dinner with Trygve and > Gertrud at Øredev last year.) So you have an entire industry focusing on > classes because they misunderstood an acronym (or popularizers of the > technique misunderstood it – I won't mention any names). Focus on roles > — the roles that objects can play — not classes. > > There are other ideas I could bring to bear from the field of user > experience, from Brenda Laurel's writings, and from other staples of > object-orientation that the Java-duped public doesn't read, but take my > word for it. This is not the object-orientation you learned in college. > > ... > > But, again, object orientation is all > about capturing mental models in code, and we need to be attentive to > stakeholders other than the programmer. Like Raskin said: The interface > is the program. A user experience person would pursue this issue using > the kind of question I posed in an earlier post, leading to the > description (e.g., for a money transfer) that I think about things in > terms of source accounts and destination accounts. Unfortunately, my > bank doesn't have source accounts. I can conceptualize a source account, > but can't create one, can't open one, can't find one. They're not > *objects*. They're protocols, or interfaces to objects. They're roles. > Those, too, are part of our mental models. And they should be part of > the code as well. If you look at where Rebecca Wirfs-Brock has taken > responsibility-driven design, it is into this realm of roles. Objects > don't have responsibilities; their roles do. That was the conversation > that Trygve and I recall from his discussion with Rebecca on the deck of > the Hurtigruten all those years ago. There are some additional concepts > that we should be attentive to as well, including algorithms and the > associations from roles to objects. DCI packages most of these in roles > and Contexts. > > If all you have learned is objects, then everything to you is an object. > That is whey I said you might make a good student of Kant. A good > exploration of end-user mental models shows that they are much more > subtle. Introducing roles provides a much better match for this model > and provides a much better foundation for good software structure than > the pure object approach does. Trygve published some preliminary metrics > about this on object-composition, and you might have a look at them and > at the surrounding discussion. > > ... > > There is still a place for your > grandfather's object-oriented programming. There are architectures we > can call event-driven architectures, where the interesting operations > are all atomic. A shapes editor is a good example. It in fact has no use > cases. Most operations are atomic and trivial: "Change the color of this > shape." "Resize this shape." "Create this shape." Once in a great while > you might have operations involving multiple methods of multiple shapes, > and that's where DCI comes in. > > More broadly, not everything is object-oriented, whether DCI or your > grandfather's object-oriented design. Procedural design still has a > place. So do state machines — and that has nothing to do with objects > (for example, in protocol design). So does rule-based computation. So > does functional programming as in SASL or KRC. Anyone who attacks the > world with one weapon alone will be defeated. I wrote a whole book on > this several years ago called "Multi-paradigm design. > > Why did you think I felt that DCI was the only way? > > ... > > Given that it took me seven years to learn it, I can speak strongly for > the fact that it is a paradigm shift. That it is a paradigm shift has > nothing to do with its payoff — only with the mode of understanding. > > ... > > As to why DCI is > more than AOP, read my above long segment on mental models and > paradigms. DCI is not just a programming trick to reflect cross-cutting. > It can represent much higher dimensions of cross-cutting than AOP can > and, because of the Contextual mapping of roles to objects, is much more > dynamic. They are barely in the same league. I think you are confusing > one of the mechanisms of Aspects with one common mechanism used to > implement DCI in some programming languages. > > This, too, is the sign of a new paradigm: everyone tries to describe it > in terms of what they know. Some people say that DCI is like mixins. > Some say it is like multi-paradigm design. Some say it is like aspects, > some like dependency injection, and a million other things. What gives > me the most grief is that there is a tiny bit of truth in each of these > claims, just enough to keep people from making the necessary mental > leap. To do that requires digging into it and trying it. It is like > learning a martial art: no number of PowerPoint slides will get you > there. > > ... > > The real goal of AOP (I have this from Gregor > Kiczales personally) is to shock people into taking reflection > seriously. It was supposed to scare people from Java back into Lisp, > where you can express these things cleanly. Cutpoints and wrappers and > whoppers are native to CLOS, for example. The problem is that people > weren't shocked: they embraced the scaffolding. > > ... > > (Most languages can express DCI concepts in some > degree. There's only one popular language that can't, and I'll let you > figure that out. Class, that's your homework assignment for tomorrow.) > > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > Anyway - I don't grok DCI yet, but it's on my List of Things to Learn > More About... > > > Regards, > > Bill > > > > _______________________________________________ > Sweng-Gamedev mailing list > [email protected] > http://lists.midnightryder.com/listinfo.cgi/sweng-gamedev-midnightryder.com > -- fabs(); Just because the world is full of people that think just like you, doesn't mean the other ones can't be right. _______________________________________________ Sweng-Gamedev mailing list [email protected] http://lists.midnightryder.com/listinfo.cgi/sweng-gamedev-midnightryder.com