A Realistic Look at Object-Oriented Reuse
Sidebar: Reusable Resources
Sidebar: Whence Business Objects?
Reusability is one of the great promises of object-oriented technology. Unfortunately, it's a promise that often goes unrealized. The problem is that reuse isn't free; it isn't something you get simply because you're using object-oriented development tools. Instead, it's something you must work hard at if you want to be successful. The first lesson is that there is more to reuse than reusing code. Code reuse is the least productive form of reuse available. Don't get me wrong, code reuse is still a good thing; it's just that you can get a bigger bang for your reuse buck elsewhere. There is much more to an application than source code; thus, you should be able to reuse much more than code. Let's explore the types of reuse in detail, and see where you can apply them when you're building applications.
Code reuse, the most common kind of reuse, refers to the reuse of source code within sections of an application and potentially across multiple applications. At its best, code reuse is accomplished by sharing common classes or collections of functions and procedures (this is possible in C++, but not in Smalltalk or Java). At its worst, code reuse is accomplished by copying and then modifying existing code. A sad reality of our industry is that code copying is often the only form of reuse practiced by developers.
A key aspect of code reuse is that you have access to the source code. If necessary, you either modify it yourself or have someone else modify it for you. This is both good and bad. By looking at the code, you can determine, albeit often slowly, whether or not you want to use it. At the same time, by releasing the full source code to you, its original developer might be less motivated to document it properly, increasing the time it takes you to understand it and consequently decreasing its benefit to you.
The main advantage of code reuse is that it reduces the amount of actual source code you need to write, potentially decreasing both development and maintenance costs. The disadvantages are that its scope of effect is limited to programming and it often increases the coupling within an application.
Inheritance reuse refers to using inheritance in your application to take advantage of behavior implemented in existing classes. Inheritance is one of the fundamental concepts of object orientation, letting you model is a, is like, and is kind of relationships. For example, to develop a CheckingAccount class, you start by having it inherit from SavingsAccount, directly reusing all of the behavior implemented in that class.
The advantage of inheritance reuse is that you take advantage of previously developed behavior, which decreases both the development time and cost of your application. Unfortunately, there are several disadvantages to inheritance reuse. First, the misuse of inheritance will often result in developers missing an opportunity to reuse components, which offers a much higher level of reuse. Second, novice developers will often skimp on inheritance regression testing (the running of superclass test cases on a subclass), resulting in a fragile class hierarchy that is difficult to maintain and enhance. As you can see, this is reuse, but at a prohibitive cost.
Template reuse is typically a form of documentation reuse. It refers to the practice of using a common set of layouts for key development artifacts-documents, models, and source code-within your organization. For example, it is quite common for organizations to adopt common documentation templates for use cases, status reports, developer time sheets, change requests, user requirements, class files, and method documentation headers. The main advantage of documentation templates is that they increase the consistency and quality of your development artifacts. The main disadvantage is that developers have a tendency to modify templates for their own use and not share their changes with coworkers.
For best results with templates, you need to make it easy for developers to work with them. I've seen implementations of templates as simple as Microsoft Word document templates and as complex as Lotus Notes databases shared by all developers. Your organization also must provide training in how and when to use the templates so that everyone uses them consistently and correctly.
Component reuse refers to the use of prebuilt, fully encapsulated components in the development of your application. Components are typically self-sufficient and encapsulate only one concept. Component reuse differs from code reuse in that you don't have access to the source code. It differs from inheritance reuse in that it doesn't use subclassing. Common examples of components are Java Beans and ActiveX components.
There are several advantages to component reuse. First, it offers a greater scope of reusability than either code or inheritance reuse because components are self-sufficient-you literally plug them in and they work. Second, the widespread use of common platforms such as the Win32 operating system and the Java Virtual Machine provide a market that is large enough for third-party vendors to create and sell components to you at a low cost. The main disadvantage to component reuse is that because components are small and encapsulate only one concept, you need a large library of them.
The easiest way to get going with components is to start out with user interface widgets-slide bars, graphing components, and graphical buttons (to name a few). But don't forget there's more to an application than the user interface. You can get components that encapsulate operating system features such as network access, and that encapsulate persistence features such as components that access relational databases. If you're building your own components, make sure they only do one thing. For example, a user interface component for editing surface addresses is very reusable because you can use it on many editing screens. A component that edits a surface address, an e-mail address, and a phone number isn't as reusable-there aren't as many situations where you'll want all three of those features simultaneously. Instead, it's better to build three reusable components and reuse each one where needed. When a component encapsulates one concept, it is a cohesive component.
Framework reuse refers to the use of collections of classes that implement the basic functionality of a common technical or business domain together. Developers use frameworks as the foundation from which they build an application; the common 80% is in place already, they just need to add the remaining 20% specific to their application. Frameworks that implement the basic components of a GUI are very common. There are frameworks for insurance, human resources, manufacturing, banking, and electronic commerce. Framework reuse represents a high level of reuse at the domain level.
Frameworks provide a beginning solution for a problem domain and often encapsulate complex logic that would take years to develop from scratch. Unfortunately, framework reuse suffers from several disadvantages. The complexity of frameworks makes them difficult to master, requiring a lengthy learning process on the part of developers. Frameworks are often platform-specific and tie you into a single vendor, increasing the risk for your application. Although frameworks implement 80% of the required logic, it is often the easiest 80%; the hard stuff, the business logic and processes that are unique to your organization, is still left for you to do. Frameworks rarely work together unless they come from a common vendor or consortium of vendors. They often require you to change your business to fit the framework instead of the other way around.
Artifact reuse refers to the use of previously created development artifacts-use cases, standards documents, domain-specific models, procedures and guidelines, and other applications-to give you a kick start on a new project. There are several levels of artifact reuse, ranging from 100% pure reuse where you take the artifact as is and use it on a new project, to example reuse where you look at the artifact to get an idea about how to proceed. For example, standards documents such as coding and user interface design standards are valuable artifacts to reuse between projects, as are modeling notation documents and methodology overview documents. I've also been able to reuse existing applications either via a common data interface or by putting an object-oriented wrapper around them to make them look like normal classes.
Artifact reuse promotes consistency between projects and reduces the project management burden for each new one. Another advantage is that you can often purchase many artifacts or find them online: user interface standards are common for most platforms, coding standards for leading languages are often available, and standard object-oriented methodologies and modeling notations have been available for years. The main disadvantage of artifact reuse is that it is often perceived as overhead reuse by hard-core programmers-you simply move the standards and procedures binders from one desk to another. The bottom line is that artifact reuse is an important and viable technique that should not be ignored.
Pattern reuse refers to the use of publicly documented approaches to solve common problems. Patterns are often documented by a single class diagram and typically comprise one to five classes. With pattern reuse, you're not reusing code; instead, you're reusing the thinking that goes behind the code. Patterns are a very high form of reuse that will prove to have a long life span-at least beyond the computer languages that you are currently using and potentially beyond the object-oriented paradigm itself.
The Contact Point pattern, modified from my book Building Object Applications That Work(SIGS Books, 1997) is modeled using a Unified Modeling Language (UML) 1.1 class diagram, shows a common pattern for tracking the contact points between your organization and other business entities. This pattern shows that you can treat e-mail addresses, surface addresses, and phone numbers as the same kind of object-contact points through which your organization interacts with other business entities (customers, employees, suppliers, and so on). This pattern increases the flexibility of your applications. It shows that not only can you mail an invoice to a customer, but you can also e-mail or fax it. Instead of shipping a CD-ROM or a video cassette to a surface address, you can transmit the product electronically. The Contact Point pattern is a key enabler for doing these things. I've successfully implemented this analysis pattern in several applications, reusing the most difficult part of a model-the thinking that went behind it. Pattern reuse provides a high level of reuse that you can implement across multiple languages and platforms. Patterns encapsulate the most important aspect of development-the thinking that goes into the solution. Patterns increase the ability to maintain and enhance your application by using common approaches to problems that are recognizable by any experienced object-oriented developer. The disadvantage of pattern reuse is that patterns don't provide an immediate solution-you still have to write the code that implements the pattern.
Domain component reuse refers to the identification and development of large-scale, reusable business components. A domain component is a collection of related domain and business classes that work together to support a cohesive set of responsibilities. A component diagram for a telecommunications firm has several domain components, each encapsulating many classes. The Service Offerings component encapsulates more than 100 classes ranging from a collection of classes modeling long-distance calling plans, to cable television packages, to Internet service packages. Domain components are initially identified by taking an architecture-driven approach to modeling, modified and enhanced during the development of new applications for your organization.
Domain components provide the greatest potential for reuse because they represent large-scale, cohesive bundles of business behaviors that are common to many applications. Everything you produce during domain development should be reusable. Domain components are effectively architectural bins into which business behaviors are organized and then later reused.
The good news about these approaches to reuse is that you can use them simultaneously. Yes, framework reuse often locks you into the architecture of that framework and the standards and guidelines it uses, but you can still take advantage of the other approaches to reuse with frameworks. Artifact and component reuse are the easiest places to start; with a little bit of research, you can find reusable items quickly.
You can purchase documentation templates online, but if your organization doesn't have a well-defined development process, you may get little benefit from templates. Inheritance and pattern reuse are the domain of modelers, and they'll start applying these forms of reuse as a matter of course.
Realistically, I would start with artifact and component reuse to train my modelers in the appropriate use of inheritance and patterns, implement an architecture-driven development approach to identify and develop domain components, and trust my coders to reuse whatever code they can.
Now that we have several techniques in our reuse toolkit, let's see where we can apply them. The four-layer class-type architecture indicates the approaches to reuse for each layer. Because each layer has its own unique properties and development demands, it makes sense that the approach to reuse should also be unique for each layer. Let's look at each layer in detail.
The user interface layer encapsulates screens and reports, the points at which users interact with your application. The most common type of reuse for the user interface layer is obviously component reuse of interface widgets-it is quite common for developers to purchase component libraries of scroll bars, graphs, lists, and other interface widgets. Just as important for this layer is artifact reuse, specifically of user interface and report layout standards. One of the most important things in interface design is consistency, and following a common set of standards and guidelines is the easiest way to promote it within your application.
The business layer encapsulates the problem domain logic of your application. Pattern reuse, specifically analysis pattern reuse, is important for the business layer as well as framework reuse for the applicable business domain and common business class libraries. Although all three of these approaches to reuse are still fairly immature, they are improving rapidly for many business domains. A large collection of patterns is being developed both within academia and the business world, and common frameworks are being farmed by large consulting and technology companies that have expertise in one or more vertical markets.
More important to reuse within the business layer, however, is the introduction of domain components within your organization. Domain components are an important by-product of an architectural-driven approach to development-an approach that is founded on reuse.
The persistence layer encapsulates and generalizes access to the various persistence mechanisms you use to permanently store objects such as relational databases, object databases, and flat files. The most important forms of reuse for this layer are framework reuse and component reuse. This is because you can purchase packages that implement whole or part of the persistence layer. Design pattern reuse is also a strong likelihood, as designs for persistence layers have been presented in several publications. Artifact reuse of data dictionaries within your organization should also be possible.
The system layer encapsulates and generalizes access to the operating system, the network, hardware, and other applications. Design pattern reuse, especially for the wrapping of hardware and applications, is very common for the system layer, as is component and artifact reuse of wrapper classes.
Within all four layers, code and inheritance reuse are obviously applicable. You could also argue that pattern reuse can be achieved in the user interface layer. During the entire project, template reuse of standard document layouts and development standards and procedures is also significant.
So how do you actually achieve object-oriented reuse? I wish I could say that all you need to do is go out and buy a few tools and a repository to store your reusable work to get a good start. Unfortunately, reuse is about far more than tools. In fact, many organizations have failed miserably because of their focus on tools and not on process. Here are some reuse tips:
You can't call something reusable unless it's been reused at least three times on three separate projects by three separate teams.You can attempt to design for reuse, but you can't claim success until some element of the application has been reused at least three times. Reusability is in the eye of the beholder, not in the eye of the creator.
Reusable items must be well-documented and have one or more real-world examples of how to use them.In addition, the documentation should indicate when and when not to reuse an item so developers can understand the context in which it is to be used.
The only way you'll make reuse a reality is if you plan for it. You must allocate the time and resources necessary to make your work reusable. If you don't step back and take the time to generalize your work, then it will never happen-project pressures will motivate you to put that work aside until you have the time to do it. The bottom line is that if reuse management-the act of specifically reusing existing items and constantly adding to the store of reusable items-isn't part of your development process, then reuse won't happen.
Reuse is an attitude. When you begin a project, the first thing you should do is determine what portions of your application can be reused from somewhere else. Perhaps someone else has built what you need, or perhaps you can purchase components or other reusable items. The other side of the coin is that you must be willing to share your work with other people so they can reuse it. A good team lead will constantly be on the lookout for opportunities for reuse and will promote and reward reuse within his or her team. An excellent approach is to look for reuse during inspections: during model walkthroughs, look for opportunities for inheritance and pattern reuse; during code walkthroughs, look for component and code reuse.
Often you will have to combat the "not invented here" (NIH) syndrome, a problem that could prevent you from trying to spread the reuse attitude among your team. According to the NIH syndrome, developers won't reuse the work of other developers because they didn't create it themselves. Pure hogwash. Professional developers constantly seek to reuse the work of others because it frees them up to work on the domain-specific portions of their own applications. My experience is that professional developers will readily reuse the work of others as long as it meets their needs, is of high quality, and is well-documented and easy to understand. The NIH syndrome is a myth. If it were true, then object-oriented development environments wouldn't come with class libraries, and the hundreds of companies selling reusable components and frameworks wouldn't exist.
Word of mouth is often the way people find things to reuse. Yes, reuse repositories are good things to have, but they are similar in concept to the official chain of command in your organization. Just like some things get done through official channels and some through your informal network of contacts, you find some reusable things in the repository and some through your friends.
Reuse is an organization thing, not a project thing. Many organizations fail at reuse because they don't understand its scope. Reuse between projects is where you get your payback, not reuse within a single project. Many organizations prematurely give up on reuse when they don't achieve it on their first project, which is foolish when you consider that there is nothing to reuse in the beginning. This is why an architecture-driven approach to development is important-because it looks beyond the needs of a single project to the needs of the entire organization, and an important organizational need is to reuse existing work wherever possible.
A one-size-fits-all approach to reuse won't work. There are many different approaches to reuse, and the unique needs of each class-type layer require a different combination of approaches. You need to recognize this and plan accordingly.
Part of not "reinventing the wheel" is to first understand that you have more than one wheel at your disposal. You can reuse source code, components, development artifacts, patterns, and templates. Most important, your work isn't reusable simply because it's object-oriented. Instead, it's reusable because you've taken the time to make it so.
REUSABLE RESOURCES
Organizations are often overwhelmed when they attempt to increase their reuse on projects-they quickly find that they often have little available to them internally that is worth reusing. What they don't realize is that externally there is a wealth of items waiting to be reused. Although I leave you to fend for yourself, I want to share with you several representative sources of template, component, framework, artifact, and pattern reuse (code and inheritance reuse are internal approaches). Template Reuse. If your organization hasn't already defined common templates for use cases, time sheets, and so on, then you might want to check out the templates from Software Productivity Centre (www.spc.ca). It has several sets of documentation templates available to purchase. One of its products is called The Essential Set, which includes 54 documentation templates that cover the full application development process. Component Reuse. Companies that sell reusable components are fairly easy to find on the Internet. For example, Gamelan (www.gamelan.com) is a great source for links to reusable Java Beans, and ActiveX.Com (www.activex.com) markets ActiveX components for a wide range of needs, including web site development and database access. Framework Reuse. The cost of reusable frameworks is often very high, but then again, the savings are often higher. PeopleSoft (www.peoplesoft.com) sells frameworks for financial management, materials management, distribution, manufacturing, and human resources. SAP (www.sap.com) markets a product called Business Framework Architecture for extending and enhancing business process control within SAP R/3 and SAP R/4. Artifact Reuse. Artifact reuse is straightforward to achieve as long as you're willing to look to outside sources. Anyone developing for the Windows platform should have a copy of the user interface design standards defined in Microsoft's book The Windows Interface Guidelines for Software Design(Microsoft Press, 1995). Java developers can take advantage of the AmbySoft Java Coding Standards posted at www.ambysoft.com. Object-oriented modelers can download a copy of the Unified Modeling Language (UML) notation document from Rational (www.rational.com). Pattern Reuse. You can get a good start on patterns with the books Design Patterns: Elements of Reusable Object-Oriented Software (Addison-Wesley, 1995) by Erich Gamma et al, and Martin Fowler's Analysis Patterns: Reusable Object Models (Addison-Wesley, 1997). The Patterns Home Page, http://st-www.cs.uiuc.edu/users/ patterns/patterns.html, is also an excellent resource for pattern reuse. Domain Component Reuse. To learn how to build reusable domain components, you must take an architecture-driven approach to object-oriented development. For further details, I suggest Software Reuse: Architecture, Process, and Organization for Business Success by Ivar Jacobson et al (Addison Wesley, 1997).
|
WHENCE BUSINESS OBJECTS?
For years, object experts have claimed that a marketplace for business objects is just over the horizon, a marketplace where you can purchase many or all of the objects needed to build a business application. The idea is that someone will build a business object, document it, and put it up for sale in the object marketplace. Although this is a grand vision, I don't see it happening on a large scale. Yes, there are many common business objects between organizations; we all deal with customers who have addresses and purchase products or services from us, but the reality is that my business objects are very different from your business objects. The way I deal with my customers, the way I sell them products and services, is very different from the way you do. This is what gives each of us a competitive edge. Yes, we all need the same business objects, but because we do business differently, we need different implementations of them. Therefore, the marketplace for business objects will never be as successful as the pundits claim. I suspect there will be a small but healthy market for business objects that truly are common between organizations. Because common sets of rules apply to all organizations, I should be able to buy a collection of taxation classes, a set of classes representing a surface address, and potentially a set of classes for accounting. The one caveat is that we need a common environment in which to run these objects, such as the Java Virtual Machine or CORBA (Common Object Request Broker Architecture). Java and CORBA are a good start, but we still need a common approach to the persistence and system layers (CORBA almost has this) to be successful. Over the next few years, I hope the standards efforts within Java and CORBA will pave the road to a business object marketplace. Time will tell. |
http://www.drdobbs.com/a-realistic-look-at-object-oriented-reus/184415594