Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Designing context-dependent classes as top-level nested classes (nested classes, for short) enclosed by the context-serving class makes this dependency clearer. Furthermore, the use of nested classes makes the collaboration easier to recognize, avoids namespace pollution, and reduces the number of source files.
(The complete source code for this tip can be downloaded in zip format from the Resources section.)
Nested classes are simply static inner classes. The difference between nested classes and inner classes is the same as the difference between static and nonstatic members of a class: nested classes are associated with the enclosing class itself, whereas inner classes are associated with an object of the enclosing class.
Because of this, inner class objects require an object of the enclosing class, while nested class objects do not. Nested classes, therefore, behave just like top-level classes, using the enclosing class to provide a package-like organization. In addition, nested classes have access to all members of the enclosing class.
Consider a typical Java subsystem, for example a Swing component, using the Model-View-Controller (MVC) design pattern. Event objects encapsulate change notifications from the model. Views register interest in various events by adding listeners to the underlying model of the component. The model notifies its viewers of changes in its own state by delivering these event objects to its registered listeners. Often, these listener and event types are specific to the model type, and therefore make sense only in the context of the model type. Because each of these listener and event types must be publicly accessible, each must be in its own source file. In this situation, unless some coding convention is used, the coupling between these types is difficult to recognize. Of course, one may use a separate package for each group to show the coupling, but this results in a large number of packages.
If we implement listener and event types as nested types of the model interface, we make the coupling obvious. We can use
any access modifier desired with these nested types, including public. In addition, as nested types use the enclosing interface
as a namespace, the rest of the system refers to them as
<Enclosing>.<Nested>, avoiding namespace pollution inside that package. The source file for the model interface has all the supporting types,
which makes development and maintenance easier.
As an example, we develop a simple component,
Slate, whose task is to draw shapes. Just like Swing components, we use the MVC design pattern. The model,
SlateModel, serves as a repository for shapes.
SlateModelListeners subscribe to the changes in the model. The model notifies its listeners by sending events of type
SlateModelEvent. In this example, we need three source files, one for each class:
/after, corresponding to the nonnested and nested examples provided above