Let this be the place in WikiWiki
where we discuss the definition of a component in today's fast-moving world of ComponentBasedDevelopment
Discussion of whether the meaning of component should be discussed at all refactored to NeologismsNotHomonyms
Here are some definitions of Component:
- "A component is a nontrivial, nearly independent, and replaceable part of a system that fulfills a clear function in the context of a well-defined architecture. A component conforms to and provides the physical realization of a set of interfaces." (PhilippeKrutchen?, RationalSoftware?)
- "A runtime software component is a dynamically bindable package of one or more programs managed as a unit and accessed through documented interfaces that can be discovered at runtime." (GartnerGroup?)
- "A software component is a unit of composition with contractually specified interfaces and explicit context dependencies only. A software component can be deployed independently and is subject to third-party composition." (Clemens Szyperski, ComponentSoftware)
- "A business component represents the software implementation of an autonomous business concept or business process. It consists of the software artifacts necessary to express, implement, and deploy the concept as a reusable element of a larger business system." (WojtekKozaczynski?, SSA)
- "A component is a unit of distributed program structure that encapsulates its implementation behind a strict interface comprised of services provided by the component to other components in the system and services required by the component and implemented elsewhere. The explicit declaration of a component's requirements increases reuse by decoupling components from their operating environment." (Steve Crane's definition of component, from a paper co-written with NatPryce last year. See http://www-dse.doc.ic.ac.uk/~np2/pubs.html) That page contains three papers written by Steve Crane and Nat Pryce, published in two different years, none of which as of 2004 were "last year". Which paper are you talking about? I found it in section 2.1 in this one: http://www.doc.ic.ac.uk/~np2/papers/iccds.pdf
- "A component is an object in a tuxedo. That is, a piece of software that is dressed to go out and interact with the world." -- MichaelFeathers
- "Software components enable practical reuse of software parts and amortization of investments over multiple applications. There are other units of reuse, such as source code libraries, design, or architectures. Therefore, to be specific, software components are binary units of independent production, acquisition, and deployment that interact to form a functioning system." (Clemens Szyperski, ComponentSoftware Preface)
- "A component is a physical and replaceable part of a system that conforms to and provides the realization of a set of interfaces...typically represents the physical packaging of otherwise logical elements, such as classes, interfaces, and collaborations." (GradyBooch, JimRumbaugh, IvarJacobson, The UML User Guide, p. 343)
- "Components are self-contained instances of abstract data types (ADTs) that can be plugged together to form complete applications." (DougSchmidt, How to Make Software Reuse Work for You, Jan. 1999 C++ Report, p. 51)
I too prefer number 3, but it doesn't include the concept of the framework
. Components are designed to fit into a framework, and frameworks exist to support componentization. Frameworks encapsulate large-scale abstractions to help one think about a problem domain, while components encapsulate small-scale abstractions within the domain of the framework.
It is the framework that provides the "well-defined architecture" and the run-time support for "third-party composition". The framework is (or should be) the only implicit context dependency of a component.
Toward the end of this thread, MichaelFeathers
pointed out that many of these definitions don't capture placing multiple components into a single binary unit. This is an important reality in CBD practice, so I feel we should clearly define component and
framework in the context for the ComponentDesignPatterns
language. Framework should complement component and ComponentFramework
should also be added to the many different kinds of software frameworks that exist today.
I'm actually being even more controversial. I've noticed that some people actually call the the single binary unit the component rather than the multiple things that are placed in them. It is the kind of thing that begs for resolution in a definition. Is a component a library of entities behind interfaces, or a single entity behind an set of interfaces? Or both?
My goal right now is to resolve this, so I'm not spending much time finishing my paper on layering frameworks. You are definitely onto something. Our definition should be as pragmatic as possible - it should fit if you do beans or COM, or any other type of CBD. I'll keep thinking and throw something onto the top of this page when I get something that we can slice 'n dice.
In C++ and COM, the programmer using a component uses abstract C++ class stubs. These stubs inherit from base interfaces stubs even though inheritance isn't possible in COM at the component level. For example, if you have an interface IFoo with methods Bar1, Bar2, and Bar3, then you will see an IFoo stub with methods corresponding to them, and it will subclass IUnknown, which has AddRef
, Release, and QueryInterface
Once you CoCreateInstance
, it returns a pointer which you can use to QueryInterface
into the right interface. Then you use the stub to call methods and eventually Release when you're finished. All of this is done via the abstract class the stub gives to you to interact with the component.
When reusing a component, packaging and location are irrelevant, and you are forced to interact with the class in an abstract manner. When reusing a class, whether through inheritance or decomposition, you have access to its entire state (except for private class members) and don't have the benefit of conforming to a defined interaction protocol. You are forced to learn the implementation of the reused class like you developed it yourself.
Two quick thoughts. I want to challenge the notion that a framework is necessary for components. COM controls, for instance, are components, yet they are blissfully unaware of the context that they will run in. At least in Nat's sense of large-scale abstractions. However, I agree that a good contextual framework is where it is at for value.
The other thing is that I tend to agree with Clemens' definition (3) but I do get tripped up by the fact that what he and many people call "components" are actually more at the class level rather than the instance level. Because I like the way that TheSourceCodeIsTheDesign
allows us to make parallels to other forms of engineering, I want to call the instances the "components."
To me, components and frameworks can be understood in terms of "plugs" and "sockets." If you have something with only "plugs", it is a component. If you have a component with some "sockets" then it acts as a framework for other components. Maybe framework isn't a terribly useful word in this context? I get the sense that "framework" in a composable blackbox context is more like the background to whatever you consider in the foreground.. a GestaltPsychology?
Components are a piece of software, instances are not. But instances are implemented by a piece of software called class. Therefore components are at the class level! -- PeterMaier
I agree that is the way that people use the term, but look at it this way. I ask you to hold out your right hand and I put a screw in it. Is that a component? I put a catalog containing a spec of a screw in your left hand, is that a component? The former fits in physical engineering. Why not software? -- MichaelFeathers
Perhaps because the physical artifact built with the screw is the final product. When we write software, we are building a specification or template from which multiple in-memory instance can be created. -- DavidAllsopp
Question to Michael:
When you say "yet they are blissfully unaware of the context that they will run in," are you referring to the container holding them or the COM infrastructure?
''Yes. I meant the first one, and I hope I understood Nat correctly. My point is that there are many components which do not make assumptions about other things in the problem domain. They just understand some very abstract connection protocol which leaves many option open.
I don't think that a COM component is blissfully unaware of the context in which it is run. Being a COM object does not make that object a component. COM is no more than an object model and the implementation of that model. The COM runtime provides rules and mechanisms for instantiation of objects, querying for interfaces on those objects, object identity, and control of objects' lifetimes. However, the semantics of object interfaces make sense only in some other context built upon COM (the framework). If you instantiate a random COM object you have no idea what to do with it, because there is no framework in which it fits.
COM objects can be used as components once one has designed a framework into which components can be plugged and codified that framework in terms of COM interfaces. E.g. OLE and ActiveX define a number of interfaces which codify potential interactions between components, such as drag-and-drop protocols, visual composition, serialization etc. This means that an ActiveX application (ie: an application built using the ActiveX framework) can use COM to instantiate an object, query it for well understood interfaces and use those interfaces to bind the object/component into the framework.
Another framework built upon COM is DirectShow
components cannot be embedded in an ActiveX document and ActiveX controls cannot be plugged into a media-stream - they are two completely different frameworks that both happen to use COM as their underlying object model. (The ActiveMovie?
ActiveX control is an adapter that links the two, but that's another matter...)
The same holds for Java. A Java program can use the reflection API to instantiate an object of any (instantiable) Java class. However, if it doesn't have a framework in which to plug that object there is nothing it can do with it - it can't treat the object as a component.
And I'd argue that the same holds for any component model. Although there may be "components which do not make assumptions about other things in the problem domain", those which provide system services for example, I do not think that they can "just understand some very abstract connection protocol which leaves many options open" because it would be impossible to actually make use of them. I think well defined interaction protocols are essential in any component model.
Nat, great summary, and I completely understand the technical side of your point. To add to it, you can do ATL in C++ or do raw COM programming in C (if you're a real gearhead) to implement COM objects that fit into the MTS application framework. You can implement shell extensions, which are in-process COM servers that allow you to extend the Explorer shell with your own custom extensions. You can plug in-process COM objects into the Microsoft Management Console, which is another ComponentFramework
. There's a bunch more, but I've got to catch a flight (unfortunately not one taking me to OOPSLA ;-( )
You say "COM is no more than an object model and the implementation of that model." That's true. COM is a binary standard in that regard.
Here are some perspectives on "what COM is..."
- COM is a Specification; ...a real piece of paper at http://www.microsoft.com/com.
- COM is a Binary Standard. It defines what it means to be a COM object and how a COM object is called. It is the glue.
- COM is a philosophy of modern software development. The COM specification describes a world in which applications are built from components. COM is also a philosophy of designing your software by the concept of interfaces.
- (...and Don Box and the guys at Developmentor would say that COM is a religion!)
You are right. The semantics of object interfaces make sense only in some other context built upon COM (the framework).
We all agree that COM alone is not the framework. Components alone can be built on it, but a big part of the pie is missing. COM-based components, component frameworks, and components that plug into them do a better job at representing the whole picture of CBD.
In patterns-discussion, MikeBeedle
said "OMG's initiative to make CORBA a component architecture is called BOCA, and it was approved earlier this year (4/98), but needless to say, has not been implemented by any vendors." Here, a CORBA implementation (e.g., Iona's Orbix) acts as the COM equivalent. What's missing is something like BOCA. Interestingly, Microsoft had what OMG wants to do with BOCA, perhaps starting with VBXs, before COM ever existed.
It is called "Corba Component Model" as of 4/2002,
What did VBXs have that COM Controls (ActiveX Controls) don't have other than a brain-dead 16 bit limiting architecture?
I guess that the difference between a VBX and an OCX (ActiveX control) is that they have different object models. An ActiveX control is built upon COM, while a VBX is not and is, I guess, closely tied to whatever object model VisualBasic
might have. Certainly the Automation interface used by ActiveX controls is closely tied to the VisualBasic
implementation (as well as being completely redundant). -- NatPryce
As I understand it from Microsoft, yes, the IDispatch (Automation) interface was originally created by the actual VB team (and not the COM team) for late binding languages like VB and now VBScript, etc. Because of the limitations of the data types that VB could handle, this interface was necessary. VB has since changed but we are left with this legacy.
Yes, that's the story I heard. However, since the MIDL compiler generates all the appropriate marshalling/unmarshalling code, a scripting language could invoke object operations by marshalling each invocation into a buffer and passing it to the server-side skeleton for dispatching. This would move all the data-conversion operations out of the server object and into the runtime of the scripting language, meaning that it would be the same for each object instead of being specified on an object-by-object basis as it is at the moment. Then COM object developers would get scripting for free, instead of having to implement IDispatch, which is a right hassle. This is how CORBA supports scripting - one can use the Dynamic Invocation Interface or create an "encapsulation", a buffer containing a marshalled invocation, and pass it to the ORB for dispatching. Anyway, this is not exactly germane to the issue so I'll shut up now... -- NatPryce
Even though their models were different - and one could argue that VBXs didn't really have much of a model except for the requirement of 16-bit DLL entry point ordinals that were used to gather properties, deal with events, persistence, etc. - one could argue that they were still models that were used in the context of component development and assembly. Before VBXs and VisualBasic
, we had custom controls. I remember creating a few of these back in 1989 while testing the dialog editor that came with the Windows 2.0 SDK. Today, ActiveX controls use COM as their model.
I think your main point is that a ComponentFramework
must exist (in this case the ActiveX control container framework) that requires implementation support for the usual suspects (e.g. IDispatch, IPersistObject, IOleInPlaceActiveObject, IPersist, etc.) to allow you to plug components (ActiveX controls) into it. -- PhilipEskelin
Yes: The ComponentFramework
must exist in the form of the COM interfaces you have listed to allow components to plug into it.
This is an exciting topic and I commend you guys on this much needed pattern language. Thanks.
-- (originally by someone else, but also the sentiment of JeffGrigg
Thanks! Always good to get words of encouragement. I took much of this great discussion and tried to factor it into ComponentFramework
. Check it out. I think a component framework allows you to essentially create an infrastructure that enforces certain requirements in order for the component to be 'legal'. For instance, at the lowest level, if COM is the ComponentFramework
, then a COM component is required to implement IUnknown.
I think that there are two layers here:
- The "framework" that defines supports the componentization of a system (what a component is and the application protocols it uses to interact with other components). (E.g: ActiveX, DirectShow, JavaBeans)
- The "middleware" that defines how invocations are represented and passed between binary components. (E.g: COM/DCOM, Java/RMI, CORBA)
In terms of the ISO/OSI 7-layer model, the "framework" is at the Application Layer while the "middleware" is at the Presentation and Session Layers.
Another view: the framework is *what* components communicate and the middleware is *how* they communicate.
However... middleware is the wrong term here I think. Middleware implies distribution and OS independence, while the "middleware" I'm talking about here might well be constrained to be within a single address space or OS dependent.
To summarize this discussion, I think these attributes are what identifies a "component-based" system, c.f. an object-oriented system:
- Encapsulation: A component encapsulates state and/or behavior behind a strict interface.
- ContextIndependence: A component is only dependent on it's framework and other components in its operating environment. Dependencies on other components are made explicit and set up by the entity that instantiates the component rather than being hidden within the component.
- Interaction Protocols: Components interact according to well-defined interaction protocols. These interaction protocols are defined in terms one or more roles that components can play in the interaction. The interface of a component is composed of the various roles that the component plays in its interactions with other components in the system.
- Packaging: A component is an independently packaged piece of software. Run-time packaging support allows a system to instantiate the component and integrate it into the system.
- Framework: Runtime support for the componentization of the system. The framework might be organized as a higher-level application framework defined in terms of a low-level framework that supports instantiation and binding.
Secondary characteristics that are useful, but not essential for something to be a component, include:
- TransparentDistribution: components do not need to know the physical location of other components with which they interact.
- InterfaceDiscovery: allows a component to make use of another component without a-priori knowledge of the interaction protocol used.
- Language Independence: allows components to be built in any (programming) language and be used by components built in any other language.
I'm trying to remember something I saw Robert Martin write either on news:comp.object
or else the OTUG mailing list. It was something like ... a class is a compile-time unit of logical design, whereas a component is a run-time unit of physical design. Hmmn, no that's not quite right. Ill see if I can find it. -- BradAppleton
This page includes many mentions of frameworks. Frameworks are discussed in more detail in the page about ComponentFrameworkDefinition
Just getting back to this page and some of the comments above. I agree that components must have some context or framework to be useful, but I think that is true of objects as well. Excel is an application, but it can be called from VB as a component. In that case the "framework" is optional unless we consider the OS the framework, or just say that Excel is only a component at times. Or we could say that instances of Excel are components, or the types or instances of its composed objects.. workbooks, worksheets.. are components.. Is "Excel Worksheet" a component or is the worksheet named "1998 Fiscal Budget"? Or both?
Frankly, the picture is more confusing to me than OO ever was. The only common point that I can find in all the definitions I've heard is the fact that the user of the component may not be the same as the developer.. components are somehow packaged for third party use. That is a very wide net; I've even seen libraries and documents called components.
playfully said "An agent is an object with an attitude." For me, until I can get a narrower generally accepted definition (and I hope I can), a component is an object in a tuxedo. That is, a piece of software that is dressed to go out and interact with the world.
Michael, I empathize your confusion and think it's imperative we clear this up in the introduction of the pattern language to its reader (along with defining framework for that matter). I like what Brad thinks Robert Martin said about a component being a runtime unit of physical design. And I found a different definition from the Preface of Clement Szyperski's book Component Software
that was placed in definition #7 at the top of this page.
I like the "binary units of independent production, acquisition, and deployment" part. If production was the only aspect mentioned, then one could argue that class libraries are independently produced as well. Same with acquisition. But (at least for me) I think independent deployment of a binary unit is what distinguishes it for me. Patterns like InterfaceDiscovery
and others can be used in this context to reflect upon or discover new components via their interfaces. What do you think?
I agree. Szyperski's definition is the most consistent I've seen. The one area of component definition that I find most troubling (and I forget where Szyperski falls on this, I've read too many component definitions recently and my copy of his book is 300 miles away right now) is whether components must/may have run-time discernible identity. For instance, if I distribute a DLL that defines/contains three ActiveX control types, do I have one component or three? The former makes components equivalent to libraries in my mind. The latter makes them classes with published interfaces. It is this distinction that is most interesting to me.
I was too caught up in looking at what I felt was the most accurate definition of the ones above to realize the area that troubles you is a point none of them completely addresses. Here are two experiences that complicate discernible identity:
- I've created what I called "components" which were really just cross-platform DLLs (or and shared libs on UNIX) containing a group of like C++ classes used by applications. A header file corresponding to the library linked into the application was included in application that reused them.
- In another case, I had a few dozen ActiveX controls that used a shared set of base classes that were layered on top of a few other frameworks and components. For deployment and performance reasons, all components and the framework and the shared classes were consolidated into a single physical DLL that contained all ActiveX controls and shared classes.
In both cases, the physical unit of binary independence was transparent to the user. Similar to TransparentDistribution
in the second example, COM allowed the client to instantiate many of these components without knowing they were all in the same physical entity. JAR files containing multiple JavaBeans
presents a similar bulk packaging concept for Java components.
Perhaps we can improve upon these definitions by addressing this issue.
This is the "packaging" aspect I included in the summary above. What patterns are related to packaging? Supporting multiple forms of packaging seems very useful. For example, COM supports components packaged in DLLs, executables and executables on explicitly named remote machines. -- NatPryce
What summary are you referring to? - I can't seem to find it.
The bulleted list above (now in the center of this discussion, it was at the bottom)
However I understand your aspect. Today, packaging decisions remind me of ProcessBoundary
- you should explicitly think about where you're placing your components since additional security, reliability, and transactional requirements arise if you are dealing with a distributed component as opposed to in-process. Later, the programmer will be abstracted away from these things, but for now I think you're right - this is a good area to look for patterns. I'm also (after finishing the layering paper) trying to look into more design patterns for CBD.
What do you think about definition 8 from the UML User Guide? It seems generic enough and fits CBD in practice. I'm starting to think about components being more about packaging in the physical sense, and about abstract interactions in the logical sense. Here are two contrasting examples:
- 20 ActiveX controls in 1 OCX file
- Equates to 1 physical component, 20 logical. It packages more in one punch by being one large binary, but the tradeoff is that you deploy all twenty controls when you deploy the component. Good for deployment in business applications where consistency is important, network bandwidth is high, or systems have memory and disk capacity to facilitate bulk packaging.
- 20 ActiveX controls in 20 OCX files
- Equates 20 physical components, 20 logical. Each is packaged and deployed separately. Good for Internet-based ActiveX controls where components need to be lightweight.
When thinking about component as a physical package that contains one or more logical components typically presented through a set of interfaces, the assembler is abstracted from packaging details through TransparentDistribution
, and abstracted from implementation specifics through AbstractInteractions
, but must still deal with secondary effects of the way packaging is done or whether it changes with the evolution of the system. Seems like a ripe area for more patterns. Kyle/Nat/anybody care to comment on how this applies to Java?
The Java equivalent to an OCX (which is just a DLL that contains certain functions with well-known names and semantics), is the JAR file. A JAR file is a ZIP file that contains package directories and class files in those packages, and can also contain a signature. As with the ActiveX example, the component developer has to decide whether to package single or multiple Java beans (or other components) in a JAR file.
One can also distributed Java classes individually which increases download time (due to the limitations of HTTP) but can reduce the number of classes transferred to the client. One disadvantage of distributing classes individually in this way is that, because Java loads and links classes lazily, the user notices the components "freezing" when threads enter code of classes that have not yet been loaded over the network.
Very good summary, Nat. I'd only like to add that in EJB's a Jar file can also contain Deployment Descriptors, which are serialized files that give additional information about the nature of the EJB components contained therein.
Deployment Descriptors sound a lot like ContainerManagedPersistence
. Here the container is more for deployment purposes, not user-interface purposes. But the pattern still seems to apply. Maybe we can update ContainerManagedPersistence
to include this aspect.
I really like the way you addressed that, Philip. I'd thought about breaking the definition apart into logical/physical components, but it did not sound right to me until I saw your treatment. Regarding Grouped Distribution.. it could be a pattern, but it sounds to me like a quality of physical components. A physical component acts as a distribution container for logical components.
Then again, Grouped Distribution does solve a problem. Do you all think that is the way to go? If you think so, would anyone mind if I took a stab at it?
Thanks for the compliment, but I must say that my thoughts are a culmination of the discussions we've all had on this thread and through reading informative and thought-provoking white papers and/or books on the topic. Feel free to take a stab at any of the patterns, especially the one's we're talking about here.
Two decision patterns emerging from the physical and logical aspects of components are IndividualPackaging
of components. I'm starting to feel like ComponentFramework
is a special component where many patterns apply in both cases, but additional ones apply in the framework case. I like something I picked out of DougSchmidt
's Jan. 1999 C++ Report article:
- The relationship between frameworks and components is highly synergistic, with neither subordinate to the other. Frameworks can be used to develop components, whereby component interfaces provide Facades for internal class structures inside a framework. Moreover, components can be used as "pluggable strategies" within a framework.
To me, this supports my hypothesis that a component framework is just a special type of component. Components and component frameworks are indistinguishable in the physical sense, since a component or component framework can both be local, remote, in-process, or consist of one or more independent binary entities. They are distinguishable in the logical sense for design reasons stated above and in ComponentFramework
Methinks that none of the above definitions succeeded in defining components.
So here are some observation of mine:
- A component definition should make the component class a proper subset in the most specific enclosing class of software artifacts. The definition should therefore emphasize the specific difference.
- A definition should avoid making use of orthogonal aspects that could only define subclasses of components. Distribution is an orthogonal aspects for example and we shouldn't try equate distributed components = components. Object Oriented Persistence like in Entity Bean is another example of orthogonal aspect.
- Packaging is an orthogonal aspect. No matter if we package a component as binary unit or as source code, as long as the user of the component can use it as component we shouldn't care.
- Clearly defined interfaces are common to any well-designed software artifacts. Structured programming should not be equal to component based development.
- Encapsulation is obvious to any well designed software artifact.
So, while I'm not sure what the full definition might be , and still not sure what is the most specific enclosing class of software artifacts - if there is one, I have an idea about what differentiates components from other software artifacts.
- they are amenable to being used (composition,configuration, linking) by programming tools such as IDEs. They essentially have to be usable in other ways than just coding against their programmatic interface
- they all have at least two life cycles and two sets of interfaces, the "design-time" and the "run-time" and the two states are clearly defined in their contract. The design-time state and set of interfaces allow them to interact with the tool and the developer as their end user.
I know this definition is not very inclusive, EJBs would failed to be components, but what do you think?
It's beginning to get to me that people are using the wrong DefinitionOfEncapsulation
. A lot.
What makes a good software component? Now there's a question.
Good question. If a component is a replaceable part
, then I would say a good component
should be easily replaceable.
This begins to highlight measurable differences between objects, libraries, frameworks and the various ways we can implement components. We can now consider the cost and value of providing: compile-time vs run-time binding, minimal but complete interfaces, interface implementation separation ...
I like to consider use cases that involve replacing part of the system to compare these different approaches in the context of an application and an organization. (I think I first read about this from AlistairCockburn)
I think the correct and complete definition of component has been given by Szyperski: "A software component is a unit of composition with contractually specified interfaces and explicit context dependencies only. A software component can be deployed independently and is subject to third-party composition." (Clemens Szyperski, ComponentSoftware
However this discussion seems to got lost in different ways of term usage.
The term component does not depend
on language (C, Java or VB), on time constraints (compile-time or run-time), object's nature (plain code, library, dll or whole application), object's world (physical world or software world) and so on. Therefore, if you use any words of programming language, frameworks or try to describe its typical behavior to define the term component, the definition is wrong.
I think the term component was invented once
- words like part, portion and fragment were insufficient to describe desired properties
- words like chunk or hunk were not formal enough
- words like detail, segment or section were unsuitable
The term component can be used on several layers: operator is a component of an expression, expression is a component of a statement, a statement is a component of a function, a function is a component of a class, a class is a component of a library (or module), a library is a component of a binary file (dll or what ever), a binary file is a component of an application, an application is a component of a software package, a package is a component of a software distribution, a software distribution is a component of an operating system. Just as example.
Another example from the real world: screw is a component of a shelf, a shelf is a component of a rack, a rack is a component of a cabinet, a cabinet is a component of a room.
A negative example may help a bit more: the bottom part of the tree trunk is not a component, because it cannot be detached from one tree and be attached to another tree without breaking its functionality. One side of a coin is not a component as well, because you cannot detach it from the coin and attach it to another coin.
The term component is a unit, a dynamic unit that can take different meanings depending on the context. This is why a simple usage of term component like "class A is implemented in component B" is syntactically incorrect. You have to say it like "class A is implemented in component B of the library C". The syntax of this term is like "<object X> is component of <object Y>". This way you clearly define the layer and the composition kind.
Any documentation, description or methodology has to clearly define the composition kind, before using the term component, which is then the unit to identify parts/fragments/.../chunks of the named composition. Therefore the unit component may aggregate different properties depending on the environment.
- If you speak about classes and their interdependencies (like inheritance or usage), you don't care about run-time, you don't care about model-instance relation, the inheritance-order is the issue.
- if you speak about dynamically linked objects, you mostly care about run-time issues.
- if you speak about software distribution, you don't care about model-instance issues and you do not speak about compile-time or run-time.
Therefore Szyperski's definition is correct and complete as far as I can estimate for now.