Back to article

Top 10 Component Mistakes

February 22, 2006



1. Fitting the Wrong Design into Components





2. Writing an "Almost Component"



3. Tight Coupling




4. More Plumbing than Pipes




5. The "One-Time" Component

There are many times you will encounter a situation where you think "this is a one-time situation—there's no way that it makes sense to make this a re-usable component." This will be followed by the temptation to short-circuit the design process, because what you are now designing is a "single purpose" component. Resist this urge whenever possible because the benefits of components are often not clear at this point of the process. Later, when you're refining the system, you'll regret having built any "one-offs." Keep re-usability, external configurability, and all the other component design principals in mind, and most of the time you'll discover that the overall effort to stick to good component design ends up worth it.

Good components are not "faster" to write than one-offs, although they are often easier. They're always easier to test and debug, however, and coding is only one stage in the life-cycle of your component. Component-based systems are almost always faster to construct entirely (when you include time/cost of testing and so forth).

6. Subtle Dependencies

While we've discussed the common mistake of making coupling between components too "tight," there is another, related mistake that is also very common. When attempting to reduce the dependencies of a component, to make it more portable and re-usable, it is often the "subtle" dependences that are overlooked. For example, the need for a component to have access to external files, or to a database with a certain name, might not be seen as "dependencies," and yet they are. Fortunately, these kinds of dependencies are easily detected with a careful unit-test scenario, which can be performed on a separate machine. You do have extensive unit tests, don't you?

7. Crossing Over

You have UI components getting mixed up in the service layer.

8. Everything Is a Nail

In exercising the entirely correct principals of good component design, developers look for re-use opportunities. This is a good thing, and good component design makes re-use easy and painless. A somewhat less common mistake is to take this approach too far: Developers who become familiar with the principles of component design can go on a bit of a "component rampage," component-izing to a degree that is not necessary. If you're trying to write a utility to clean up log files, you probably don't need to go entirely overboard on component design, frameworks, independence, and so forth. It is important to use good judgment in how far to take the component process, so that the benefits are still outweighing the work required. Just because you can doesn't necessarily mean you should!

Another manifestation of the "everything is a nail" approach:

9. Size Matters

In a sense, this problem is the opposite of the last mistake (Everything Is a Nail). If a single component grows beyond a certain size and complexity, it ceases to become a good component. Exactly what measure can be used to determine this limit is hard to say—it's not necessarily lines of code. The number of methods exposed by the components API is a better indicator—too many can be a sure sign that your component should be broken down further.

It is helpful to think of the next step up from components as "services," A group of related components that all together help perform a certain defined set of operations can be collected into a service—and a single API used to expose that service to the rest of the system. Internally, you then can break down into components further, and some of those components can even be used in other services. This reduces the problem of not wanting to componentize too far and thus hit the point where the exposed API is incomprehensible.

10. Not Declaring Your Independence

An essential attribute of a component is a clearly defined API by which other components and software can interact with it. This API needs to be—to mangle a famous saying—as simple as possible but no simpler. The more that complex data types are used as interface method arguments, and the more interface methods there are, the higher the chance of introducing unwanted dependencies into your component.

Despite all of these potential pitfalls, the benefits of a properly designed and well-implemented component-based system far outweigh the disadvantages. The greatest mistakes a developer can make with components is to fail to employ them at all!

About the Author


Sitemap | Contact Us