Object-oriented development is the process of turning an idea or a problem specification into an object-oriented program.
Object-oriented analysis (OOA) transforms a glimmer of a product into an object-oriented model of that problem.
Object-oriented design (OOD) entails transforming the analysis model into a feasible design.
Once the design reaches a sufficient level of specificity, it is translated into an implementation through object-oriented programming. This task can be either relatively straightforward or rather challenging, depending upon the amount of detail in the design (and perhaps on other factors, too).
Projects making a transition from a more traditional development approach, such as structured analysis and structured design (SA/SD), to object-oriented development are likely to encounter several impediments. When completed, the object-oriented software must coexist with legacy software that is not object-oriented, often requiring that the two types of software communicate with one another. Existing data that are stored in relational databases must be converted to objects in memory when used by an object-oriented application.
An organization's lack of experience with object-oriented technology presents another set of problems. The staff must be trained to understand and employ object-oriented development and infrastructure. Because they are using new design methods and programming languages, staff members will make mistakes on their first projects, regardless of how much training they receive.
This lack of experience also pervades project management. Project leaders who are unversed in the new technology often cannot detect architectural flaws until very late in the development process. In addition, because most estimation models rely on previous data, managers have a difficult time with estimation and planning.
Given these costs, why adopt object technology at all? Many organizations take the leap to object technology for non-technical reasons, such as:
Although non-technical reasons may provide sufficient incentive for some to make the transition to object technology, other organizations want more tangible benefits to justify the switch. The possible technical benefits include the following:
Given that many organizations build the same kinds of software systems again and again, a realistic goal is to avoid building every new system from scratch, aiming instead to build systems that can be extended to incorporate new capabilities, and that can be (at least partially) reused in other, similar contexts.
Object-oriented technology is based on several concepts that, when applied to a design or program, can make the resulting product easier to extend and reuse. Five such features are abstraction, encapsulation, specialization, type promotion, and polymorphism.
In general, abstraction is the process of focusing only on the essential characteristics of an entity. A class provides a powerful abstraction mechanism for object-oriented design and programming. A class defines an abstraction in the problem or solution domain. In an order processing application, for example, an Order class defines the basic properties of each order instance. In particular, it defines both the state (data) and behavior (algorithms) that its instances have. Because it defines both state and behavior, a class provides a more powerful abstraction mechanism than a procedure or a data record does.
A class also defines both an interface and an underlying implementation. That implementation is invisible to external clients of the class (or of its instances). Defining such properties as private to the class is an example of encapsulation. In other words, a class encapsulates its state and behavior. Encapsulation is a mechanism to achieve information hiding. A major advantage of information hiding is that if the information is invisible to the client, you can modify its implementation without affecting the client in any way.
Object-oriented programming languages also support class specialization, or the is-a-kind-of relationship between classes. The Automobile class is a specialization of the Vehicle class (or, Automobile is a kind of Vehicle), the Router class specializes the Device class, and the Service Order class is a specialization of the Order class. The operational result of the specialization relationship is inheritance—the specialization (or subclass) inherits all of the state and behavior of the generalization (or superclass). The Automobile class, for example,inherits all of the properties of the Vehicle class.
Class specialization allows you to define the properties common to all vehicles in the Vehicle class and then to inherit those properties in the Vehicle specializations (such as Automobile, Truck, and so forth). Therefore, a major selling point of specialization is that you can define those common properties once and inherit them where necessary. Hence, you have a single copy of those properties. With multiple copies of a piece of code, any corrections to the code must be introduced in each copy. With class specialization, however, any changes in the superclass properties are propagated to the subclasses through inheritance.
Type promotion allows you to treat a specific type of object as a more general type. For example, you can refer to an Automobile instance either as an Automobile or as a more generic Vehicle. This principle is also called substitution. When a client expects to be given a reference to a generic Vehicle, you can substitute any more specific reference (such as a reference to an Automobile). Type promotion allows you to write client code that refers only to generic types such as Vehicle. This implies that the client code is unaware of the specific types. Therefore, when you introduce a new specialization of Vehicle, the client code is unaffected. Instances of that new class will be treated by the client code as generic Vehicles.
At this point, you may be thinking, "But I want an Automobile to behave like an Automobile, not like a generic Vehicle." The complement of type promotion is polymorphism. Polymorphism simply means that an object still acts like what it really is, regardless of how a client refers to it. When a client tells a Vehicle to do something, the Vehicle will respond appropriately based on what it really is (at execution time). If what the client is referencing is actually an Automobile, it will act like an Automobile. On the other hand, if it is a Truck, it will behave like a Truck.
The combination of type promotion and polymorphism allows you to write very generic client code that is de-coupled from the existence of particular specializations. As noted previously, your client code that references only generic Vehicles is unaffected by the addition or removal of specializations of Vehicle. Nonetheless, when that code acts on a Vehicle, you still see the correct behavior based on the actual type of the Vehicle. Furthermore, the same generic code can act on any type of Vehicle.
The object-oriented development process itself is an attraction for many organizations. Compared to many alternative development approaches, which suffer points of discontinuity during the process, object-oriented development is a relatively seamless process.
As an example of a development process with a seam, consider Structured Analysis and Structured Design (SA/SD). During analysis, you create data flow diagrams that describe how data is transformed by the system. When your analysis is complete and you turn your attention to design, you draw structure charts that indicate what subroutines will exist in your implementation and how those subroutines interact. In other words, you draw one type of diagram during analysis and an entirely different type of diagram during design.
These two different representations form a discontinuity in the SA/SD process. The fact that the two models are largely unrelated further exacerbates the problem. Except in a few rare cases, you cannot transform a data flow diagram into a beginning set of structure charts. When you start the design phase, you essentially start anew.
In contrast, object-oriented development enjoys representational continuity. As you proceed through analysis and design, you continue to draw the same kinds of diagrams. During high-level analysis, you draw a class diagram, a use case diagram, and perhaps a set of interaction diagrams. Many weeks later, during low-level design, you are still drawing these same diagrams (and perhaps a few others).
The fact that the analysis and design representations are the same provides one form of continuity. A second form is the continuity of the model itself; the design is an elaboration of the analysis. That is, the classes and use cases that exist in the initial analysis also appear in the final design. The analysis of an order processing application will include Order, Line Item, and Customer classes. Those classes will continue to appear in the refined analysis and design models. In fact, they will exist in the ultimate implementation! These two forms of representational continuity provide you with a more coherent development process.
For some organizations, a major advantage of object technology is the fact that classes model real-world abstractions in an intuitive way. A class can also model both the state and the behavior of its instances. For example, an Order class in an order processing application defines the state that an order has (such as an order number and a set of line items), as well as the actions one could perform on an order (such as canceling or committing it).
A class diagram can, therefore, serve as a model of the business. Business analysts and software analysts can work together to develop an object-oriented analysis model. The result of that effort is a final business model to the businessperson, but it is viewed by the software professional as an initial model from which the final system will be derived.
This situation is far preferable to the more common situation in which business analysts build a business model that is ignored by the software developers, who in turn develop an analysis model that is eschewed by the business analysts.
Object-oriented design notations and programming languages support the decomposition of a system along different dimensions, thus allowing developers to deal with complexity in various ways.
Classes can also be organized in different types of hierarchies. The hierarchy that receives the most press, of course, is the specialization hierarchy (often referred to simply as the class hierarchy). Classes are arranged according to the specialization (or is-a-kind-of) relationship.
In the typical case, a specialization (or subclass) is also a subtype. So, the specialization hierarchy mimics the type hierarchy, A specialization inherits the properties of its generalization (or superclass). A subclass is simplified because it contains only the properties that distinguish it from its superclass.
In some cases, classes (and their instances) can be arranged in a composition hierarchy. Classes are organized based on whole-part relationships, meaning that the instances of one class are composed of the instances of others. For example, a document consists of paragraphs, which in turn consist of words. Requests can be delegated from a whole to its parts, providing a convenient and consistent way of dealing with certain types of complex structures.
Prototyping can entail anything from simply providing an interface mock-up to slapping together a crude proof-of-concept sample of the intended system. Although prototyping is never easy, object technology can make the job easier.
Perhaps the biggest advantage of prototyping is the existence of libraries of reusable classes. The classes in a class library provide standard versions of some of the prototype's potential components. For example, when building a graphical user interface (GUI) prototype, you can employ the GUI widgets such as frames, buttons, and check-boxes that come with your favorite GUI class library. You simply add whatever special processing is required by the prototype.
Encapsulation also assists the development of prototypes. Because objects are self-contained, they can provide implementations of some operations while "stubbing out" others. This permits you to build a prototype incrementally. Although a class may provide a fairly rich interface, it need not implement any part of that interface not required by the current prototype.
The successful prosecution of OOA and OOD requires an effective design
To support the development of large-scale, flexible object-oriented systems, such a method should include at least three components:
For its analysis and design notation, this book employs the Unified Modeling Language (UML). As its name suggests, UML is a notation. More specifically, it is an object-oriented analysis and design notation. As such, it includes features for everything from high-level analysis concepts (and even business process models) down to very detailed design elements. However, it is only a notation, and so UML is silent on the subject of design process or flexibility guidelines.
UML is a unification of the concepts of previous object-oriented design notations. It provides notation for the "garden-variety" features present in most existing object-oriented design methods. In addition, it adds concepts and notation missing from those methods. Some are large-scale additions, such as the inclusion of new types of diagrams from other disciplines (the activity diagram, for example). In other cases, it provides incremental yet important additions, such as its integration of concurrency features into interaction diagrams.
UML is a relative newcomer to the design notation field. The initial release occurred in January of 1997. Nevertheless, the following factors have led to UML's rapid and widespread acceptance in the object-oriented design community:
The current version of UML is 1.1, 1.2, or 1.3, depending on whom you ask. Version 1.1 was the initial version accepted by the Object Management Group as its standard design language. That version was developed by Booch, Jacobson, and Rumbaugh at Rational Software Corporation and is maintained on the Rational Web page as The Unified Modeling Language Notation Guide: Version 1.1 (1997) and The Unified Modeling Language Semantics: Version 1.1 (1997). (These are available at http://www-306.ibm.com/software/rational/ .) The OMG subsequently released version 1.2 as an editorial cleansing of version 1.1 and [then] version 1.3.
UML is an extensive language that allows you to construct several views of a
system through the use of its different diagrams.
Some important views and their diagrams follow:
A flexible design is one that is extensible or reusable. New features can be added to an extensible design relatively painlessly. Ideally, adding a new capability should affect as few classes as possible. A reusable design is one that can be used, either entirely or in part, in another system or application.
To increase its flexibility, an object-oriented design should exhibit several properties:
You will have to choose the degree of flexibility (at the price of complexity and perhaps performance) that you require.
In fact, you typically face a trade-off between flexibility and simplicity and between flexibility and performance. A flexible design is typically more complicated and often sacrifices some performance for the sake of flexibility.
This Web document is an introduction to the basic concepts and notation required to specify an object-oriented analysis model or object-oriented design, as presented by Charles Richter in his 1999 book Designing Flexible Object-Oriented Systems with UML and in the "Object-Oriented Development Using the Unified Modeling Language" course he teaches. Charles Richter's company is Objective Engineering, Inc.