Package Organization Guidelines - UML

Guideline: Package Functionally Cohesive Vertical and Horizontal Slices

The basic "intuitive" principle is modularization based on functional cohesion - types (classes and interfaces) are grouped together that are strongly related in terms of their participation in a common purpose, service, collaborations, policy. and function. For example, all the types in the NextGen Pricing package are related to product pricing. The layers and packages in the NextGen design are organized by functional groups.

In addition to the usually sufficient informal guess work on grouping by function ("I think class SalesLineltem belongs in Sales") another clue to functional grouping is a cluster of types with strong internal coupling and weaker extra - cluster coupling. For example, Register has a strong coupling to Sale, which has a strong coupling to SalesLineltem.

Internal package coupling, or relational cohesion, can be quantified, although such formal analysis is rarely of practical necessity. For the curious, one measure is:

RC= Number Of lnternal Relations / Number Of Types

Where NumberOf lnternalRelations includes attribute and parameter relations,
inheritance, and interface implementations between types in the package.

A package of 6 types with 12 internal relations has RC = 2. A package of 6 types with 3 intra - type relations has RC = 0.5. Higher numbers suggest more cohesion or relatedness for the package.

Note that this measure is less applicable to packages of mostly interfaces; it is most useful for packages that contain some implementation classes.

A very low RC value suggests either:

  1. The package contains unrelated things and is not factored well.
  2. The package contains unrelated things and the designer deliberately does not care. This is common with utility packages of disparate services (e.g., java.util), where high or low RC is not important.
  3. It contains one or more subset clusters with high RC, but overall does not.

Guideline: Package a Family of Interfaces

Place a family of functionally related interfaces in a separate package separate from implementation classes. The Java technologies EJB package javax.ejb is an example: It is a package of at least twelve interfaces; implementations are in separate packages.

Guideline: Package by Work and by Clusters of Unstable Classes

The context for this discussion is that packages are usually the basic unit of development work and of release. It is less common to work on and release just one class. Unless a package is massive or very complex, a developer is often responsible for all the types within it. Suppose

  1. there is an existing large package PI with thirty classes, and
  2. there is a work trend that a particular subset often classes (CI through CIO) is regularly modified and re - released.

In this case, refactor PI into Pl - a and Pl - b, where Pl - b contains the ten frequently worked on classes.

Thus, the package has been refactored into more stable and less stable subsets, or more generally, into groups related to work. That is, if most types in a package are worked on together, then it is a useful grouping.

Ideally, fewer developers have a dependency on Pl - b than on Pl - a, and by factoring out this unstable part to a separate package, not as many developers are affected by new releases of Pl - b as by re-releasing the larger original package PI.

Note that this refactoring is in reaction to an emerging work trend. It is difficult to speculatively identify a good package structure in very early iterations. It incrementally evolves over the elaboration iterations, and it should be a goal of the elaboration phase (because it is architecturally significant) to have the majority of the package structure stabilized by elaboration completion.

This guideline illustrates the basic strategy: Reduce widespread dependency on unstable packages.

Guideline: Most Responsible Are Most Stable

If the most responsible (depended - on) packages are unstable, there is a greater chance of widespread change dependency impact. As an extreme case, if a widely used utility package such as com.foo.util changed frequently, many things could break. Therefore, Figure illustrates an appropriate dependency structure.

Figure 35.1 More responsible packages should be more stable

Visually, the lower packages in this diagram should be the most stable.

There are different ways to increase stability in a package:

  1. It contains only or mostly interfaces and abstract classes.
    • For example java.sql contains eight interfaces and six classes, and the classes are mostly simple, stable types such as Time and Date.
  2. It has no dependencies on other packages (it is independent), or it depends on other very stable packages, or it encapsulates its dependencies such that dependents are not affected.
    • For example, com.foo.nextgen.domain.posruleengine hides its rule engine implementation behind a single facade object. Even if the implementation changes, dependent packages are not affected.
  3. It contains relatively stable code because it was well - exercised and refined before release.
    • b or example, java. util.
  4. It is mandated to have a slow change schedule.
    • For example, java.lang, the core package in the Java libraries, is simply not allowed to change frequently.

Guideline: Factor out Independent Types

Organize types that can be used independently or in different contexts into separate packages. Without careful consideration, grouping by common functionality may not provide the right level of granularity in the factoring of packages.

For example, suppose that a subsystem for persistence services has been defined in one package com.foo.service.persistence. In this package are two very general utility / helper classes JDBCUtililities and SQLCommand. If these are general utilities for working with JDBC (Java's services for relational database access'. then they can be used independently of the persistence subsystem, for any occasion when the developer is using JDBC. Therefore, it is better to migrate these types into a separate package, such as com.foo.util.jdbc.Figure illustrates.

Guideline: Use Factories to Reduce Dependency on Concrete Packages

One way to increase package stability is to reduce its dependency on concrete classes in other packages. Figure illustrates the "before" situation.

Suppose that both Register and PaymentMapper (a class that maps payment objects to / from a relational database) create instances of CreditPayment from package Payments. One mechanism to increase the long - term stability of the Sales and Persistence packages is to stop explicitly creating concrete classes defined in other packages (CreditPayment in Payments).

Figure 35.2 Factoring out independent types

Figure 35.3 Direct coupling to concrete package due to creation

We can reduce the coupling to this concrete package by using a factory object that creates the instances, but whose create methods return objects declared in terms of interfaces rather than classes.

Domain Object Factory Pattern

The use of domain object factories with interfaces for the creation of all domain objects is a common design idiom. I have seen it mentioned informally in design literature as the Domain Object Factory pattern, but don't know of a published reference.

Guideline: No Cycles in Packages

If a group of packages have cyclic dependency, then they may need to be treated as one larger package in terms of a release unit. This is undesirable because releasing larger packages (or package aggregates) increases the likelihood of affecting something.

Figure 35.4 Reduced coupling to a concrete package by using a factory object

Figure 35.5 Breaking a cyclic dependency

There are two solutions:

  1. Factor out the types participating in the cycle into a new smaller package.
  2. Break the cycle with an interface.

The steps to break the cycle with an interface are:

  • Redefine the depended - on classes in one of the packages to implement new interfaces.
  • Define the new interfaces in a new package.
  • Redefine the dependent types to depend on the interfaces in the new package, rather than the original classes.

All rights reserved © 2018 Wisdom IT Services India Pvt. Ltd DMCA.com Protection Status

UML Topics