Why GUI Systems are Object Oriented?
In the previous post I talked about areas of software development where data is at least as important as behavior in the system design. Object oriented practitioners will contend that behavior is the most natural way of designing a system, and will give a number of examples where it works and the data-centric approach doesn’t.
In almost 100% of the cases they will cite GUI libraries as an example where data or functional design doesn’t work. And you know what, they are right.
The reason is that OO was created to model system behavior. And, at the same time, we don’t really care about what data is stored in GUI code (we can always store relevant data somewhere else). For the most part, we just want to operate on the UI in terms of its behavior: window open events, button clicks, menu selections.
As we have seen before, OO is an excellent programming methodology when data is not important. One can design the interaction between objects in a very simple and direct way. This is clear from the heritage of languages such as Smalltalk and Simula. Smalltalk was designed for direct UI interaction. Simula is a simulation language above all. In these languages, operating with data using a functional approach is not the main goal.
Lack of Behavior
The advantages of OO systems start to fade when posed with tasks that don’t require a rich behavior component. For example, a compiler is just a system that inputs source code and outputs binary code. There is not much behavior to be explored in such a system, unless you want to stretch the definition of events.
It is no surprise, then, that it is easier to write compilers in functional languages (although compilers are typically written in languages such as C/C++ due to the low level nature of the task). Similarly for numerical code, a lot of which is still written in Fortran and similar languages.
Data Manipulation
Another way to view the shortcomings of OO languages when faced with data-oriented tasks is the strange way it interoperates with data. In some languages, like C#, data elements assumes the form of properties. In general, the idea is to provide getters and setters to access data components.
Now, if you think about it for a second, getters and setters don’t make any sense. Objects were created to encapsulate behavior, not to provide access to information. If that were the case, why having an object in the first place? Objects have no business in storing information that should be accessed by outside code. Any object that provides such access is not doing enough with its data to justify its existence, unless the data is computed in some complicated way.
The real answer is that objects should not provide access to data. They should provide behavior, not function as storage areas. Java and C++ designers recognize this by talking about POD objects, which have no associated behavior (only getters and setters…)
What happens if you have a programming project that manipulates lots of data? In OO programming, you have to fake plain data use POD objects. It would be much more natural, however, to use a functional approach to develop the system.
Conclusion
Object oriented design is not a panacea. It provides little support for data manipulation. Instead of trying to fix its shortcomings through things like POD objects, maybe we should allow richer programming models that are not dependent solely on the use of objects.
Further Reading
Pearls of Functional Algorithm Design is a very solid book explaining how to design algorithms in a functional style
The Functional Approach to Programming is another book that explain the nuts and bolts of writing functional code.