Bill Kohl's Object Oriented World

Bill Kohl

Subscribe to Bill Kohl: eMailAlertsEmail Alerts
Get Bill Kohl via: homepageHomepage mobileMobile rssRSS facebookFacebook twitterTwitter linkedinLinkedIn


Beyond Entity Objects

Modeling concepts with objects

Thus in object-oriented programming we have the view that computation is simulation.
-Timothy Budd

We have all read that objects are software representations of real-world entities and that one of the first design tasks is identifying these entities in our problem domains. These entities then become classes of our applications. However, the object-oriented paradigm allows us to model not only entity objects, but any abstract concept for which behavior can be identified. This article explores how to logically model abstract concepts with objects and why this will deliver higher quality software that is more maintainable and extendable.

Entity and Conceptual Objects
According to Merriam-Webster, an entity is "something that has separate and distinct existence." Grady Booch in his book Object-Oriented Design refers to "a tangible and/or visible thing." Common entity objects in business applications are Customer, Employee, PurchaseOrder, City, State, etc. Common practice is that db tables are represented as objects in the application (if not directly in the application, then in the translation layer between the application and the db). All of these are entity objects. They have a real tangible existence in the problem domain. Conceptual refers to objects that represent ideas that have no entity counterpart in the problem domain. They may be identified in the vocabulary of the problem domain or they may appear only in the solution domain as design contrivances for solving the problems at hand. Validation, process, and builder are examples of conceptual objects. Our desire is to separate the conceptual ideas from the entities of the problem domain by objectifying them.

Creating Conceptual Objects
The first object-oriented programming (OOP) language was Simula. As its name implies, Simula was used to develop simulations of real-world systems. The idea was to create software entities called objects that represent the entities of a real system, program each object to simulate the actions of its real-world counterpart, and then, through objects sending messages, let these objects interact to simulate the real system. Simulating entities with objects requires identifying the properties of the entity and its interactions with other entities of the system. If we were simulating a bowling ball, for example, it would have weight, shape, diameter, and color properties. It has interaction with the bowler who bowls it, the lane upon which it rolls, and the pins that it strikes. It would therefore respond to the messages bowl(velocity, spin) sent by the bowler, and roll(lane, time delta) and strike(angle) sent by the lane.

Simulating concepts works in a similar way. First we identify the properties of the concept, then we identify its responses to logical interactions with other objects. A list, for example, has its elements as properties. Its logical interactions would be to answer queries about its size or one of its elements, or add or remove an element. For an integer, its property is its binary representation inside the computer. Its logical interactions are asking for its string representation or to compare itself to another integer object.

Concepts Become Objects
Now we can say what the conditions are for simulating abstract concepts. When I talked about making lists and integers into objects, I asked the following: What are the properties and what are the logical requests (behaviors) we could expect of a list or an integer? These are the same questions we ask of any concept we wish to objectify. But these requirements, though simple, are too restrictive; they can be refined further. Before doing so let's review encapsulation.

Encapsulation hides data and implementation; it does not hide the interface. Where does that leave us with the required conditions for simulating concepts? It means that the only requirement for simulation is that we can identify logical requests (interface) that the concept object should respond to. There does not need to be properties for the object. Most objects do have properties, and we should still be asking the question: "What are the logical properties of the concept we are simulating?" Now, however, the answer may be none. An example would be a NetworkBuilder, an object that implements the rules for creating a network. The rules are pure logic and the NetworkBuilder object contains no properties. All the data contained in the network is passed in as arguments; the NetworkBuilder constructs the network and passes back a Network object.

Cohesion, Coupling, and Encapsulating Change
You've heard the dictum, maximize cohesion, minimize coupling (Structured Design by Ed Yourdon and Larry Constantine). These programming rules, originally formulated for structured programming, are equally valid for OO programming. A lesser known rule is to "encapsulate change" (Thinking in Java by Bruce Eckel). That is to say, those areas of an application that are most likely to change should be contained in as few objects as possible. Conceptual objects can help us accomplish both of these goals. I always begin by asking the question, "What is most likely to change in the application." If it's a business application the answer will be business rules and business processes. Based upon the rule to "encapsulate change," I would like to encapsulate business rules in one set of classes and business processes in another set. This would encapsulate change and increase cohesion since rules would have their own set of classes as would process. How do we do this? Rules and process are both abstract concepts. How can we create objects from them?

We could first observe that many business rules are applied by validating data entered into a system. The data may create new entities - a new employee, for example; or couple existing data - add Employee A to Dept. X. In either case, business rules are applied through validation, so validation becomes the concept we wish to objectify. Note that the examples I used above form two distinct cases for validation. In the case of validating a new employee, the data that creates the new employee is cohesive, that is it's all contained in one object, an Employee object. Since the business rules associated with creating this new object involve only that object, they may be included with the behavior of the Employee class and we say that an Employee is self-validating. In the case where Employee A is added to Dept. X, the business rules involve at least two objects and probably more. (A HumanResources object may also be involved.) If the validation logic resides in the objects being validated, they are coupled by the rule logic and, furthermore, the rule itself is fragmented, parts of its logic lying in two or more classes. The concept of validation can be used to create a better situation here. The idea is to create a Validation class (this will probably become a hierarchy in the application) that encapsulates a business rule that would ordinarily be fragmented across two or more objects. This provides cohesion for the rule and decouples the objects involved in the rule.

Process Objects
One interesting result of being able to simulate abstract concepts with objects is process objects (as in a business process). A business process may generally be defined as anything a business does that includes discrete events occurring over time. There is an initial event of the process and all succeeding events are determined by the finishing condition of previous events. An event is a discrete step in the process that can occur without interruption. When we consider business processes, it's common practice to have objects collaborate to carry out this process. For complex processes this leads to a network coupling between objects of the process and highly fragmented process logic. Each object of the process must know about the next object of the process, thereby coupling the objects. If the process logic changes, its multiple locations must be tracked down. In this situation the concept of process leads to process objects that contain the process logic, thus increasing the cohesion of the system. Although the level of coupling has remained the same, coupling through the process object is more desirable, allowing us to alter the process, adding or deleting tasks without altering the entity objects of the process.

What are validation and process objects? How do we logically arrive at their structure? We begin by asking the same questions we asked in simulating lists and integers: What are the properties? What are the behaviors? I will put off the properties question for now and answer the behaviors question with an example, that of an order-fulfillment process. There is an order process that includes four objects. Each of the objects participates in a part of the process and knows which object follows it in the process and what message to send to that object to continue the process. These objects are coupled by the process logic and the process logic is fragmented across these objects.

The same process can also have a ProcessObject coordinating the process. The objects involved in the process still carry out the tasks that represent their part of the process. However, they don't have any knowledge of the overall process. They don't know what objects follow them or that they are even a part of a process. The OrderProcess object knows the entire process and is responsible for carrying it out. Process logic is encapsulated in the OrderProcess object and the four objects taking part in the process are decoupled with respect to the process. The OrderProcess object represents the entire process, but has delegated individual tasks to other objects.

The PartsClerk object may participate in more than one process. The OrderProcess and a Financial object determine the value of a company's assets. These functionalities are orthogonal, having only the collaboration with the PartsClerk object in common. By encapsulating the logic of each process in one object, the PartsClerk doesn't need any knowledge of either process and contains logic related only to its own purpose.

The behavior of the OrderProcess object is the flow logic of the process. In our OrderProcess example, when each step of the process is completed, the OrderProcess object initiates the following step, which constitutes the behavior of the object. What are the properties of the OrderProcess object? Does it have any data properties? It has a name as a possible data property, but that's contained in its class name. Since it is conceptual and doesn't represent any real-world entity, it has no physical properties. Are there any data properties required for its behavior? The answer is probably yes, but if we take the simplest case it's no. In the simplest case the process could be "hard coded" with the logic (hardly ever a good idea) and the OrderProcess would not require any properties

Instead of hard coding the process, properties of the process object could include a collection of process nodes, each of which knows how to initiate and finalize its step of the process. We would also include a DataDictionary to contain the data required for completion of the process. In our example, there would be four process nodes, one for each step. When the process is initiated, it sends a "begin( this)" message with itself as an argument to the TakeOrder process node. The process node in turn notifies the OrderClerk object to "takeOrder(this)". When the order has been taken, the OrderClerk notifies the TakeOrder node "orderComplete( )", which in turn notifies the ProcessOrder. The ProcessOrder then sends "begin(this)" to the next node, etc.

All ProcessNodes implement a ProcessNodeInterface so that adding a node to the process would simply require inserting into the proper place in the node sequence. One property of the ProcessOrder would be this collection of process nodes. In addition we may wish to place some constraints on the process. This would lead to properties such as beginTime, endTime, and maxElapsedTime. If the process elapsed time exceeds the maxElapsedTime, the OrderProcess object would send notification of this condition to the appropriate party. These self-timing ideas would also apply to the process nodes. (You might already be imagining some additional benefits of process objects. The OrderProcess object could collect information about itself. This could be used to determine how efficient the process is, allowing us to improve the process over time.)

For complex processes, the process object may contain as a property a network that represents the process as task nodes and the state conditions dictating the next task of the process. This naturally leads to the idea of a subsystem of objects that form a framework for creating process subsystems.

What about the validation object? A validation object is simpler than a process object because it represents a single event. Its behavior is the application of the business rules via its methods. Properties may or may not be present. In the example above, a HumanResources object is required for the validation along with the employee and department objects. The validation class containing this rule may maintain a reference to a HumanResource object as a property. In general, validation objects will not have properties. All of the data necessary to carry out a validation will be passed in as arguments. For example, an employee has certain information. The department may require that employees have certain skills before they can work there. The HR department would apply the process of validation by introducing the employee to the department where the department could interrogate the employee to determine if there is a match. Each department may ask different questions or they may all ask the same question and expect different answers; that information behavior is delegated to the department. The supplied object must conform to the Employee interface and, in doing so, decouples itself from the department. In turn, the department is decoupled from the implementations of Employee so that new types can be introduced with minimal effects on the code.

Developing object-oriented applications is more than modeling entities of the problem domain as objects. To achieve the goal of creating maintainable and flexible apps, we need to create objects from the abstract concepts of the domain and solution spaces that complement the entity objects of the domain. We find them in the vocabulary of domain experts, in requirements, in use-cases, in applying patterns, and in our own experience and knowledge shared by design experts. Our goal is cohesive objects whose purpose in the application is well defined. We strive for smaller objects that specialize. To get there we create objects such as Validation and Process. By objectifying these abstract concepts we increase the cohesion and reduce the undesirable types of coupling from the application.

I've attempted to show how objects are created from abstract concepts. This is the first step in being able to create object-oriented applications that are composed of systems of cohesive, purposeful objects whose interactions fulfill the requirements.

For other ideas of conceptual objects, let me recommend the Wirfs-Brock reference below. Her "roles" should be helpful to you in finding conceptual objects in your applications.


  • Nygaard, K. "Early history of Simula," (1978). History of Programming Languages. Richard L. Wexelblat, ed. Academic Press, 1981.
  • Budd, T. (1997). An Introduction to Object-Oriented Programming. Addison-Wesley.
  • Wirfs-Brock, R. (2003). Object Design. Addison-Wesley.
  • Yourdon, E., and Constantine, L. (1978). Structured Design. Prentice Hall/Yourdon Press.
  • Booch, G. (1991). Object-Oriented Design. Benjamin/Cummings.
  • Martin, R., published articles: www.objectmentor.com/resources/articleIndex
  • Next Step Object-Oriented Programming and the Objective C Language, Addison-Wesley, 1993: www.toodarkpark.org/computers/objc
  • Merriam-Webster Online: www.webster.com
  • Eckel, B. (2002). Thinking in Java, 3rd Edition. Prentice Hall PTR: www.faqs.org/docs/think_java/TIJ3_t.htm
  • More Stories By Bill Kohl

    Bill Kohl works as a software architect for a large petroleum industry corporation. He has worked in software for more than 30 years, the last 15 of those in the OO world. His roles have included OO instructor and mentor, Smalltalk, C++ and Java developer, and for the last 6 years, software architect. He has extensive experience in developing object models for enterprise applications.

    Comments (3)

    Share your thoughts on this story.

    Add your comment
    You must be signed in to add a comment. Sign-in | Register

    In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.