For sometime, circa Infinity version 8, Pegaโs wizards in App Studio and Dev Studio have only created Concrete classes, even if it did not have records, it has been a concrete class. With the introduction of Blueprint and the Blueprint Import capability, this practice has continued and we now see this question more and more. Where is the Abstract class? Why is it missing?@Kamil_Janeczek, @BraamSmithCLSA, @PauloTonin and myself have long discussed if this was deserved of its own Constellation 101 - there are a few details out there but this tends to be hard to find, or lost in all the other features and docs.
Hopefully, this article highlights this important concept with our community, and changes in practices when it comes to this new Architecture.
Why?Delivering working software quickly.
Constellation follows a โCenter-outโ approach focused on business outcomes and customer journeys rather than traditional technical components. Concrete classes align better with this philosophy and the Case Designerโs data modeling capabilities.
Abstract classes and Constellation
Abstract classes are not recommended in Constellation, utilising an abstract class will introduce several functional limitations that impact the user experience and data handling capabilities.
โข No search and select support, which restricts data interaction
โข Limited field support โ only query fields work without manual configuration
โข Breaks from Constellationโs design defaults optimized for concrete classes
When is it acceptable?Migrating from Traditional UI
Only as a workaround when migrating an existing Data Model to Constellation. If absolutely necessary, youโll need a multi-stage configuration process including:
Creating the empty abstract class
Configuring it specifically for Constellation
Adding and configuring single-page Data Pages for single-record reference fields
Adding and configuring list Data Pages for list-of-records reference fields
Use concrete classes for Data Objects. This is Constellationโs default design pattern and provides full out-of-the-box support for all data model features.
Thanks Marc Cheong & Team for sharing this best practice. Agree this was/is a debatable decision point when designing data type and nice to see this coming from Pega representatives.
So for constellation applications, we no more talk about Abstract / Concrete data types instead we just see the SOR pattern. Data objects that need to be persisted (define local or external SOR) Vs Data objects that need to be embedded (not persisted, so we mark just define data source later, so technically it uses pr_other table).
One more important thing to clarify on this line is - Even for the traditional UI design from App studio we face a similar situation, why not apply this same best practice for traditional UI as well (food for thought). For time being we can safely say this is applicable only for Constellation applications but still lot of projects do traditional UI design using app studio. Do we need to change the class to abstract in this situation? Hopefully at some point this best practice becomes applicable to Pega platform as whole not just specific UI design system.
Hope the documentations and Pega Academy carefully give verdict for these debates! (I have to update my content as well )
@Premkumar Youโve raised an excellent and insightful point. Thank you for elaborating on it.
You are correct that for quite some time, the wizards in App/Dev Studio has generated concrete classes for data objects, regardless of whether the UI is built using the traditional architecture or Constellation.
Personally, I feel the primary reason this best practice is now explicitly highlighted for Constellation is due to the immediate and tangible impact on the user experience that abstract classes can cause. In a traditional UI architecture, the drawbacks are often less visible to the end-user and are primarily felt by the development team through increased complexity, longer development cycles, and potential refactoring efforts down the line.
Your observation also perfectly aligns with the broader strategic direction of the Pega platform. The emphasis is increasingly on accelerating the delivery of value and working software. We see this in the evolution of features in Constellation, the removal of concepts like temporary cases, and the overall vision for Pega Blueprint and Blueprint-delivered. The goal is to lean into the lowest-code offerings provided by the platform, as these represent the fastest, simplest, and most accessible path to implementation.
This isnโt to say that more advanced implementation patterns are no longer possible or have been deprecated. However, the platformโs โpath of least resistanceโ is intentionally being aligned with best practices to ensure that the default, out-of-the-box approach is also the most efficient and scalable one.
Itโs a great discussion to have, and youโre right to point out the need for this to be a consistent message across the Pega platform and its documentation.
I want to zoom out a bit and look at this topic through a wider industry-adoption lens, comparing how different platforms and programming languages handle similar design trade-offs.
In classical OOP languages like ๐๐ฎ๐๐ฎ and ๐#, ๐ข๐ฃ๐ด๐ต๐ณ๐ข๐ค๐ต classes are a ๐ญ๐ข๐ฏ๐จ๐ถ๐ข๐จ๐ฆ-๐ญ๐ฆ๐ท๐ฆ๐ญ ๐ค๐ฐ๐ฏ๐ด๐ต๐ณ๐ถ๐ค๐ต. The ๐ฐ๐ผ๐บ๐ฝ๐ถ๐น๐ฒ๐ฟ ๐ฝ๐ฟ๐ฒ๐๐ฒ๐ป๐๐ ๐ฑ๐ถ๐ฟ๐ฒ๐ฐ๐ ๐ถ๐ป๐๐๐ฎ๐ป๐๐ถ๐ฎ๐๐ถ๐ผ๐ป ๐ผ๐ณ ๐ฐ๐น๐ฎ๐๐๐ฒ๐ ๐ฑ๐ฒ๐ฐ๐น๐ฎ๐ฟ๐ฒ๐ฑ ๐ฎ๐ ๐ฎ๐ฏ๐๐๐ฟ๐ฎ๐ฐ๐ and enforces implementation of abstract methods in concrete subclasses. ๐ฃ๐๐๐ต๐ผ๐ป supports ๐๐ฃ๐ด๐ต๐ณ๐ข๐ค๐ต ๐๐ข๐ด๐ฆ ๐๐ญ๐ข๐ด๐ด๐ฆ๐ด (๐๐๐๐ด) via the ๐ฎ๐ฏ๐ฐ ๐บ๐ผ๐ฑ๐๐น๐ฒ, but their use is optional. ABCs are enforced at runtime only when explicitly defined and used. ๐๐ฎ๐๐ฎ๐ฆ๐ฐ๐ฟ๐ถ๐ฝ๐ has no native abstract class concept at all. In both Python and JavaScript, abstraction is primarily a design convention, not a structural requirement imposed by the language runtime.
In the earlier days, when Pega was less of a low-code platform, being a Java-built technology, it was naturally influenced by the Java-centric patterns. However, there is an important semantic difference here - In Java, instantiation means creating an ๐ผ๐ฏ๐ท๐ฒ๐ฐ๐ ๐ถ๐ป ๐บ๐ฒ๐บ๐ผ๐ฟ๐. In Pega terms, that is closest to creating a ๐๐น๐ถ๐ฝ๐ฏ๐ผ๐ฎ๐ฟ๐ฑ ๐ฝ๐ฎ๐ด๐ฒ. In Pega, calling a class ๐ฐ๐ผ๐ป๐ฐ๐ฟ๐ฒ๐๐ฒ means something else: that the class is mapped to a physical database table. An abstract class can still have Clipboard pages and participate fully in runtime behavior, but it does not own its own ๐ฝ๐ฒ๐ฟ๐๐ถ๐๐๐ฒ๐ป๐ฐ๐ฒ ๐น๐ฎ๐๐ฒ๐ฟ.
If we look at other low-code platforms: ๐ ๐ฒ๐ป๐ฑ๐ถ๐ supports abstract ๐ฒ๐ป๐๐ถ๐๐ถ๐ฒ๐ that cannot be instantiated directly but can define attributes. ๐๐ฝ๐ฝ๐ถ๐ฎ๐ป has no concept of abstract ๐ฅ๐ฒ๐ฐ๐ผ๐ฟ๐ฑ ๐ง๐๐ฝ๐ฒ๐; all Record Types are concrete. ๐ข๐๐๐ฆ๐๐๐๐ฒ๐บ๐ also has no abstract ๐ฒ๐ป๐๐ถ๐๐ concept, but differentiates between ๐๐ฎ๐๐ฎ๐ฏ๐ฎ๐๐ฒ ๐๐ป๐๐ถ๐๐ถ๐ฒ๐ and ๐ฆ๐๐ฎ๐๐ถ๐ฐ ๐๐ป๐๐ถ๐๐ถ๐ฒ๐ to control mutability rather than existence.
Given that Pega is increasingly maturing as a ๐น๐ผ๐-๐ฐ๐ผ๐ฑ๐ฒ/๐ป๐ผ-๐ฐ๐ผ๐ฑ๐ฒ platform and focusing on a more ๐บ๐ผ๐ฑ๐ฒ๐น-๐ฑ๐ฟ๐ถ๐๐ฒ๐ป development approach, moving away from the abstract/concrete distinction makes sense, in my opinion. That said, I would prefer this configuration to disappear entirely from the rule form - so that there is no lingering ambiguity or confusion for developers.
> So for constellation applications, we no more talk about Abstract / Concrete data types instead we just see the SOR pattern. Data objects that need to be persisted (define local or external SOR) Vs Data objects that need to be embedded (not persisted, so we mark just define data source later, so technically it uses pr_other table).
I think it is even simpler than that. Think of it as โIs my case data composed of any other types of data?โ. My Account Onboarding case needs a Customer, an Address, and a Credit Assessment (among others). Each of these is a data object that needs to be in your applicationโs layer cake.
Where distinct records of the data object exist, the case types that use them add a Data Reference field of that data object.
Where the case holds its own instance of the data object, the case types that need them add an Embedded Data field of that data object.
Both approaches can happily use a data object whose underlying class is Concrete. And, yes, the philosophy fits for Traditional UI applications too.
> For time being we can safely say this is applicable only for Constellation applications but still lot of projects do traditional UI design using app studio. Do we need to change the class to abstract in this situation?
If you have an existing application using a Concrete class for Embedded Data. Leave it. Changing it to Abstract does not unlock any special powers, and in its current form it will play nicer with modern app configuration in App Studio.
@EricSchranz90 The choice of Concrete vs. Abstract is a persistence decision.
The inheritance design of the classes - and resulting architectural benefits that you and @MarcCheong allude to - is independent of the persistence decisions.
A Car can always inherit from a Vehicle.
Instances of a Car can be persisted (Concrete), even if instances of a Vehicle are never to be persisted (Abstract or Concrete).
If you were to build that data model in Infinity today, creating Vehicle as a Concrete class:
If no use case in your application needs to persist an instance of Vehicle, then Vehicle still behaves as Abstract.
With Vehicle defined as Concrete, you can Build for Change more easily when a future need emerges to record instances of Vehicle.
It can be harder to pin down whether certain business objects in enterprise data models will never require distinct records to be saved. Let Infinityโs studios create them as Concrete. If you donโt currently need to save them as distinct records, then thatโs fine.
@SamyaGanguly yes I think that if we had our time again, we at Pega might have chosen different words to differentiate between Abstract and Concrete.
For the purposes of this conversation, the key distinction for our Pega ecosystem on these two terms is:
Abstract: instances in memory cannot be saved to the Infinity database
Concrete: instances in memory may optionally be saved to the Infinity database
As Infinity creates all new data objects as Concrete, every data object in modern Infinity applications has the option to save its instances, without any obligation to.
As we move into delivering applications using Blueprint, this is incredibly powerful. Blueprint will import (contextually correct) sample data for the case types and data objects that you choose build from the Blueprint. The sample data is stored as records in the Infinity database of your application. This helps your stakeholders get immediate visibility of how case types built from the Blueprint use Data References to those data objects, even when the data object eventually gets this data from another system-of-record.
So, I hope that you can see that the choice of Concrete for all data objects is a powerful tool that assists with rapid completion, playback, and business acceptance of user stories.
@EricSchranz90not a simple question, nor a simple answer. In my opinion, the Constellation architecture provides better reusability and implementation across the enterprise, especially approaching it with a modular architecture. Instead of just inheriting a collection of rules, you are now inheriting from and reusing a well-defined business object.
The customer data object, for example, is defined once with all its properties, views, logic, relevant records, and sourcing.
No logic hidden in the UI, to launch clipboard pages or transform data in the UI itself - no broken UI because someone has modified it without realising the true impact of their changes amongst the โspaghettiโ of action sets and sections stacked in the UI. The primary unit of reuse becomes the data object itself, which is easily accessible in Constellation View authoring.โโโโโ
This architecture is the technical embodiment of Pegaโs Center-out business architecture. You define your core business logic and data entities in the โcenter,โ independent of any specific channel (like web, mobile, or back office). This creates a stable, enterprise-wide foundation.
Iโve personally found, this also helps data redundancies by elevating the data object with that single source of truth, mitigating those โmore common than comfortableโ scenarios where we have multiple different definitions for the same data object in the same application.
Is that explicitly all down Abstract vs Concrete? No. However, this answer should be taken in the context of the architecture evolution, simplifying application design and build, all to provide working software quicker.
I would love your opinion. Does the adoption of Concrete data objects as standard impact your implementations?