8/22/98 - Jack Harich - Document Map
Components are software's latest Silver Bullet. They are the successor to "Object Oriented" as the key productivity mechanism. But for most shops OO failed to help much at all, due to its complexity and the paradigm shift required to use it. How can we avoid also muffing up with components? |
There are no earth shattering revelations here, just gentle reminders. The Low Dependency Integrity pitfall is a bit interesting.
Components are unquestionably as much a paradigm shift as Object Oriented. By now they obviously have as much productivity improvement potential, actually much more. System assembly from components, once mature, can easily give us an order of magnitude productivity leap. How can we avoid the pitfalls of component use? How can we achieve high component productivity? These two question are so intertwined we address them together by examining a few key pitfalls:
1 - No Solid Infrastructure
There will be a grave, naive tendency to stitch together components with lots of custom code. "After all, this is what we've been doing for decades, so why change now? After all, I can solve anything with code. After all, code is cool and that's what I'm here for...."
That's the inner talk of a Coding Cowboy, the dominate life form for programmers today. Here's the inner talk we really need:
"What standards do we need for components working with other components? What tools do we need to assemble them efficiently and effectively? What training do we need? How should we change our process?"
That's the inner talk of a cool, calm and collected Component Assembler. Here are the infrastructure features we see as crucial:
Standard Organization - All nontrivial systems need a standard way to organize their components. This allows systems structure and behavior to be treated separately and better.
Standard Services - Reusable non-application specific behavior should be treated as services, and made easily accessible to components via a Service Architecture.
Standard Collaboration - A standard interaction mechanism is necessary for snapping components together. We cannot have gobs of different interfaces or superclasses, because then there would be many components that cannot talk to each other.
Organization Visualization - Complex systems need a way to reduce conceptual complexity and to navigate the system. This requires a well designed visual interface.
Visual Composition - Composing systems from components will require a visual tool. Doing it by hand with code is not scalable. It's possible this can be done with UML, but that means lots of nonstandard relationships and arbitrary organization.
Component Centric Process - To tie it all together and hit truly high levels of productivity we need to adopt a software development process that is component centric.
2 - One Shot Components
Many developers and managers are new to serious, well designed components that can be used in a variety of ways without code changes. It takes a high degree of experience and skill to develop good components. Many will develop components they think are okay but in reality are only suitable for single use. When they try to reuse them and stumble they will reason, "Oh, this is a hard case. Anyone would have trouble here." Not so.
The danger is systems will be developed with lots of one shot components, and when another system tries to use these components it will suffer. Blame will go towards a variety of scapegoats. The fact of the matter is that highly reusable components can be built for any and all problem domains. It just takes a specialist - a Component Developer.
3 - Postponing Components
We estimate it takes 2 to 5 times as long to develop a good component as it does to hard code nearly everything. It takes over twice as long if the developer is still ramping up to component development. This large amount of extra time/cost will cause many projects to postpone components "right now" in the interest of schedules and cost.
The same problem existed for well designed objects, but the numbers are higher for components because they are far more difficult to design. Remember that most components will be facades for subsystems, which is obviously complex and full of gotchas.
This problem can be addressed by adopting a software development process that is component centric. Such a process would have system assemblers and component developers. Projects would commit to use this process, and therefore commit to the extra time and cost investment of high quality components.
4 - Low Dependency Integrity
A problem with large systems is how to assure dependencies (AKA assumptions) remain valid. This is the equivalent of relational integrity. It was never solved for databases until the database vendors built it into the database. This is a clue that we must do the same for component dependencies.
An intriguing way to handle this is Dependency Agents (DA). DAs would automatically examine the system for dependency breaks. This could be done during assembly, during system idle time, after making a large change, when exceptions appear, during testing, etc. It would require supporting infrastructure such as standardized component organization, relationships and communication. It might also require a dependency repository. We have not yet explored this area.
One new technology we need here is Incremental Integrity. This is a pervasive mechanism that enforces system wide integrity whenever any change is made, no matter how small. It goes beyond the low level integrity enforces such as compilers and database relational integrity. It duplicates and improves on the human skills now used to do this at the high level. It starts automatically checking integrity when the first component is added to an empty system. We have not yet explored this, but will probably start with ParamType Definitions and InterParam Dependencies subsystems.
A side benefit is if we can figure out a way to effectively manage dependencies, we may be able to apply it to managing complexity, one of software's trouble spots.
5 - Low Quality Components
The component repository needs a quality gate to avoid low duality systems due to low duality parts. The Component Developers and Reuse Manager could use a High Quality Component checklist. They could also review "candidate components" before upgrading their status to "reusable". The Reuse Manager could track metrics on defects, productivity, user satisfaction, etc. to improve the component base.
Without such a "formal high quality component reuse program" we will inevitably see projects failing due to low quality components, especially as system size increases.
A related danger is premature release of components for reuse. Repeat after me, "I will not release a wine before its time...."
:-)
6 - Components Don't Work Together
This is a more subtle problem. What happens when you snap together a system with 2000 different parts? It will only work smoothly if the parts work together smoothly. This of course requires extreme foresight. It's not just a matter of "fitting" but of supporting each other well. This is a major challenge for component designers.
One definition of components is "A fleet of carefully designed reusables used to build systems." From this you could deduce that the single most important component characteristic is how well it is designed to work with other components.
7 - Components Hard to Reuse
When it comes to reusing components, you've got to:
- Find it to reuse it. For a large repository this means search criteria.
- Evaluate it to decide to reuse it, and not others or build your own.
- Understand it to design how to reuse it. This requires documentation and examples.
- Configure and access it to reuse it at the code or parameter level.
- Deploy it to reuse it.
All these must be addressed well before high reuse is easy.
8 - Building Rather Than Buying
The "Not Invented Here" syndrome will cause many hotshot developers to roll their own components, while perfectly satisfactory ones exist in the market, or even in another department. The "Hard to Find" pitfall mentioned above will cause part of this problem. Not assigning someone to comb the market for reusables will also cause part of this problem.
We anticipate that at first 70% of developers will be Component Developers, 20% will be System Assemblers, and 10% will be Managers. Later this may change to 20%, 70% and 10%. But meanwhile the Component Developers will be so swamped with requests and so new to components that they will not spend ample time combing the market for reusables. The component market is currently hard to search reliably. It will probably take a Component Buyer, a Reuse Manager and a more mature component market to rectify this problem.
9 - The Component Standards Muddle
We have CORBA, COM and EJB as competing standards for components. Which horse should we pick?
Just as they must support multiple platforms and languages, large systems will have to support multiple component standards. Sigh.... This is a fact of life we must accept. To blindly latch on a single component standard is to build systems that are islands.
The situation is too complex to recommend an exact solution now. Therefore we recommend adopting infrastructure and design approaches that are standard neutral and can accommodate all 3 standards and future new standards. Since most of these standards revolve around how distributed components collaborate, the Proxy or Facade Pattern would allow insulation from which distributed standard(s) were used. Whatever you do, don't let a standard dominate your approach to component use.
10 - The API Is Overly Complex
When Microsoft first released their version of collaborating components, OLE Controls, it took a minimum of 20,000 lines of code to implement one. Conferences were held on how to write them. Three inch books on OLE sold like hotcakes. OLE Controls became the workhorse building blocks of Visual Basic. They were also used to stitch together Visual Basic, Excel, Word and Access. It looked like Microsoft was on to something.
Then Visual Basic 4.0 was released with showering fanfare about its new features: more object oriented, collections, 32 bit support, and better OLE Controls. But for 6 months the new fancy controls were too buggy to use. Developers became irate. Microsoft blamed the problem on the fact that third party vendors were late developing the controls. Visual Basic 4.0 was a disaster at first, causing many developers, including yours truly, to begin to look elsewhere for a better language.
The real reason for the problem was the OLE Control API Spec was overly complex. It took top drawer specialists with years of experience to produce rock solid OLE Controls. To salvage the situation Microsoft had to have its own developers frantically help rewrite and debug many of Visual Basic's new controls, because they were written by outside vendors who were less than expert.
Contrast this with the Java Bean Spec, which describes Java's approach to components. The simplest bean can be written in 9 lines of code. (1 field, 1 setter, 1 getter) More complex beans with many properties, events and methods take only a few hundred lines of code. Even highly complex beans with customizers take only a few thousand lines of code. Because of a simple API in the spec, beans have been easy to understand, build and use from the start.
The moral of this story is keep your APIs few in number and simple to understand, and they will allow building castles in the air overnight.
11 - Insufficient Component Expertise
Component design, development, use and reuse requires tremendous component skills to do it well. Just as many developers and shops rushed into using Object Oriented technology with insufficient training, many will repeat this catastrophe with components. From industry experience it takes an average of 2 years for a developer to achieve strong OO skills, and about 25% never "get it". The illusion of "I can do this now. I'm good." is strong. We recommend:
- First mastering Object Oriented skills if you plan to build your own components
- Study mature components and systems built with them.
- Write up your own Guide to Component Use. By inventing this yourself your understanding will be deeper and it will address your particular needs closer.
- Develop several test throwaway component systems before tackling real systems. These can be small but challenging.
12 - Insufficient Up Front Investment
As you can see from several of the above pitfalls, ramping up to components requires a significant up front investment in expertise, organizational mindset, infrastructure and components themselves. Skimping on this is a surefire road to project disaster and much human agony.