“面向组件的程序设计”(component-oriented programming,COP)已经被鼓吹得足够久了,这让它多少有点像一个buzzword。什么是COP?如何实现一个COP的系统?avalon是一个不错的参考。
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.
实现COP时,一个重要的设计模式是“控制反转”(inversion of control,IOC):“don't call us, we'll call you”的“好莱坞原则”使每个组件的实现能够独立。另外,avalon用一个极其贴切的比喻阐明了“接口-实现分离”的原则:组件好比演员,接口好比剧本;演员总是很多,各有性格,但都要按照剧本来表演;framework自然就是整幕大戏的导演——template method模式的人性化描述。
准确地说,“剧本”还不仅仅是接口(interface),还应该包括契约(contract)。在IOC的系统中,component无法对其他component作任何假设。实现COP时,design by contract也会是有用的。
At the core of the Avalon framework is the component. We define it as "a passive entity that performs a specific role". This is important to grasp because it requires a specific way of thinking.
A passive entity must employ a passive API. A passive API is one that is acted upon, versus one that acts itself. See the Inversion of Control pattern for an explanation.
The concept of roles comes from the theater. A play, musical, or movie will have a certain number of roles that actors play. Although there never seems to be a shortage of actors, there are a finite number of roles. I am not going to make reference to different types of roles at this point, but simply bring the concept to light. The function or action of a role is defined by its script.
We are introducing this concept now because you need to have it in mind when you are designing your system architecture. Think of the different roles in your system, and you will have your "cast" of components so to speak.
For each role, you need to specify its script, or interface to the rest of the system. To be honest the interface is not enough. There are specific contracts that you must define and keep in mind when you specify your interfaces. In other words, what users of the component must provide, and what the component produces. When the interfaces and contracts are defined, you can work on your implementation.
John Donne wrote, "No man is an island." to communicate that we are all interdependent. The same is true for the component. That is why there are different concerns regarding the component. In the section on roles we specified one of the concerns: the role. The concerns directly supported by the Avalon Framework are: configuration, external component use, management, and execution.
As you might have guessed, each one of these concerns has a separate interface that describes that concern. We will delve deeper into the interfaces and the reasoning behind them in other sections. It is important to know the order of precedence for the concerns so that you know the overall contracts of how they are put together.
The contract surrounding this order means that the methods defined by each of those interfaces are called in a specific order by the object that created the component. Each interface represents a narrow view of the component or object being controlled.