link
Avalon
Avalon Central
Home PlanetProductsCentral
Component Oriented Programming (COP)

Component Oriented Programming, or COP for short, takes Object Oriented Programming one step further. Regular OOP organizes data objects into entities that take care of themselves. There are many advantages to this approach. I'll assume that you, being a Java programmer, are familiar with those.

It also has a big limitation: that of object co-dependency. To remove that limitation, a more rigid idea had to be formalized: the component. The key difference between a regular object and a component is that a component is completely replaceable.

There is a lot of buzz in the industry touting Component Based Design (CBD). You will find, that the definition of a component in Avalon is more formal than most companies' definition of a component. Any system developed with the principles of Avalon can claim CBD. In fact the Avalon Framework formalizes CBD more rigidly than the marketing definition. Do not be fooled though, CBD and COP aren't necessarily the same thing. Component Based Design refers to how a system is designed and not how it is implemented. Component Oriented Programming, on the other hand, refers to how a system is implemented and not how it is designed. In practice, you can't implement COP without first designing with components in mind.

Designing a Component

The first step in writing the component is determining how it is going to be used. There will be a number of times where you have a powerful component that can be used in many different contexts. Those contexts may include executing the component from the command line (separate from Avalon), using it as a part of a sub system, or using it as an integral part of Avalon.

All components are an integral part of Avalon, so there is really nothing to be done beyond specifying its interface (role). It is important to identify and document its social contract with the rest of the system. What I mean by social contract is the order of dependencies, what it needs to function, and what it supplies to the rest of the system.

A sub system can either be part of Avalon, or live in a separate context. A perfect example would be a component that can function within a Servlet or Enterprise Application. Neither of those contexts are native to Avalon (though they can easily be built on top of Avalon).

It is important to do even more careful planning than in the first scenario. The reason is that you want the interface to be as generic as possible and still accurately represent its role.

Because the contexts may not be an integral part of Avalon, you must take care to use the component in the same manner as Avalon would. That means that you follow the order of concerns that Avalon has specified for those concerns.

When you are designing a component to be run from the command line (or directly by the operating system), try to separate the main function from the component itself. This is imperative in order to maintain the passive API of Avalon. By designing your component in the manner stated in the previous section, you have effectively minimized what the main function has to do.

Follow the practice of having an object dedicated to the main function that includes the parsing of the command line parameters and initialization of the component. When the component is used the exact same way in every context (including the command line), you minimize the number of locations to look while debugging.

A common mistake is to combine the main function in the implementation of the component. This requires violating the contracts and principles that Avalon is built upon. This violation of the pattern of "Inversion of Control" is aptly dubbed "Subversion of Control" (thanks to Steven Coffman for the name of the anti-pattern).