Terms and Concepts
A package is a general-purpose mechanism for organizing the model itself into a hierarchy; it has no meaning to the execution. Graphically, a package is rendered as a tabbed folder. The name of the package goes in the folder (if its contents are not shown) or in the tab (if the contents of the folder are shown).
Names
Every package must have a name that distinguishes it from other packages. A name is a textual string. That name alone is known as a simple name ; a qualified name is the package name prefixed by the name of the package in which that package lives, if any. A double colon (::) separates package names. A package is typically drawn showing only its name, as in Figure 12-2. Just as with classes, you may draw packages adorned with tagged values or with additional compartments to expose their details.
Figure 12-2. Simple and Qualified Package Names

A package name must be unique within its enclosing package. |
Owned Elements
A package may own other elements, including classes, interfaces, components, nodes, collaborations, use cases, diagrams, and even other packages. Ownership is a composite relationship, which means that the element is declared in the package. If the package is destroyed, the element is destroyed. Every element is uniquely owned by exactly one package.
Composition is discussed in Chapter 10 . |
Importing is discussed later in this chapter. |
Figure 12-3. Owned Elements

Visibility
You can control the visibility of the elements owned by a package just as you can control the visibility of the attributes and operations owned by a class. Typically, an element owned by a package is public, which means that it is visible to the contents of any package that imports the element's enclosing package. Conversely, protected elements can only be seen by children, and private elements cannot be seen outside the package in which they are declared. In Figure 12-3, OrderForm is a public part of the package Client, and Order is a private part. A package that imports Client can see OrderForm, but it cannot see Order. As viewed from the outside, the fully qualified name of OrderForm would be Client::OrderForm.
Visibility is discussed in Chapter 9 . |
Importing and Exporting
Suppose you have two classes named A and B sitting side by side. Because they are peers, A can see B and B can see A, so both can depend on the other. Just two classes makes for a trivial system, so you really don't need any kind of packaging.Now, imagine having a few hundred such classes sitting side by side. There's no limit to the tangled web of relationships that you can weave. Furthermore, there's no way that you can understand such a large, unorganized group of classes. That's a very real problem for large systemssimple, unrestrained access does not scale up. For these situations, you need some kind of controlled packaging to organize your abstractions.So suppose that instead you put A in one package and B in another package, both packages sitting side by side. Suppose also that A and B are both declared as public parts of their respective packages. This is a very different situation. Although A and B are both public, accessing one of the classes from within the other package requires a qualified name. However, if A's package imports B's package, A can now see B directly, although still B cannot see A without a qualified name. Importing adds the public elements from the target package to the public namespace of the importing package. In the UML, you model an import relationship as a dependency adorned with the stereotype import. By packaging your abstractions into meaningful chunks and then controlling their access by importing, you can control the complexity of large numbers of abstractions.
Dependency relationships are discussed in Chapter 5; the UML's extensibility mechanisms are discussed in Chapter 6 . |
Figure 12-4. Importing and Exporting
