|Informative Information for the Uninformed|
Once data flow paths have been generalized from the instruction tier through the module tier, it is no longer possible to create additional concrete generalizations for most runtime environments1. Even though it may not be possible to establish concrete generalizations, it is possible to define abstract generalizations. An abstract generalization attempts to show data flow relationships between abstract elements. A good example of an abstract element would be a logical component which is defined in the architecture of a given application. For example, a VPN client application might be composed of a user interface component and a networking component, each of which may consist of multiple concrete modules. By defining logical components and associating concrete modules with each component, it is possible to further generalize information beyond the module tier.
Given the example described above, it may be prudent to define two abstract generalization tiers. The first abstract tier is the component tier. In this context, a component is defined as a logical software component that contains one or more concrete modules. The component tier makes it possible to illustrate data flow between conceptual components within an application as derived from how data flows between concrete modules. The second abstract tier is the application tier. The application tier can be used to illustrate how data is passed between conceptual applications. For example, a web browser application passes data in some form to a web server application, both of which consist of conceptual components which, in turn, consist of concrete modules.
The caveat with abstract generalization tiers is that it must be possible to illustrate data flow between what may otherwise be disjoint concrete elements. The reason for this is that, often times, the paths that data will take between two modules which belong to different logical components will be entirely indirect with respect to one another. For this reason, it is necessary to devise a mechanism to bridge data flow paths between concrete software elements that belong to each logical component or application. A particularly useful example of an approach that can be taken to bridge two distinct components can be found in web services.
In a web services application, it is often common to have a client component and a server component. The two components pass data to one another through an indirect channel, such as through a web request. For this reason, it is not immediately possible to show direct data flow paths from a web client component to a web service component. To solve this problem, one can define a mechanism that bridges the formal parameters associated with the web service method that is being invoked. In this manner, the the formal input parameters for a web service method found on the client side can be implicitly linked and shown to define the formal input parameters received on the web service side. By illustrating data flow at a concrete tier, it is possible to generalize data flow behaviors all the way up through the abstract tiers.
The benefit of describing data flow behavior at abstract tiers is that it makes it possible to derive data flow behaviors between abstract software elements rather than strictly focusing on concrete software elements. This is useful when attempting to view an application's behavior at a glance rather than worrying about the specific details relating to how data is passed. For example, this could be used to help validate threat models which describe how data is expected to be passed between abstract components within an application.
When generalizing information at abstract tiers, the only information that can be conveyed, at least based on the approach described thus far, is whether or not a component or application are passing data through a formal input or formal output parameter. The specifics of which formal parameters are passed is no longer available for use in generalization. Using the example shown at the data type tier, one might assume the following component associations: Company.dll and Person.dll, which contain the Company data type and Person data type, are part of the user interface component of a human resources application. The classes used from system libraries can be generically grouped as belonging to an external library component. Using these, groupings, the component data flow paths may be represented as shown in figure 11.
As with all previously described generalization tiers, a single component data flow path may represent multiple module data flow paths. The single component data flow path should be associated with each corresponding module data flow path through a one-to-many link table in a normalized database.