Monthly Archives: February 2009

OO for Oldsters

Most of the developers on the SnupNow team do not have much background in OOP. Most cut their teeth on structured programming techniques. Some, like me, started programming before they even heard of “structured” techniques and learned first hand the cost of maintaining spaghetti code.

Switching completely to OO thinking from structured programming thinking is non-trivial, but that doesn’t mean that understanding enough about OO to start coding or read the code of others is difficult. This short introduction is geared to seasoned software developers who just don’t happen to have OOP in their bag of tricks to date. It uses InterSystems Cache’ examples, since that is our platform of choice for this project.

I’ll add a quick disclaimer that the average theorist and perhaps even practitioner might really dislike me putting OOP into old terminology in a way that is not precise. I am painting a picture that might add light to some aspects of learning OOP while potentially obscuring some other areas that are not the focus. For example, I will not talk about the heap and the stack. I won’t even mention references. This introduction will focus on a high level way a developer can think about their coding efforts, rather than on the details of how the machine works. In spite of this disclaimer, I just know some of you are going to shudder when you read the next sentence, but at least it should irk both OO and relational purists alike.

Description of Objects

Objects are named records in memory. They could be persisted, of course, to some secondary storage device, but even if they have been, they are in memory once the programmer is working with them. They have properties, which might be called members or attributes, but let’s just call them fields, OK?

Once you catch on to objects being records with fields, there is a bit more to add to it, but before we do that here is some motivation. Why would we want records that might not be persisted? Stored records are at the “back end” of the application (I lost some DBMS folks there, right?), but there are lots of nouns at the front-end too. When working with a browser user interface, for example, we have web pages. These pages have elements, some of which might be combined together and maybe even mapped to virtual records (objects) to form a component, as we do with the Cache’ Zen framework. Working with records throughout your software means that you can model nouns everywhere: front-end, back-end, and everywhere between.

Thinking procedurally about software with a user interface, we have a user invoking some software, which starts to run and then shows the user something, collecting information from them, which it manipulates and then interacts with a DBMS to store data, for example. Thinking in objects, the user still invokes something, we still show the user something, collect information, manipulate it and persist it. The verbs don’t go away, but the nouns get more visibility. The user arrives at a page on our site and fills out a textarea on a form. They trigger events, such as changing values on the page, moving the mouse, or clicking a button. Do you see how some verbs got rolled into the noun “event”? We can work with virtual records of data that back a page, and can think in terms of such objects as the pages and their components as well as the database files, records, and fields (tables, rows, and columns, if you prefer).

I mentioned that objects are named. When using a framework like the one we use from InterSystems, some objects are created and named by the framework, while most are still named by the application developer. The Zen framework gives the name %page to the object that is the page when that page is in memory on the server. It is named zenPage when we are referring to the page object from JavaScript running in the browser. This page is the html page the user sees in the browser window. One property of this Cache’ Zen page is layout and another is height, for example. Those with a background in MultiValue software development might be delighted to hear that another is children with a definition of “property children as list of component.” Read that as “components” and you get the idea that these records have both single and multivalued properties and that these properties can be of many different types, not just strings and numbers.

On to a Class

Let’s toss some of the other OO terms into the mix now. An object is an instance of a class. A class is–oh man if I were closer you would slap me (and you know who you are)–a program. It is source code, then perhaps bytecode or object code once compiled. It is a program that defines a type of object. It is the definition for our records in memory, whether a virtual or stored file definition. One instance of a class is an object just like one instance of a file is a record. The class is the definition of the object, the metadata, the spec for one type of record.

In case it helps to redeem myself after offending just about every purist reading (I’m hoping they simply are not reading this), I will say that I do not explain OOP this way to youngsters, just seasoned pros. With those starting out, I talk about modeling objects in the real world with objects in the computer and blah blah blah, the usual sort of introductory material. But I’ll continue with the previous approach by indicating that typically at the top of this program, called a class, is the data dictionary, the list of properties. There can be zero properties, unlike typical persisted records. So, there must be something else to it.

Yup, code. An amazing amount of the code in a class is just structured programming code, sometimes with more complex objects being manipulated in addition to variables of string or integer types, for example. The variables used in our code can be strings, collections, such as lists or records, or objects, those records in memory already mentioned.

Still Procedural, In Spite of Itself

When I was first teaching myself OOP, I had a question that took me a bit to figure out. I didn’t understand how a software application got started when all you had were these classes, these nouns. I found out that you could make one class that would be the application, the big kahuna, with all other class code coming into play from that one. That application was still a thing, a noun, however. How did you get it to do anything? I figured you had to start somewhere and progress to somewhere else, procedurally, and yet we seemed stuck with nouns.

Here is the secret that I’ll share in Java, only because I have not needed to learn the Cache’ syntax for this. In Java, a class can have a “main() method” declared by the cryptic public static void main(String args[]) declaration, which we might think of as a MAIN: label in the program. If you launch this class (not all classes can be launched), and it finds this main method, it runs it. It runs it like you would run a BASIC program, starting at the top and exiting at the end of this method. There you have it. All OO applications are written procedurally, start to finish. Object-oriented applications start somewhere and end somewhere, just like any other software applications. They have if statements and the usual cadre of control structures. They have variables and assignment statements. It is just code, not magic.

A variable in a method can be of any type. Types are defined by classes. So, if I define a class called P.Person (we can talk about the dot in that name later), I can have an object identified with a variable name, such as myPerson, that is an instance of this class, a P.Person record, so to speak.

Our classes have code along with fields. We can run this code from our programs (other classes), much as we might run subroutines. This code is available to be run once one has one of these objects in memory. It is written in the form of functions, sometimes called methods. These functions are like subroutines where you can pass in values and get values back in return, adhering to the specific syntax for declaring them and running them. They are typically shaped in the form of a function such as myFunction(thisInput,parameterList) returns a String. In Cache’ a method declaration might be:

Method getAge() As %Integer

If this were a typical subroutine or a function from structured programming, we would pass in a parameter, which could be done in OOP and which we would do in this example if we were using a class method, a method that does not assume you have an instance of this class in memory. That could be declared as

ClassMethod calculateAge(BirthDate) As %Integer

Instead of passing in the BirthDate, if that birthdate is part of our object (a property or attribute of the object, aka a member of the object), then we need not pass it in, we simply have to indicate what object to use and it has the birthdate. If our class is called P.Person, we might create a new instance of it (a new record) with

myNewPerson = “P.Person”->%New()

in Cache’ using MVBASIC enhanced for OOP. We could then continue with something like

myNewPerson->BirthDate = “04/06/1956”

and then (for the sake of this example) decide to show the user the age of this person by executing the code from the getAge() method as

print “The age of this person is ” : myNewPerson->getAge()

If using a class method from any class instead, you could write

print “The age of this person is ” : “AnyClass”->getAge(“04/06/1956”)

See how that works? You can call class methods as functions without needing to have an instance (object) of the class they are in, while you call regular or instance methods by using the name of the object that is an instance of that class and then calling (with an arrow in this notation, a dot in Java) the method “on” that object and from the class that defines the type of object this is.

When you read class documentation, you are reading program documentation telling you the properties (fields) for an object of this type and what functions you can call, whether with an object (instance methods) or without (class methods).

One JavaScript method that classes that are Zen pages have available to use (meaning that the method is defined in the page class or in a superclass of the page class, but I won’t get into that hierarchy right now) is the getComponentById() method. If we have a component with an id of “personForm”, for example, we can have a variable called myForm that is an object and make an assignment (now using a dot instead of an arrow):

myForm = zenPage.getComponentById(‘personForm’);

There is a synonym for this of zen(). So, in JavaScript in a Zen page, we can write

myForm = zen(‘personForm’);

The object named myForm is in memory in the browser now, having executed the getComponentById() method from the page object named zenPage. Using Zen we can do this same thing in another language of our choice on the server when appropriate (like when the page has been generated on the server, before we show it to the user), using MVBASIC, for example, with the statement:

myForm = %page->%GetComponentById(‘personForm’);

MVBASIC enhanced for objects makes it easier to work with the more complex (than a string) nouns on the front-end of our application, such as a web page and its components.

Advertisements

Software as Good as American Pie

Three and a half hours down the highway here a celebration is taking place in memory of Buddy Holly, Ritchie Valens, and The Big Bopper, who played their last concert in Clear Lake, Iowa 50 years ago tonight.

We got some good news last week that the University of Iowa will have students do some marketing research for SnupNow this semester. I had paid a student intern at our local college to assist me with some research at the start of the company, but not enough to get to the point of financial projections that I would ever show to someone else. I have never believed any financial projection I’ve ever read from any project. I don’t like reading them, nor do I like preparing them, but the students will not do that for me, just help to bring this horse (that would be me in this analogy) to water.

I need to waffle less regarding how fast this project will go, when the software will be delivered, prior to pursuing funding, should I decide to do so (I guess I waffle on that question too). That answer depends quite a bit on the resources available for the project, right? Some such resources depend on the amount of funding. The funding amount depends on having answers to questions about how fast the project will go.

When will we be delivering software? I have been thinking that it will go to pilot sites, but not go to general availability until after we have received some funding. It just seems like a really bad idea to be supporting real users with no one who gets paid. On the other hand, it is easier to pursue funding when you can point to a number of people using your software already. In that case, if we can get people using it and also paying for the service, then the specifics of the funding might be different.

In any case, the approach I am not taking is the one made famous by silicon valley, where you get venture captial (I have no plans to pursue such), shoot for the moon, then either reach the stars or crash and burn, as Buddy Holly’s plane did on that fateful night.

With the speed at which we are going right now, it is clear that I am not taking that “shoot the moon” approach. I think it was Philippe Kahn of Borland fame who said “Delivery is a feature” but I could not find confirmation with a quick internet search. I agree that delivery is an essential feature of our SnupNow software that we are currently lacking, although we do “deliver” our builds to a user experience testing area. Adding in the delivery feature to software that does not have sufficient features to be useful would not be a virtue, however. Delivery is not the first feature of any software. If it comes too early, you can crash and burn.

Another way to crash and burn is to take off without enough lift in the form of people to support the speed at which you will grow. I have considered this past week that if I were to add up all of the hours I have spent in trying to get others on board working with me, so that we can write and support something bigger than me, these hours would significantly exceed the amount of hours from all others working on it. That might seem ridiculous, but it really does take work to make work. It also has taken and is taking me a lot of hours to learn the toolset I chose, with more hours spent teaching it to others. Other than the hours I have spent producing software, Tom has spent the most hours, with Ken coming in second, and all others well behind, spending time learning and getting onto the runway, but not yet really taken off by adding many features to the software to date. While I am hopeful that improvement on this front is coming (John has been writing some code this week and Bobby plans to this week too), the payback to having others work with me on this project is yet to come.

That brings me to another well-known quote from Kahn, which wikipedia tells me is from his keynote address at COMDEX 1992 and says “Philippe’s Law states that the productivity of a software developer in a team of N people is diminished by dividing it by the cube root of N.”

So, if I were to have been heads down writing the software last year, I would have completed let’s say 1 whole piece of software. Since there are 5 people on the development team right now, a quick estimate would be that we would get roughly 3 developers worth of progress. However, what we have are after-hours hours, not full-time members of the team, with the total hours not even adding up to a single full-time person, plus me with my productivity diminished by coordinating with each and all. My estimate is that I could have been five times more productive in writing the software on my own than in bringing others into the project so early. Instead of 1 for me solo, I think our team with me included ended up with about a 0.3 for 2008. Can you tell I’ve pondered the wisdom of my “get others involved” approach?

Unlike a pie, however, software doesn’t get made and baked by a baker and then eaten and gone. It is also not like the song American Pie about 50 years ago tonight, after midnight on February 3, when the music died. It cannot be written once and then used forever that way, even played repeatedly with Don McLean singing it (and me singing along). Software is developed and maintained over time. I could both bake a pie and write a song today, in theory at least, although both would lack the quality I would wish for in a pie or a song.

I want this software to be as good as American Pie, and taste as good as American pie.  If I did write this software on my own, I think I would have trouble getting that delivery feature in there in such a way that the customer base could grow. I would get myself into a bind, I’m quite sure, I think, most likely, perhaps.

One way that I handle so many differing opinions (even when only considering my own) on topics of when to deliver, how to get to delivery, what features to have when we deliver, how tight the software needs to be, and whether I should just sit myself down and do more coding in a week and less talking with the other Snupnow LLC owners is to focus on what we are doing, and try not to worry about the speed.

Of course, I do worry about the lack of speed. While I sometimes remind myself that “slow and steady wins the race,” and “haste makes waste,” or even “a stitch in time saves nine,” I do want to go faster than we are going right now, so that I can have some confidence in making good future projections that are still within my expected lifetime. This weekend I mulled over issues of what-they-call-human-resources, aka people. Could we use more? Less? Different skillsets? We do not yet have a high-productivity team, even if each individual can be productive at times. Right now we still somehow need to pick up enough speed to get off the runway, start to fly, and reach that delivery destination. I know we will, but today is also a reminder that, alas, that does not always happen.