So far two layers were used the way they were deployed with PFC. The next logical step is to add another layer. This can be accomplished by adding an additional layer between PFC and PFE. The new layer (PFD) is inserted by changing the inheritance structure of the PFE layer. Datawindow services are utilized as an example to demonstrate this technique. Figure 12 shows the datawindow services relationship in a two layer approach, before the additional layer is added. The base service object n_cst_dwsrv is inherited from its PFC counterpart pfc_n_cst_dwsrv.

Figure 12 - Two Layer Relationship
After an additional layer is inserted between PFC and PFE the datawindow service relationship is changed. The new relationship is shown in figure 13 below.

Figure 13 - Three Layer Relationship
A new object pfd_n_cst_dwsrv is inherited from pfc_n_cst_dwsrv. N_cst_dwsrv is changed to inherit from pfd_n_cst_dwsrv. This can be accomplished by saving the old n_cst_dwsrv as pfd_n_cst_dwsrv, then deleting the existing n_cst_dwsrv and creating a new one by inheriting from the from pfd_n_cst_dwsrv. If the existing n_cst_dwsrv already contains some code its ancestry can be modified by exporting the object, replacing all the references to its ancestor, and importing it back. The same process is then repeated for every object. The process sounds a lot more intimidating than it actually is. The three layered extension PBLs took an hour to generate. A tedious one, but nonetheless only an hour.
Three Layer Approach (PFC, Framework and Application Layer)
Using a three layer approach there is room for a framework in the additional middle layer, leaving PFE to be used for application specific code.

Figure 14 - Three Layer Approach
Advantages
Flexibility.
PFE layer is available for the application specific code. The application objects can be extended by insertion, inheritance or delegation. In the previous example of the u_dw popup menu and the status bar service the application specific code may be placed directly in the u_dws pfc_prermbmenu and pfc_statusbarclicked of the n_cst_winsrv_statusbar.
Allows further extension by insertion.
In contrast to the last approach this time PFE layer is left empty. The users of the framework have an option of adding yet another layer between PFD and PFE. The change of inheritance is easier because PFE is empty. The objects in PFE may be overwritten without the fear of losing any code.
Third party utility friendly.
When the PFC library is extended by insertion all the objects in PFE layer include the new functionality. Any template or code generated by a third party application will reference the objects in PFE layer and therefore will automatically include the new functionality.
Limitations
Requires maintaining a separate copy of PFE and PFC
pbls for each project.
The above is true anytime PFE layer contains application specific code. Consider the relationship between the pfc_u_dw, u_dw, n_tr, and pfc_n_tr. Figure 15 demonstrates what happens when two applications share the same PFC pbls. In the first application the transaction object was extended. An instance variable and a function were added.

Figure 15 - Shared library limitation.
When the first application is regenerated the definition of n_tr is memorized and the pfc_u_dw object becomes aware of a new instance variable and a function. AS shown in Figure 16, when the second application is regenerated its n_tr definition replaces the first.

Figure 16 - Shared library limitation.
If the first application is regenerated the second will not run successfully because of the n_tr definition mismatch. This may result in a "GPF tug of war" - when the first application is rebuild the second breaks and vice versa.
The same issue applies for the objects related by inheritance. For example when adding a function to n_cst_dwsrv, in the PFE layer the definition of all descendant datawindow services will include the new function. As a result the definitions of both PFC and PFE objects have been indirectly modified.
Introduces additional inheritance levels and larger
number of pbls and objects.
The performance degradation due to the number of inheritance levels is in Powerbuilder 5.0 is insignificant. However the greater number of pbls and objects may affect the performance in development mode. This is because a lot of optimization performed in the compiled application cannot be done in development mode. As a result this approach may cause a performance hit in development mode. Note, the performance hit in the executable due to an additional layer is negligible.
Change is a fact of life. Immediately after the framework is deployed you will receive bug reports and enhancement requests. Typically these will come from a project team early in the development cycle. Meantime, another team may be closer to their deployment date. They have worked very hard to get to this point and have spent endless days testing every application feature. The mere mention of change is sure to get you off their Christmas list. The only way to allow each team to have control over their own destiny is to implement version control. The changes between each versions should be documented and each team may pick a time most appropriate for them to migrate to the next version. Support of the multiple version is more complex so you may want to limit the support to the last two or three versions and make the migration mandatory for all others. Some of the extension method decisions will directly affect the ability to effectively maintain the framework and each application.
When creating a middle layer there is another issue that should be resolved. There are two possible choices. An interim layer object may be inserted between every PFC and PFE object or only between the ones that were modified. This approach is demonstrated in Figure 17 below.

Figure 17 - Partial Layer Approach.
The framework only contains functionality for the sort and find datawindow services. Everywhere else the original object relationship was preserved.
Utilizing the latter approach the framework objects may be added as required when new functionality is added. The second approach is acceptable for a single team framework, but it introduces extra maintenance problems for multiple project environments. When a new object is added to the framework, every application will have to change the inheritance structure to point to the new object instead of PFC. The complexity is multiplied by the number of applications currently in development or production. An inheritance adjuster utility may simplify this task, but may be still too intrusive to be considered viable. Consider asking every project team to change their application inheritance structure with each framework release. Generating a middle layer object for every PFC object regardless of changes made will simplify maintenance down the line.
Article based on the material from "PowerBuilder Foundation Class Library Professional
Reference", McGraw Hill, ISBN
0-07-913267-7.
Last revised: February 15, 2004 03:58 AM.