The Schizophrenia of Object-Orientation

Why Object-Orientation is More than One Paradigm

Until recently, I believed that object-orientation is a paradigm that contrasts e.g. the functional or the procedural paradigm. I imagined that everybody who worked in an object-oriented fashion had more or less the same ideas, beliefs and views. On the other hand, I often discovered that I found myself misunderstood in the community of object-oriented developers, and that I did not relate to what they were talking about.

Then, I heard Richard P. Gabriel (at: 33:30) say (roughly): “When there is a shift in paradigms it is impossible for either side to understand the other. And there is a shift in paradigms: from Object Oriented Systems to Object Oriented Languages.” – This resonated deeply inside me. Both sides use the same words and idioms and yet they talk about completely different things. They talk and talk and …

…they don’t even realize that they don’t understand each other. Just sometimes they notice that something isn’t working.

To give you a picture of the situation, I guess it’s easiest to show you how Nicole and I approach the topic. We experience this difference very often, and I believe I am representing the “systems” side while she stands for the “language” side. We usually call this the “dynamic” and the “static” view on programming. In this article, we try to demonstrate each of the extreme positions.

Let’s start with a look at my perspective.

Software is Composed of Small Interacting Parts

Andreas: To me, software is a “living thing composed of small parts interacting with each other”.

If I code a class, I look at it as a small program, a self-containing entity. I want the class to show clearly how its instances (the objects) can interact with other objects and I want the objects to interact with others. I don’t focus on types or state. In fact, after more than 10 years of Java I am still annoyed by the static typing Java forces me to declare. When designing properties I am method centered, not field centered. To me a field is a necessity, not a value in itself.

But this all is only building the parts. A software that is not running is just dead code, not software. Push the “run” button, man, execute it! – As soon as the program starts to execute, its parts start interconnecting and interacting. And that is the real game! Messages sent from here to there, bytes flowing at incredible speed. This is what makes it fascinating to me. – All the coding is only a really primitive way to prepare the stage for the actors.

What does it look like on the other side?

The Beauty of Software Lies in its Construction

Nicole: 
My main fascination in software development comes from the theoretical underpinnings, especially type theoretical ones. They convey a sense of truth, truthfulness, reliability and provability, which is what I am striving for.

The programming language, especially its syntax together with its underlying concepts, is very important for me because it determines how I can express myself. It determines not only what I can state, but also in which way I can state it: Does it bring forward elegant and crisp formulations, or is it clumsy and talkative? What does it allow, what does it restrict? How many errors does it already uncover at compile time?

When actually coding, I am fascinated by finding a balance between shaping the code to be simple and understandable, shaping algorithms to be elegant and efficient, shaping objects to be encapsulated and self-contained, and integrating all this smoothly into the existing codebase.

But when it comes to trying out the code by running it, my first thought is “Why? I’ve already created this beautiful code, isn’t that enough?” Until now, it has not become second nature to me that I need to run my code.

In fact, actually running my program sometimes gives me the creeps because suddenly tons of strange things happen. That’s why I try to control many aspects of the code statically: Errors that can be caught at compile-time need not be caught by running the code… And no, I am not talking of Java’s lame attempts of static typing here! I have something more powerful in mind, something that is e.g. offered in functional languages like Haskell.

Diving Deeper Into Words

Let’s have a look at some well-known words and try to find out what their meaning is in the eyes of Nicole and Andreas:

Interaction

Andreas: Interaction is the sending of messages from one object (or group of objects / module) to another.

Nicole: What Andreas describes is merely the taking place of the interaction at runtime. In my opinion, this cannot happen unless the interaction has been defined statically by how the code is interconnected, e.g. which class possesses a reference to an instance of which other class, which method implements the invocation of some other method on some reference and so on.
Therefore, the static definition of interaction is a prerequisite for its taking place. Interestingly, different static definitions can lead to the same runtime behavior.

Structure

Andreas: Structure ist the topology of the object network, looked at from a static point of view. Structure is the basis for interaction. This concept is closely related to the static code, but relevant at runtime.

Furthermore, structure evolves from the layout of code units. It is very important where your code is located with respect to classes, packages or modules (in the sense of e.g. an OSGi-bundle or Eclipse project). If your code is healthy there will be identifiable modules. Structure defines which module accommodates which code. Structure also describes the dependencies of the modules.

Finally, structure defines the possible interactions at runtime.

Nicole: If I hear the word “structure” in general, I mainly think of the structure of the type system, namely how classes and interfaces are related to each other hierarchically. I do not regard as “structure” the connections between classes that are established via composition or aggregation. Therefore, structure and interaction are orthogonal concepts for me.

If some context is given, it may change my understanding of the word “structure”. If we e.g. talk about “package structure”, my understanding of “structure” gets much closer to Andreas’ description of code modules.

System

Andreas: A system consists of the interactions that take place on the basis of a structure. In a system, I can concentrate on static and/or dynamic aspects of a given (sub-)system, namely by focusing on a certain area of the structure or on certain interactions.

For example: A very small system is defined by a unit-test. The term “system under test” shows that very clearly. The smallest possible unit test describes also the smallest definable system in your code.

Nicole: The expression “system” is quite alien for me. When I think about its meaning, I get to something like “application”, where the application represents the “overall system”. An application can interact with other applications, this way forming a larger system. A part of an application, on the other hand, like a class in a unit-test, does not represent a system in itself.

So what?

It took us several weeks to write this article because we had so many long and intensive discussions around the topic. We’ve learned a lot about each other and ourselves. In our daily work it helps us to know that we – and probably our co-workers as well – have biased views of reality and especially what these views are.

This diversity of views greatly enhances our lives. It is our choice to see it this way.

Now find out about yourself. Ask yourself:

  • What do you think of this duality of object-orientation?
  • Which of the two views is closer to your own view of the world?

And then discuss with others!

Enums considered a codesmell!

You are luckily using enums? You think it’s one of the major improvements to Java in 1.5?

Let’s have a closer look at them. What problem do they address?

  • I can now switch over something I can define. – Great (moan) – But why would you like to switch?
  • Because switching is better than doing if statements. – Why do you have procedural decision logic?
  • It’s clearly readable. – If you are used to procedural style, maybe. But…

… Be honest: Didn’t you ever have to deal with code splattered with identical or similar if statements all over the classes?

In my day-to-day work I see even worse use of enums: The enum construct is misused as a singleton container. Yes, you’ve read correctly: a singleton container. It looks like that:

public enum SingletonContainer {
	Instance;
	
	public void aRealCoolMethod() {
		// here we do the singleton's logic
	}
}

public class UseTheSingleton {

	public void useTheSingleton() {
		// some logic
		SingletonContainer.Instance.aRealCoolMethod();
		// some more logic
	}
}

What a creative way to use enums! – Oh, by the way, did I mention that we are inside a multi-threaded web application?

But that is not the main reason why enums are evil.

Enums are just an easy excuse for not creating the right abstractions. They are handy to use, simple to understand and readily available. But all this does not make them more important than closures, absence of primitives, real generics and many of the other features Java is still missing. The concept is just
a waste of bytes. There is nothing essential that couldn’t be done without them.

We can do it better:

Every enum is a plea for a type. An enum is a type, of course, but…

… Have you ever implemented polymorphic behaviour inside an enum? It starts like that:

package pack;

public enum Showcase {

    First {
        @Override
        public void methodHasToBeimplemented() {
            // do some type specific logic here
        }
    },
    Second {
        @Override
        public void methodHasToBeimplemented() {
            // do some type specific logic here
        }
    };

    public abstract void methodHasToBeimplemented();
}

And now continue following this approach:

You’ll get more and more methods; you’ll get more and more enum constants. Your file will start to cry for relief!

If you look at the compiled classes you’ll find three:

  • Showcase.class
  • Showcase$1.class
  • Showcase$2.class

This means that the compiler knows what you really want: different classes. Why didn’t we do that by our own? – We only lose one thing: We cannot switch over instances of these classes any more. But we got rid of our implicit singletons and can put all the logic into the classes where it belongs. Then we can invoke the methods on the proper objects and have no need for switch statements at all.