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
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:
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.
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.
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.
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!