Using OO as a Learning Efficiency Mechanism
Sis and I were piano students at the French School of Music in Plainfield, NJ during the 1970's. Our teacher Mlle. Yvonne Combe worked directly with famous French composers like Claude Debussy, Camille Saint-Saens, Gabriel Fauré, and Maurice Ravel. One of the many reasons for her success was that she required a parent to attend piano lessons, so that during the week students (especially the younger ones) could practice with some level of assurance that the next week's lesson wouldn't be derailed because they didn't follow Mlle. Combe's instructions properly. Looking through the French School archives, there were a number of students who gave their first recital at ages 2 1/2 - 5. It was fun when that happened, the whole audience would giggle. My sister gave her first recital at age 4 1/2. Robert Taub gave his first recital at age 3 1/2.
As a result, there were a number of times when my dad would attend our lessons, and because he didn't have a piano teacher anywhere near Mlle. Combe's caliber, he would immediately recognize the value of the tips and tricks she taught us during those lessons. Over a period of 20 years, he compiled those tips and tricks into a book called Fundamentals of Piano Practice, both in online and book form.
I recently finished reading his current version from cover to cover, and while he needs to fix some things for his third edition, he managed to pull off what none of us had the courage to do - he captured Mlle. Combe's efficient methods of piano practice, which enabled many of her students to play in Carnegie Recital Hall, attend Juilliard, become concert pianists, professors, etc. Many who didn't become professional musicians became doctors, lawyers, technologists, executives, etc. because those piano lessons and performing experiences gave more than a solid musical foundation, they instilled within students a sense of self-worth, self-respect and self-confidence.
The rest of this blog entry is an email I sent to my dad when I finally put my finger on why there were so many redundancies in his book, which I thought could be removed. It starts with some background from my earlier days in computer science, and is written in this way because, while my dad is a retired physicist with a PhD from Cornell and 6 patents to his name, he doesn't have a programming background.
Back around the early to mid 1990's I used something called Motif which was a toolkit I could use to create graphical interfaces. It had a way to create widgets like labels and buttons and textFields, and also had this concept of containers that could contain those types of widgets so that you could organize information on a screen. A RowColumn container could be used to customize rows and columns, which might be useful if you wanted to create a color palette. A Form container could be used to layout a typical form with labels and textFields for users to enter data, etc.
By 1997 I was learning Java. At first things looked familiar, I saw my usual toolkit for creating graphical interfaces, since the need for buttons, textFields and labels hadn't changed. But then I saw something weird in addition to the containers, a new group of classes called Layout Managers. I was puzzled because this was something I couldn't see, it wasn't “concrete” like a button or icon or label.
Yes, this idea of containers in Motif was cool. But the problem with those containers is that they were concerned with a lot of things:
- what background color, foreground color, how to draw it
- what x, y coordinate was the container positioned, what width, height?
- what if a container got covered, or partially covered, how would it draw or redraw itself?
- since it was more complex than the other widgets - not just a button, that meant it contained child widgets, so what do you do with those?
- if the child widgets were of uniform sizes, you could treat them in certain ways
- if the child widgets were different sizes, there were lots of choices for how you might want to lay them out
and on and on and on. So if you think about it, trying to create just a few, say 5 or 6 Motif containers must have been hard. You had to deal with all of these considerations. Given the complexity of the code, it was possible for rendering logic to adversely impact how the child widgets were laid out, or vice versa.
Those unwieldy containers weren’t particularly useful to developers like me trying to use those containers. We only had 5 or 6 of them. If a container didn’t do Exactly what I wanted, I was toast.
How was Java different? Someone realized the containers were trying to do too much, and split out different parts of the functionality:
- the containers were simplified such that all they did was focus on how they would render themselves: background color, foreground color, drawing, hiding, showing, resizing, etc.
- the designers then came up with this idea of a LayoutManager, an abstract set of classes that only made sense when used in conjunction with a container, that would manage the layout of the child widgets within that container
At first I felt mad, I saw this idea of a LayoutManager was brilliant, but I couldn’t figure out how they came up with this. Only by working with people with a Smalltalk background in 1997 did this slowly become clear.
The primary rule of object-oriented analysis / design / development is to identify and decouple logically unrelated functionality. The Java designers recognized that logic needed to render a container belonged together, and logic for managing child widgets had nothing to do with rendering logic, therefore those functions belonged together and could be separated out away from rendering logic. This led to all sorts of benefits:
- less code in the containers, and the excess code was transferred to the layout managers. Now if something goes wrong, it becomes clear - this is a rendering error, I’ll look in the container. Oh weird, the children aren’t laying themselves out properly, I’ll look in the layout managers. You’re not staring at this monstrous code in a Form widget trying to figure out where the problem is, what side effects are caused by two completely unrelated sets of code not playing nice with each other - rendering vs. managing children.
- what this does for people using containers is extraordinary. I went from having 5 or 6 Motif containers, hardcoded and calcified, to having 5 or 6 containers, plus an additional 5 or 6 layout managers. That gave me 5 x 5 or 25 different options that I didn’t have before, because I could mix or match them!
And it’s the fact that I now have a Cartesian product - a product set of options, not just a set of options - that makes this so powerful. So what happens when someone else realizes that the containers are still too unwieldy? Look, I just found another abstract concept I can pull out, and put into Fleebo Managers. And let’s say I now have 5 Fleebo Managers to choose from. Now that Cartesian product looks like 5 (containers) x 5 (layout managers) x 5 (fleebo managers) and I’m really off and running.
So how the heck does this story tie into your piano book?!
What happens when a new piece of information comes in like staccato practice? If you apply a Cartesian product between this new piece of information with your existing knowledge base, you automatically get a ton of new information to explore. Now granted, the Cartesian product represents the entire product set, and not all connections in that product set may make sense, so it helps to take the Cartesian product and begin applying research on top of it to validate what works and what doesn’t.
That’s why I (or anyone else) could immediately spit out: oh, staccato practice hands separate slow, then fast. Then try hands together slow, then fast, addressing any synchronization issues. Try playing staccato and soft, while relaxing the arms. Record multiple times in Garageband and listen to see if it's consistently uneven, slow down the tempo to exaggerate the unevenness so you know which parallel sets to use to fix, etc. That person may sound like a genius but they’re simply applying an efficiency principle that anyone can apply. And that’s also the trick to collapsing your book, because you don’t need to go through and discuss every single connection within that Cartesian product every time a new piece of information comes in. You simply have to explain this efficiency principle once, demonstrate how it works in a few places, and leave the rest as an exercise for readers to apply for themselves.
That way, you don’t have to worry about the redundancies, and can then focus only on the exceptions and quirks.