Bridging data classes that have different "package" names
The 7.3 LSA course strongly advises to add properties to Foundation application-supplied Data classes as-is, not wrap them or extend them per highlighted note below:
Note: It is not a best practice to use a custom data model or wrap the foundation data model. The best practice is to leverage the foundation data model and embellish it as needed.
Suppose a customer-developed class has (A) already been used in multiple applications and (B) contains basically the same type of information as a foundation data class such as details about a work party. What then?
Had the foundation application come first, a class such as PegaFS-Data-Party-<Org>-<App> could be defined, where: <Org> represents enterprise-wide extension and <App> represents application-specific extension beyond that. Note how this data class’s name makes it obvious to developers that it stems from a Pega Foundation-defined class.
This is similar to what you would do in java where a class name is formed using: <package name> + “.” + <object name>. It is generally considered poor practice for a class in one package to directly extend a class in a different package. Doing so makes it appear that the second package has “co-opted” the first package. In Pega you can use pattern inheritance to acknowledge the extending class’s origin while not having to separately declare a package name.
Back to question regarding how to deal with classes that do not share the same root / prefix / stem. Unlike java, Pega does not support Interfaces. Imagine being able to comma-delimit class names in a rule’s Pages & Classes. This would result in confusion. If the same-named rule were applied to two classes that have different roots, which should be used?
Changing a step page's pxObjClass at run-time to something that is not in the inheritance path of what is declared in Pages & Classes for that page’s name is far too risky, What you can do instead is call two separate rules using the same step page, the class of another page being “cast” by supplying a Page Name parameter. For example, in the first rule that is called Param.CustomerParty = Org-Data-Customer, in the second rule that is called Param.CustomerParty = PegaFS-Data-Party.
Feel free to comment if agree, disagree, and/or have something to add.
A Bridge Data class can easily be defined starting with a Pega Foundation Data class:
Extend the Pega Foundation Data class using pattern inheritance
Directly inherit the legacy Data class
Once you define this class you do not need to invoke two rules in back-to-back, one rule that “casts” a page to the Pega Foundation Data class, a second rule that “casts” a page to the legacy Data class. Instead you declare the “applies-to” class of an embedded page as the class constructed in (1) above.
Rule Resolution will initially traverse the class in (1) above right to left. When RR reaches the root, it jumps to the legacy Data class in (2) and once again traverses right to left.
Suppose an additional third class that begins with <Org>, <Org>-<Div>, or <Org>-<Div>-<App> is defined, that class directly extending a pattern-inheritance extension of the legacy Data class, that class directly extending a Pega Foundation Data class. Doing so “buries” the Pega Foundation class beneath two levels of non-Foundation classes -- the exact opposite of what is recommended in the 7.3 LSA course.
It is highly unlikely that rules would ever be defined with <Org>, <Org><App>, <Org>-<Div>, or <Org>-<Div>-<App> as the “applies-to” class. Defining a property at the <Org> level would only make sense if multiple Orgs had to be accommodated by applications, each Org having Org-unique properties.
The aforementioned <Org>-<Div>-<App> classes are primarily used as the points from which Work/Data/Int classes are branched. If a property is generic to any case, Work- or Work-Cover- can be used the “applies-to” class. Similarly, if a property is generic to any Data class, Data- can be used as the “applies-to” class.
My apologies for not providing an illustration to accompany this discussion.
Background: Suppose a very useful Contact Data class exists but was associated to ORG2, i.e., ORG2-Data-Contact. The current application, which uses ORG1-DIV-APP as its prefix, wants to incorporate this Data class. The ORG1-DIV-APP development also wants to leverage the PegaData-Contact class that is defined in the Pega-SharedData ruleset. Currently there is no such thing as an ORG1-DIV-APP-Data-Contact class.
One solution is to go ahead and create the ORG1-DIV-APP-Data-Contact class then define the direct inheritance hierarchy as shown below:
An alternative solution is:
The only difference is that PegaData-Contact would take precedence over ORG2-Data-Contact should similarly named Properties and Sections exist.
If so, an overridden ORG2-Data-Contact Section, say, could be copied to PegaData-Contact-ORG1-DIV-APP. Thoughts?