ccording to Clemens Szyperski
(author of "Component SoftwareBeyond Object-Oriented Programming
,"), software components are binary units of independent production, acquisition, and deployment that interact to form a functioning system. He continues to add that a software component can be deployed independently, is a unit of third-party composition and has no (externally) observable state. In UML we use component diagrams to break down systems into understandable chunks that show the dependencies between components.
In this article I'll use component diagrams to link the class diagrams I discussed in earlier articles (see part 1, "Building Classes," part 2, "Mastering Associations," and part 3, "Aggregating") with the "Deployment Diagrams" in Part 4.
Component diagrams in UML capture the essence of how components interrelate with each other. Each diagram consists of only three different elements: components, interfaces, and dependencies. Components are composed of interfaces to other components as well as dependencies, which show how the components depend upon each other.
Component diagrams differ from class diagrams in how software is represented. In a class diagram the implementation of the classes is source code (which is why code can be directly generated from a class diagram). In component diagrams executable code is represented, which is closer to the deployment diagrams I looked at in the part 4.
Class diagrams show relationships that represent the association between classes from the simple bidirectional association to the more complex compositions and aggregations shown in "Mastering Associations." Component diagram rely on dependencies for component relationships. Dependencies differ from the class associations because associations are references from one class to another and can be bidirectional whereas dependencies demonstrate the dependence of one component on another component. If a component with a dependency is missing, the missing component is added to the Global Assembly Cache (GAC) but nothing else is inferred.
Figure 1. The Different Component Elements: Each component in the example has a stereotype that represents what type of component it is and tags describing the vendor (proprietary is the same as in-house), the language (where applicable), and the version of the component. Dependencies point from the dependent class to the class that it depends upon. The interface will usually have a name, which in some cases will be a method call.
Figure 2. Simple Component Diagram for Richmen, Inc.: Notice that with only six components the diagram is complicated. PortfolioVision displays portfolio statistics, StockVision displays current stock information, Portfolio calculates the client's portfolio value and QuoteData, CustomerStockData, and NewsFeed manage the data inputs.
In class diagrams interfaces are treated as separate classes, which are implemented through their associations with other classes. In component diagrams the interfaces are an integral part of the component and are not always displayed.
Figure 2 is one of the component diagrams for Richmen, Inc., a fictional company used through this series of articles. The diagram is complicated even with only a small number of components. In systems where there are 100+ or even 1,000+ components the complexity of component diagrams is mind-boggling. Validating the diagram for any architectural problems is almost impossible. PortfolioVision depends upon both Portfolio and QuoteData. In the context of the other four components is this good or bad? Are there any obvious architectural problems?
Fortunately there is an easy and organized way to view a component diagram. In the following section I will show this solution using architectural patterns.