Today every vendor of an infrastructure brands it as “object-oriented”. In fact, the vast majority of infrastructures are – if one is in a very charitable mood – just object-based. If one is in a less than charitable mood, they are just function libraries where closely related functions have been bundled into “objects”. Worse, many such infrastructures actually violate basic OOA/D principles. Classic examples are Microsoft’s NET and Win32 infrastructures. (I often wonder if anyone at Microsoft knows anything about OOA/D.) Thus, the applications that use them are forced to design to them and that trashes the cohesion and encapsulation of those applications. One reason is that such infrastructures are often developed to make things easy for the infrastructure developers, not the infrastructure user.
One example is MVC, the Model-View-Controller. Originally developed as a RAD paradigm for Smalltalk environments, substantial infrastructures have been developed around it in IT for other OOPLs. Like most RAD applications, that works fine if things are very simple, like viewing data in a database in different ways and performing very basic updates on it. However, it breaks down as soon as the application needs to do some serious work and requirements start changing. One reason for that is that the Model, View, and Controller are completely artificial concepts in the developer’s mind, rather than customer space concepts. Worse, they are based on an overall strategy for processing data in the computing space rather than what the customer actually wants done.
That approach violates OOA/D doctrine in two ways. The solution is structured around the computing space problem of managing data rather than the customer’s problem of, say, computing employee benefits. That kind of structural divergence guarantees difficulties during maintenance. OOA/D doctrine says that the solution structure should map as directly as possible to the customers’ space. That’s because customer don’t like change any more than software developers, so they will implement changes in their space in a way that minimizes disruption of their existing structures. If the software structure faithfully mimics the customers’ structures, then when the changes filter down to the software as new requirements, the customer will already have done most of the work. However, if the software structure is based on an artificial organization like MVC, one is doomed to mismatches that will require unnecessary rework to fit the new requirements into the structure.
The second way the MVC violates OOA/D doctrine is the way applications are partitioned. OO applications are partitioned into subsystems that reflect logically distinct problem space subject matters. Since each subject matter has its own unique functionality, this allows requirements changes to be isolated. The larger and more complex the solution is, the more subsystems one will tend to have in the design. In the MVC approach, though, the infrastructure supports only three subject matters, regardless of complexity. In a large application, that can lead to subject matter implementations that are very difficult to maintain just because of their size.
There are a variety of RAD layered models similar to MVC that are commonly implemented and they all suffer the same problems due to their rigid and artificial structure. Most of the keystroke-saving infrastructures in IT are based, at least to some extent, on those layered models. One of the more common classes of IT infrastructure deals with allowing the application to talk to a relational database. Such infrastructures save a lot of keystrokes for the developer because they capture a lot of the grunt work of DB access. That’s because RDBs and their access are very narrowly defined so that very generic access tools (e.g., SQL) can be used. However, from an OO perspective, that is a major problem because those infrastructures must be accessed directly from the application code that is actually applying business rules and policies to solving a specific customer problem.
The difficulty is that RDBs are an entirely separate problem domain. Worse, they are a computing space domain, rather than a customer business domain. OOA/D doctrine says that such unique domains need to be isolated and entirely encapsulated behind an interface as a subsystem. The rest of the application that deals with the customer’s problem should have absolutely no knowledge of the RDB. Put another way, the rest of the application does not care if the data is stored in an RDB, an OODB, flat files, or on clay tablets. But as soon as the developer uses those handy infrastructures, that isolation is impossible and the RDB semantics bleeds into the rest of the application.
One can argue, “So what? In IT everybody uses RDBs, so why worry about it?” Well, in my career I have seen five major DB paradigms (flat files, ISAM flat files, CODASYL, RDB, and OODB). Each one caused great gnashing of teeth when mountains of legacy code needed to be upgraded. Maybe RDBs are the endpoint for IT. But look at the amount of legacy code that will have to be changed and tell me that the virtually costless isolation of the DB access in a subsystem is not methodologically good insurance against a modern day Codd showing up with a better idea.
This can be taken to even greater extremes. A couple of vendors provide infrastructures for doing things like queries and joins in an OOPL. IMO, that is a really, really bad idea from an OOA/D perspective. RDBs exist for a single purpose – to provide persistent data storage in a generic fashion. Access through an RDB is generally much slower than through an equivalent flat file system that is optimized for a particular application (that’s why RDBs are about as common in R-T/E as penguins at the Equator). What RDBs provide is reasonable performance for each of many applications accessing the same data for very different reasons. Constructs like queries and joins are uniquely suited to that sort of generic access. IOW, the RDB approach is an optimal solution for the multiuser, arbitrary data access problem.
However, a particular application is solving exactly one, very particular problem for the customer. In that situation, one wants optimal data structures and access techniques that are hand-crafted to the problem in hand. In that context, generic constructs like queries and joins are always going to carry a serious performance penalty compared to a custom design. That’s why one wants to isolate the data storage mechanisms in a single subsystem with a generic interface.
But from an aesthetic OO perspective, the problem is much worse than performance. The relationships that underlie queries and joins are table-based rather than row-based (Table:Row::Class:Object). In OO development, relationships are object-based. That means that one thinks about relationship navigation very differently in an OO context than in an RDB context. That difference will be reflected ubiquitously throughout the entire design because of the way messages are addressed and collections are formed. As soon as you introduce a class-based relationship navigation mechanism, you cease doing OOA/D entirely.