Skip Headers
Oracle® Application Development Framework Developer's Guide For Forms/4GL Developers
10g (10.1.3.1.0)

Part Number B25947-01
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Master Index
Master Index
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
View PDF

8.9 Deciding on the Granularity of Application Modules

A common question from developers related to application modules is, "How big should my application module be?" In other words, "Should I build one big application module to contain the entire data model for my enterprise application, or many smaller application modules?" The answer is different for different situations. This section provides some tips about how to answer this question for your own application.

In general, application modules should be as big as necessary to support the specific use case you have in mind for them to accomplish. They can be assembled from finer-grained application module components using a "nesting" feature described below. Since a complex business application is not really a single use case, a complex business application implemented using ADF will typically not be just a single application module.

In the case of a sample like the SRDemo application, there is really only one main use case that it is implementing which allows users to manage service requests. You could argue that the application's functionality of managing technicians skills is a separate "back-end" use case, and you'd be right. However, in practice, modeling the demo that way implied having a second application module with just two view object instances in it, so the SRDemo developers took the liberty of including everything for this small-sized sample application into a single application module for simplicity's sake.

8.9.1 Use Cases Assist in Planning Your Application Modules

In the early analysis phases of application development, often architects and designers use UML use case techniques to iteratively refine a high-level description of the different kinds of end-user functionalities that the system being built will need to support.

Each high-level, end-user use case identified during this design phase typically identifies two kinds of logical outputs:

  • The domain business objects involved

    What core business data is relevant to the use case?

  • The user-oriented view of business data required

    What subset of columns, what filtered set of rows, sorted in what way, grouped in what way, is needed to support the use case?

The identified domain objects involved in the use case help you know which entity objects from your business domain layer will participate in the use case. The user-oriented view of business data required helps developers define the right SQL queries captured as view objects to retrieve the data for the end user in the exactly way that they expect. For best performance, this includes retrieving the minimum required details necessary to support the use case as well. In addition to leveraging view object queries to shape the data, you've learned how to use view links to setup natural master/detail hierarchies in your data model to match exactly the kind of end-user experience you want to offer the user to accomplish the use case.

The application module is the "workunit" container that includes instances of the reusable view objects required for the use case in question, related through metadata to the underlying entity objects in your reusable business domain layer whose information the use case is presenting or modifying.

8.9.2 Application Modules Are Designed to Support Assembly

Use cases map to modular functions. Certain higher-level functions might "reuse" a "subfunction" that is common to several business work flows. Application modules support the ability to create software components that mimic this natural modularity by creating composite application modules that you assemble using instances of other application modules. When you nest an instance of an application module inside another, you aggregate not only the view objects in its data model, but also any custom service methods it defines. While this feature of "nesting" or reusing an instance of one application module inside of another is not typically the focus of simple sample like the SRDemo application, it is one of the most powerful design aspects of the ADF Business Components layer of Oracle ADF for implementing larger-scale, real-world application systems.

Using the basic logic that an application module represents an end-user use case or work flow, you can build application modules that cater to the data required by some shared, modular use case, and then reuse those application modules inside of other more complicated application modules that are designed to support a more complex use case. For example, imagine that after creating application modules SRService and ProductMaintenaceService, you later need to build an application that uses both of these services as an integral part of a new CompositeService. Figure 8-14 illustrates what this CompositeService would look like in a JDeveloper business components diagram. Notice that an application module like CompositeService can contain a combination of view object instances and application module instances.

Figure 8-14 Application Module Instances Can Be Reused to Assemble Composite Services

Image shows application module instances reuse

If you leverage nested application modules in your application, make sure to read Section 10.3.7, "How Nested Application Modules Appear in the Data Control Palette" as well to avoid common pitfalls when performing data binding involving them.

8.9.3 Root Application Modules Versus Nested Application Module Usages

At runtime, your application works with a main — or what's known as a root — application module. Any application module can be used as a root application module, however in practice the application modules that are used as root application modules are the ones that map to a more complex end-user use case, assuming you're not just building a straightforward CRUD application. When a root application module contains other nested application modules, they all participate in the root application module's transaction and share the same database connection and a single set of entity caches. This sharing is handled for you automatically by the root application module and its Transaction object.

At runtime, each top-level application module that your application uses will get an application module pool created for it. More sophisticated customers like Oracle Applications who are building large applications with many, many business functions, often have written custom code to make more efficient use of a "generic" pool of container application modules to avoid ending up with hundreds of different application module pools. Based on the customer workflow that needs to be started, they have written code that takes a generic application module — which is basically an application module with no view object instances of its own or any nested application modules of its own defined at design time — and they programmatically use the createApplicationModule() API on this "generic" application module to dynamically nest an instance of the appropriate "use case"-based application module at runtime. When the user is done, they call remove() on that dynamically nested application module instance, leaving the generic application module "empty" again, ready to be used by another end user for whatever "use case" they need to accomplish.