(my catch on) Object-oriented programming methodologies

overview

Let’s just abbreviate Object-Oriented as OO.

Together the OO methodology is a software development methodology, developed in the late 1980s, with the goal of dealing with complexities of modern programming problems. It comprises:

The analysis involves breaking a real-world problem into conceptual parts, the design deals with identifying those problem concepts and assembling them in a consistent, coherent way amenable for programming, and the programming part involves translating the design to code in an OO language.

Problem: conventional software consisted of a long list of actions and logical decisions, to be applied to inert data. As programs expanded, the logic of their code usually became impossible to follow.

The logic of conventional programs would often go into “modes”:

”if in such a mode, do such and such to certain data;
if in another mode, do some other thing to some other data”

This “modal programming” style was adequate for rather simple programs, but became very cumbersome in modern programs that deal with many things and interact in complex ways with users and other entities.

Also, the conceptual information about the real-world problem was typically buried and diluted in code — by the same token, information about a specific aspect of the program was commonly manifested in logic laying in widely separated regions of the code. This is naturally fragile situation: a small change in one place of its code may have unfortunate consequences somewhere else.

OO Idea: directly model real world things, and their relations.

In OO terminology, the programmatic models for things are called objects.

The program consists of a collection of declarations of these objects, and when it starts, usually a single object is created, which goes on to create other things.

The objects are (or are meant to be) relatively simple internally, and only know about their internal behavior, and maybe a little about the other things with which they most closely interact. They encapsulate the properties, behaviors and relationships of the real-world entities they model.

In this idea, an object maybe contains data, and is responsible for dealing with that data. Other code must go through the object’s “interface” — mostly, this is done by calling functions that are associated with individual objects. This “hiding” of the object’s data is called “encapsulation”. It is a way of decoupling of different parts of the program.

So instead of dumb data being acted upon by a very complex program, these simple objects are meant to interact in ways that reflect the interactions of their real-world counterparts.

Old idea: have some data; code does stuff to the data. New idea: model things (which ultimately are related to data) which interact with one another. This is more like how we think of the world, of the problem we are trying to solve by programming. Because the code reflects better the way we conceptualize the problem, it is easier to understand, to extend, and to optimize.

Linguistically speaking: old programming consisted of command-form verbs (functions) that acted on nouns (data):

”do this to that, do this to that”

OO programming adds subject nouns, which may have intransitive verb “behaviors”

”this performs such an action”

and relations to other nouns by means of transitive verbs:

”this thing performs an action to that thing, that does something else to another thing”

So OO provides a much richer syntax for describing the real world.

characteristics of OO methodologies

Several programming methodologies preceded OO programming, some of which included ideas like encapsulation. (This is called “modular programming”, and can be done very profitably in C.) The difference between OO methodologies and all that came before is a very important relationship called inheritance, by which the notion of “kinds of things” can be modeled, the relationship that one thing is a kind of a bigger group of things; as a dog is a kind of animal.

The primary characteristic of OO methodologies is the idea of kinds of things that inherit properties and behaviors from other kinds.

The other way of looking at inheritance is that objects of a single class, say Animal, can come in different kinds (Human, Dog), which have different properties and behaviors. This is called polymorphism. Human and Dog are different forms of Animal.

Often a program needs to deal with several different kind of a thing, each of whose behavior differs from the general behavior only in a few specifics: a woman mostly does things all humans do, but there are a few behaviors and characteristics that set women apart from other humans.

In OO terminology, a “kind” is called a class, and an individual of certain kind is called an object of its class. The class is the abstraction, the object is a concrete example of the class. The class declaration describes data and functions that are attached to the individual objects — these are called object methods, as well as the data contained in the object, its members.

Now, kinds of things often form an inheritance hierarchy: maybe an obvious one is the hierarchy of living things (whose members has its own distinct ancestral hierarchy )

Fish, Dog and Human are all kinds of Animal.
Dog and Human are kinds of Mammal, and in turn Mammal is a kind of Animal. But Fish is not a kind of Mammal.

In OO, Fish, Dog and Human are subclasses of the class Animal,

Human and Dog are “subclasses” of the class Animal.

Other terms for subclass are derived class or child class. Animal would be the “base class” or “parent class” of all the other classes mentioned..

examples of inheritance and overriding of behaviors

Consider a class Graphic (modeling perhaps things drawn on a computer screen). This base class defines methods draw() and move(), and all the subclasses inherit these. But subclasses Circle and Square override the draw() method, to produce quite different shapes on the screen — but they might implement the move() method in exactly the same way. The Graphic class might define a method rotate(), which by default does nothing: Square would override this method to do something, but Circle might not.

In business applications, people are often divided into different subclasses: Person might have names, a current mailing address, and phone number. Subclasses of Person might include Employee, Customer, Business Contact. An Employee might have a special employee number, and instructions for paying. Customer might have means for investigating current and past orders. Business Contact might be related to a separate class, Company. Employee might have a further subclass of Manager, which is related to another separate class of Department. But all objects of class Person, regardless of their subclass, have names, address and phone number, available in exactly the same way, because they inherit those properties.

The set of classes and relationships for a particular problem is entirely a matter of problem analysis, which is largely a matter of art or personal taste. The trick is to capture what is essential about the entities in question, as well as properties or relationships that might arise in “corner cases”, while not cluttering the model with structure immaterial to the problem being solved.

For example, a model of vehicles: the base class Vehicle all have behavior go() and stop(), but how different vehicles go about these things varies widely. Not all vehicles have wheels. Not all carry passengers. Given the problem at hand, what is essential and important about different kinds of vehicles? One important distinction might be, does the vehicle carry passengers or not? Does it have a driver (pilot,captain,...) or can it be automatic? Or are the vehicles in the programming problem naturally limited to certain kinds, say, motor vehicles for use on roads and highways?

OO programming language features

In OO programming, the code defines the class. When the code is run, objects of the class are created (or “instantiated”). So classes exist in the code; objects come into being at program run-time.

The code for a class is self-contained: conventionally, it’s exactly one code file per class. (In Java, this convention is enforced.) In well designed OO code, to find how a class behaves, you need only look at its code, and that of its parent classes (there usually aren’t many).

The first result of OO programming on code is that the code for a subclass is concerned only with how it differs from its parent class. This can vastly simplify the making of a new kind of thing. Second, the bulk of the most complex and error-prone code in older programming styles is a deep “modal” logic of

”if in this mode, do this, if in some other mode, do that”.

Instead, things behave the way they do because of what they are, and because of the relationships they have. Most of the ugly modal code is absorbed into the relationships of the class structure.

(By the same token, OO code looks so different from older code that seasoned programmers are bewildered, and think they’re being fooled: “Where’s the code? I only see a bunch of declarations!”).

OO programming languages have special syntax for defining classes, subclasses, and for specifying what parts of an object can be accessed from what other parts of the program.

One special feature of all OO languages is a constructor, which is code that initially creates an object, so that each object is created as a fully operational, consistent entity. (The other end of this is the destructor, which performs cleanup when an object is destroyed. But this plays a smaller role, and in some languages, is scarcely ever seen.)

learning OO

OO isn’t easy to get your head around, especially if you’ve become comfortable with older programming styles. You have to accept that there might be a lot more to learn, and you have to unlearn a lot. You aren’t likely to grasp the main idea overnight, and it make take months of practice to get good at developing code this way.

But for professional software developers, it’s well worth it.

I remember my own first experience writing a program in OO style. I fumbled around to produce a meaningful class structure as I’d read in books, fumbled more with the general programming environment (I think it was the old Borland C++ compiler on Windows), and found myself looking at a bunch of small files, each containing very little code. Then I fumbled to fix a bunch of syntax errors. And then... it ran. I couldn’t believe it. I had written so little code, mostly a lot of declarations defining a bunch of objects. I knew there was no big “program”, no “main loop” — one object had made several others, and some of these had made some more, and they were all playing together as I had meant them to. As it was a small program, I could actually see it. I loved it.

Over the past couple of decades, OO has become the dominant methodology in programming. Nowadays, students in colleges and universities are introduced to programming in an OO environment, often using Java or Python.

In the interim, several of other big software development trends have arisen: “extreme programming”, “design patterns”, “functional programming”. Unfortunately, some people (ones who never learned what OO means) say these replaced OO. This is just wrong — these other trends address completely different issues than OO does, and OO is alive and well.

Some people put OO programming down, often vehemently. In my decades of experience programming in various settings, I have never met an opponent to OO who could provide even a rough description of OO.

If somebody says that OO

you may identify them as being ignorant on the subject. If somebody says they have never seen programming problems complicated enough to warrant such a fancy thing as OO ... they aren’t lying, but either they haven’t seen much code, or they don’t understand what OO can do.

Of course, it is also very common to see slow, spaghetti code written in OO languages. OO does not automatically make a better program, any more than it makes a programmer smart. And in a sense, its richer environment presents more ways to make a mess.

For good programmers though, OO methodologies is a powerful toolkit for making better programs. When done remotely right, OO code is in fact be much easier to maintain, extend, and re-use than older code was.

The OO way of thinking is moreover a useful way of structuring thoughts generally. I found that, after I got it down as a programmer, I started looking at a lot of things in the world differently.

For a program of any size at all, I would never go back to the old way. That would be stupid. Why hit a nail with a rock, when you have a hammer?