Defining Components - A pragmatic look at software building blocks

Yesterday I argued, we´re really living in the decade of the component - and not in the good old objects or service hype days. Also I sketched out what I think is necessary to arrive at true software building blocks as the next higher level of abstraction above objects/classes: Contract First Design (CFD) and Microkernel based architecture.

CFD is about separating the interface of components from the components themselves. And Microkernels are about enabling you to benefit from this separation throughout the implementation. Because it´s one thing to have a contract, and another not to circumvent it and directly bind a client component to a provider component implementing this contract. Arriving at a contract is pretty easy, it´s just sitting down and writing it up. But not statically binding components to each other is difficult, because it needs technological support - which is not as readily available as would be preferrable.

In addition to this we need to think about what a component is in the first place. How does it differ from an assembly, for example?

First I´d like to make clear, I don´t think, the term "component" carries with it anything about who builds a component or user interface concerns or whether a component has to do with distributed systems. When looking at the literature, though, "component" is heavily overloaded with meaning. Very often "component" is used to describe a shrink wrap user interface control like a grid. On other occassions "component" are pieces of software, that need to be hosted in a service broker or application server.

I suggest, we rid ourselves of such limiting points of view and stick with a couple of tenets. Wikipedia refers to Clemens Szyperski and others with the following criteria a piece of software needs to fulfill in order to be called a component:

  1. Multiple-use
  2. Non-context-specific
  3. Composable with other components
  4. Encapsulated i.e., non-investigable through its interfaces
  5. A unit of independent deployment and versioning

That´s not bad, I´d say. But when you read for example Szyperski´s "Component Software" you can´t shed the feeling of some not so explicitly stated premises: For one, components again and again are put in context with CORBA. That hints to components have something to do with distributed applications. Secondly, the term (horizontal or vertical) "component market" is used to hint at them being manufactured by some 3rd party.

Sure, Microsoft created a very lively "component market" when introducing VBX components. Also, COM+ applications are commonly viewed as components. But I think, it is wrong, to include "market"/3rd parties and distribution into the notion of a software building block. So I´d say, the 5 tenets of components should be:

  1. A component encapsulates some well separated behaviour and should be viewed as a black box. A client does not not, how a provider component actually fulfills his requests, whether it´s internally build of many parts or is very simpel.
  2. A component communicates with other components solely along clearly and separately defined contracts. These contracts should define as much syntax and semantics of the communication as possible and necessary, e.g. not only operations and data, but also quality of service requirements or out of band data for security concerns.
  3. A component can be composed with other components to form a larger whole. For this, components need not be changed. Assembling the whole is done by configuring settings external to the component´s code.
  4. A component defines its offerings and requirements in a specification listing the contracts it implements as well as the contracts it needs partners for.
  5. A component can be separately deployed and versioned. As long as the specification has not changed, no other components should need to be changed or replaced.

In how far differ these tenets from Wikipedia´s definition? C, D, and E are carried over to tenets 3, 1, and 5. Tenets 2 and 4 have been added. Definitions A and B have been droped.

Why were A and B droped? In my view, they are detrimental to the acceptance of software building blocks. A requires them to be defined in a manner so they can be reused often. But why? Because the definition has a "component market" in the back of its head. However, this would severely limit the use of components. It would put a burden on the architect, because generalization of functionality is often hard to achieve. And it suggests, that components are something you buy and don´t build. No other industry, though, forces this notion upon their building blocks. If a car manufacturer needs a certain building block/part, it builds is itself according to clear specs. Only if that´s too expensive it seeks to outsource the production. Outsourcing might require a notion of building blocks - but not the other way around. But that´s what the software industry is still thinking.

From B it´s not really clear what is meant: a hosting context for a component or a domain context. Let´s tackle each in turn: Why should a component necessarily be independent of a hosting context? To promote reuse? I don´t think that should be mandatory. Why should it be independent of a domain context? To make it more attractive to a "component market"? I don´t think that should be mandatory.

You see, to have a highly reusable component that sells well in the "component market" certainly would be great. I´d love to become rich with such a component. But are those parts of the definition really necessary? I don´t think so. They severely limit what components can do for a software project: make it more manageable, more maintainable, easier to understand and test.

Why have tenets 2 and 4 been added? I think, both are needed to support the others. Without clear contracts (2), there is no real encapsulation. And without a specification (4) there is no composability and independent deployment.

Now, how do different kinds of todays "components" map to the 5 tenets?

  3rd party GUI controls COM+ components aka ServicedComponent (Web) Services
Encapsulation +++ +++ +++
Contracts - + ++
Composition - + +
Specification --- --- ---
Deployment ++ ++ +++

(Web) Service are closest to the "ideal" of components as defined above. That´s easy to understand: (Web) Services build on an inevitable existing "building block": a process. However, they too lack a specification in the above sense. A service is defined by a contract, which describes its offerings. But I don´t know a necessariy definition of the contracts it depends on. Now you might say: Why should there be, that´s an implementation detail and should be hidden. But I say: Sure it should be hidden, what exactly a service (or other component) actually does with another provider component. But it should not be hidden, that it needs some other components. Because if that´s hidden, it cannot be configured from the outside (which I deem necessary for easy replacement). An analogy: To replace the motor of a car, I don´t unwind srews within the motor but only screws attaching it to other parts of the car.

My bottom line concerning existing component technologies: They are good at encapsulation, but they are not good enough yet at composition. And that stems from a lack of specifications which in turn has to do with how contracts can be and are defined.

But (Web) Service certainly have made progress compared to local components. Now it´s time to catch up regarding small scale components, i.e. intra-process components.

PS: I guess, I on thin ice here when suggesting general tenets for a general component concept. Many, many smart people have wrecked their brains about the same topic. But since I don´t see a comprehensive component concept materialize for small scale components, I want to put a stake in the ground to maybe spark a new discussion about this extremely important topic. So, if you like, prove me wrong. I´d be glad to learn, how you achieve easy software system composability today.

No Comments