Object-oriented Programming (OOP) can be defined as a programming language model organized around “objects” rather than “actions” and data rather than logic. In other words, OOP focuses on objects that we want to manipulate in the business domain and assign behavior that manipulates the data encapsulated by these objects. A domain model is a visual representation of conceptual classes or real-world objects (domain objects) in a business domain.
Languages that enable OOP have been in the mainstream for three decades now. But with the introduction of JAVA and .NET framework, OOP has become widespread across the enterprise. Many business processes are being automated, and developers are increasingly using these languages.
But is the developer community using these languages as they were meant to? To illustrate, consider a fictitious scenario where a developer has been tasked to convert the program written in a procedural style to an object-oriented language say JAVA. How would he go about this task? He probably would refer JAVA material, understand the JAVA constructs and the principles of object orientation and then write the code. If he is motivated, he might look up popular design patterns (Gamma et al., 1994) and apply them where applicable. Once completed, the program would probably look similar.
What is Wrong?
In the example, OOP principles like inheritance (Larman 2002, p. 409) and polymorphism (Larman, 2002, p. 326), as well as design patterns have been used to organize code. But the classes in the example above do not have their responsibilities distributed appropriately. The domain objects in the code snippet above have data only. They do not have any behavior. Additionally, all the logic is concentrated in the ‘Manager’ class. The programmer has put in a lot of thought in writing the logic that satisfies the business requirements, but not on the domain model. The true benefits of object orientation have not been realized.
This is a pretty common phenomenon. Martin Fowler, author, and speaker describes this feature as ‘Anemic Domain Model.’ He says:
This is one of those anti-patterns that’s been around for quite a long time, yet seems to be having a particular spur of the moment.
So why are developers, after more than thirty years of popular object-oriented languages out there, still writing code that resembles code written in procedural style? A few reasons that come to mind are:
- The subjective nature of domain analysis and design make OOP hard. There are no step-by-step instructions to follow while modeling a business domain. Each business has its own set of quirks and exceptions.
- It is easier to understand the code in procedural style for particular business logic as all the logic is in one place as opposed to OOP where logic is dispersed in different classes.
- It is easier to code in procedural style as you do not need to figure out what which object to assign a particular behavior to
- You do not need to understand or represent the complex object relationships that are often the case in any real-world problem domain that the software is trying to solve
Due to this, developers often take the easy route and do not spend much time in modeling the domain. The downsides of these:
- The logic can be duplicated in multiple places as different processes are defined taking these objects into consideration. One can argue that the duplication can be avoided by extracting the common logic into common helper classes. But then you have unrelated logic sitting in these classes.
- Logic may contradict each other as they are dispersed in multiple areas.
- And because logic is dispersed it is difficult to make changes to the different processes.
What Can be Done?
Eric Evans notes that talented developers are more concerned with designing frameworks, rather than getting into the guts of a problem domain (Evans, 2003, p.4). This is mostly because gaining a good understanding to model the problem domain is a time-consuming process that requires immense patience and close work with the business stakeholders, which developers are either not willing to do or not given enough time to do so.
What then can be done to encourage proper domain design? For one thing, it is foremost necessary for an organization to realize that poorly designed model is indeed detrimental to the overall health of the application. It is required then to understand the state your domain currently is in and if it needs improvement, take the necessary steps.
When discussing solutions for the problem domain, an attempt should be made to present solutions concerning the domain model rather than the data model. This shift to domain model will encourage the developer community to think in terms of objects rather than just data that needs to be manipulated somehow.
An organization needs to understand and augment the skill set of its resources. Mentors and experts need to ensure that developers invest time upfront in organizing their thoughts around objects and their behavior. They should resist the temptation to rush ahead into coding the solution. In the example above if the payment logic is moved to the ‘Card’ class, it would make for a better design. The manager class then becomes just an entry point to the domain and it does not have any logic.
The important thing to realize is that there isn’t any single right model. There is always more than one solution. Different approaches can be taken, and they can all capture the problem domain accurately enough to solve the problem at hand as well as making it easy to extend it later on. One need not be afraid to undertake this process for fear of getting it wrong. Robert C Martin, founder and president of Object Mentor Inc, says “I’ve personally learned probably most of what I know based on either making mistakes or observing other mistakes” .
Over time object-oriented design will become second nature to the developer.
As cited in the fictitious example above, often a developer may not realize that there is anything wrong with the approach being taken. It is, therefore, necessary to understand the expertise level of your development team and offer training to ensure proper understanding. Ultimately, the developer community needs to accept and make a commitment to start applying an object-oriented approach to problem-solving.
Gamma, E., Helm, R., Johnson, R. & Vlissides, J. (1994). Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley Professional
Larman, C. (2002). Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and the Unified Process. Prentice Hall
Evans, E. (2003). Domain-Driven Design: Tackling Complexity in the Heart of Software. Addison-Wesley Professional