This is the first installment in a series of articles about The Object-Oriented Thought Process. The material used in these articles is excerpted from the second edition of my book of the same title.
Choosing the theme and title of a book, or a column, are important decisions. The choices made were not all that simple because there are a lot of very good books and articles on various object-oriented (OO) topics—including OO analysis, OO design, OO programming, design patterns, OO databases, the Unified Modeling Language (UML), various OO programming languages, and many other OO topics.
However, while pouring over all of these books, many people forget that every one of these topics is built on a single foundation: how you think in object-oriented ways. It is unfortunate, but often software professionals dive into these books without taking the appropriate time and effort to really understand the concepts behind them.
I contend that learning OO concepts is not accomplished by learning a specific development method or a set of tools. Doing things in an OO manner is, simply put, a way of thinking. This column is all about the object-oriented thought process.
Separating the development methods and tools from the OO thought process is not easy. Many people are introduced to OO concepts via one of these development methods or tools. Many C programmers were first introduced to object orientation by migrating directly to C++, before they were even remotely exposed to OO concepts. Some software professionals were first introduced to object orientation by presentations that included object models using UML, again, before they were even exposed directly to OO concepts.
It is important to understand the significant difference between learning OO concepts and using the methods and tools that support the paradigm. In his article, “What the UML Is and Isn’t,” Craig Larman states,
Unfortunately, in the context of software engineering and the UML diagramming language, acquiring the skills to read and write UML notation seems to sometimes be equated with skill in object-oriented analysis and design. Of course, this is not so, and the latter is much more important than the former. Therefore, I recommend seeking education and educational materials in which intellectual skill in object-oriented analysis and design is paramount rather than UML notation or the use of a case tool.
Although learning a modeling language is an important step, it is much more important to learn OO skills first. Learning UML before OO concepts is similar to learning how to read an electrical diagram without first knowing anything about electricity.
The same problem occurs with programming languages. As stated earlier, many C programmers moved into the realm of object orientation by migrating to C++ before being directly exposed to OO concepts. Often, developers who claim to be C++ programmers are simply C programmers using C++ compilers.
This problem is even more of an issue now that object-oriented languages such as Java, C# .NET, and Visual Basic .NET have become so popular. There are many Visual Basic programmers who now must make the leap to Visual Basic .NET. Likewise, many C++ programmers, who might not be conforming to strict OO practices, are being asked to migrate to Java or C#, where they have no choice but to think in OO ways.
Early versions of Visual Basic are not OO. C is not OO, and C++ was developed to be backward compatible with C. Because of this, it is quite possible to use a C++ compiler and use only C syntax, while forsaking all of C++’s OO features. Even worse, a programmer can use just enough OO features to make a program incomprehensible to OO and non-OO programmers alike.
Thus, it is of vital importance that while you’re on the road to OO development, you first learn the fundamental OO concepts. Resist the temptation to jump directly into a programming language (such as C++, C#, or Java) or a modeling language (such as UML), and take the time to learn the object-oriented thought process.
While taking my first Smalltalk class in the late 1980s, the instructor told the class that the new OO paradigm was a totally new way of thinking. He went on to say that although all of us were most likely very good programmers, about 10% to 20% of us would never really grasp the OO way of doing things. If this statement is indeed true, it is most likely because some people never really take the time to make the paradigm shift and learn the underlying OO concepts.
This Column’s Scope
It should be obvious by now that I am a firm believer in becoming comfortable with the object-oriented thought process before jumping into a programming language or modeling language. These columns will be filled with examples of Java, C#, and VB .Net code as well as UML diagrams; however, you do not need to know Java, C#, and so forth or UML to really understand the concepts. After all I have said about learning the concepts first, why will there be so much code and so many UML diagrams? First, they are both great for illustrating OO concepts. Second, both are vital to the OO process and should be addressed at an introductory level. The key is not to focus on code or UML, but to use them as aids in the understanding of the underlying concepts.
I cannot state too strongly that this column will not teach coding syntax or UML, both of which can, and do, command separate books. It is my hope that this column will whet your appetite for other OO topics, such as OO analysis, object-oriented design, and OO programming.
Introduction to Object-Oriented Concepts
Although it might be a bit surprising, object-oriented software development has been around since the early 1960s. Although objects have become much more prevalent in today’s software industry, a number of software shops have yet to venture into the OO arena. It is no secret that the software industry can be slow moving at times. It is also true that, when working systems are in place, there has to be a compelling reason to replace them. This has hindered the propagation of OO systems. There are a lot of non-OO legacy systems (that is, older systems that are already in place) that seem to be working just fine so why risk potential disaster by changing them? In most cases, you should not change them, at least not simply for the sake of change. There is nothing inherently wrong with systems written in nonOO code. However, brand-new development definitely warrants the consideration of using OO technologies.
Although there has been a steady and significant growth in OO development in the past 10 years, an entirely new venue has helped catapult it further into the mainstream. The emergence of the Web has opened a brand-new arena, where much of the software development is new and mostly unencumbered by legacy concerns. Even when there are legacy concerns, there is a trend to wrap the legacy systems in object wrappers.
Object wrappers are object-oriented code that includes structured code inside. For example, you can take a structured module and wrap it inside an object to make it look like an object.
Objects are slowly but surely making their way into our professional information systems (IS) lives and they cannot be ignored. With the success of Java and the introduction of Microsoft’s .NET technologies, objects are becoming a major part of the IS equation. With the explosion of the Internet, now many years in the making, the electronic highway is really becoming an object-based highway. And as businesses gravitate toward the Web, they are gravitating toward objects, because the technologies used for the Web are mostly OO in nature.
The remainder of the article begins an overview of the fundamental OO concepts. The topics covered touch on some of the topics covered in subsequent installments, which explore these issues in much greater detail.
Procedural Versus OO Programming
Before we delve deeper into the advantages of OO development, let’s consider a more fundamental question: What exactly is an object? This is both a complex and a simple question. It is complex because shifting gears to learn a totally new way of thinking is not an easy task. It is simple in the sense that most people already think in terms of objects.
For example, when you look at a person, you see the person as an object. And an object is defined by two terms: attributes and behaviors. A person has attributes, such as eye color, age, height, and so on. A person also has behaviors, such as walking, talking, breathing, and so on. In its basic definition, an object is an entity that contains both data and behavior. The word both is the key difference between the more traditional programming methodology, procedural programming, and OO programming.
In procedural programming, code is placed into totally distinct functions or procedures. Ideally, as shown in Figure 1.1, these procedures then become “black boxes,” where inputs go in and outputs come out. Data is placed into separate structures, and is manipulated by these functions or procedures
Difference Between OO and Procedural
This is the key difference between OO and procedural programming. In OO design, the attributes and behavior are contained within a single object, whereas in procedural, or structured design, the attributes and behavior are normally separated.
Figure 1.1 Black boxes.
Procedural programming has been the mainstay since the Bronze Age of computers, so why change? First, as illustrated in Figure 1.2, in procedural programming the data is separated from the procedures, and sometimes the data is global so it is easy to modify data that is outside your scope. This means that access to data is uncontrolled and unpredictable (i.e. several functions may have access to the global data). Second, because you have no control over who has access to the data, testing and debugging are much more difficult. Objects address these problems by combining data and behavior into a nice, complete package.
Figure 1.2 Using global data.
No Global Data
We can state that, when properly designed, there is no such thing as global data in an OO model. This fact provides a high amount of data integrity in OO systems.
Objects are much more than primitive data types, such as integers and strings. Although objects do contain entities such as integers and strings, which represent attributes, they also contain methods, which represent behaviors. In an object, you use the methods to operate on the data. Perhaps more importantly, you can control access to members of an object (both attributes and methods). This means that some members, such as data types and methods, can be hidden from other objects. For instance, an object called Math might contain two integers, called myInt1 and myInt2. Most likely, the Math object also contains the necessary methods to set and retrieve the values of myInt1 and myInt2. It might also contain a method called Sum() to add the two integers together.
In OO terminology, data is referred to as attributes, and functions are referred to as methods. Restricting access to certain attributes and/or methods is called data hiding.
By combining the data and methods in the same entity, which in OO parlance is called encapsulation, we can control access to the data in the Math object. By defining these integers as off-limits, another logically unconnected object cannot manipulate the integers myInt1 and myInt2 only the Math object can do that.
Keep in mind that it is possible to create poorly designed classes that do not restrict access to class attributes. The bottom line is that you can design bad code just as efficiently with OO design as with any other programming methodology. Simply take care to adhere to sound class design guidelines, which we will cover these issues in future installments.
What happens when another object—for example, myObject—wants to gain access to the sum of myInt1 and myInt2? It asks the Math object: myObject sends a message to the Math object. Figure 1.3 shows how the two objects communicate with each other via their methods. The message is really a call to the Math object’s Sum() method. The Sum() method then returns the value to myObject. The beauty of this is that myObject does not need to know how the sum is calculated (although I’m sure it can guess). In this example, you can change how the Math object calculates the sum without making a change to myObject (as long as the means to retrieve the sum do not change). All you want is the sum; you don’t care how it is calculated.
Figure 1.3 Object-to-object communications.
Calculating the sum is not the responsibility of myObject it’s the Math object’s responsibility. As long as myObject has access to the Math object, it can send the appropriate message and then obtain the result. In general, objects should not manipulate the internal data of other objects (that is, myObject should not directly change the value of myInt1 and myInt2). And, for reasons we will explore later, it is normally better to build small objects with specific tasks rather than build large objects that perform many.
In this first installment of the object-oriented thought process series, we covered some basic ground about the philosophy of object-orientation as well as a brief introducion to some object-oriented concepts. In the next column, we will define something fundamental to object-orientation—what is an object?
References and Suggested Reading
Coad, Peter, and Mark Mayfield. Java Design. Object International, 1999.
Eckel, Bruce. Thinking in C++. Prentice Hall, 1995.
Flower, Martin. UML Distilled. Addison-Wesley Longman, 1997.
Gilbert, Stephen, and Bill McCarty. Object-Oriented Design in Java. The Waite Group, 1998.
Khoshafian, Setrag, and Razmik Abnous. Object Orientation. Wiley, 1995.
Larman, Craig. “What the UML Is—and Isn’t,” Java Report, volume 4 (issue 5): pages 20–24, May 1999.
Meyers, Scott. Effective C++. Addison-Wesley, 1992.
Schach, Stephen R. Classical and Object-Oriented Software Engineering. Irwin, 1996.
Tyma, Paul, Gabriel Torok, and Troy Downing. Java Primer Plus. The Waite Group, 1996.
About the Author
Matt Weisfeld is a faculty member at Cuyahoga Community College (Tri-C) in Cleveland, Ohio. Matt is a member of the Information Technology department, teaching programming languages such as C++, Java, and C# .NET, as well as various Web technologies. Prior to joining Tri-C, Matt spent 20 years in the information technology industry gaining experience in software development, project management, business development, corporate training, and part-time teaching. Matt holds an MS in computer science and an MBA in project management.
The articles in this series are adapted from The Object-Oriented Thought Process (published by Sams Publishing). Matt has published two other computer books, and more than a dozen articles in magazines and journals such as Dr. Dobb’s Journal, The C/C++ Users Journal, Software Development Magazine, Java Report, and the international journal Project Management. Matt has presented at conferences throughout the United States and Canada.