Monday, March 4, 2024

Salesforce Apex: Composite Pattern

The Composite Pattern is a structural pattern that allows you to compose objects into tree structures to represent part-whole hierarchies. It lets clients treat individual objects and compositions of objects uniformly.

In the context of CPQ, the Composite Pattern can be used to model product bundles, where a bundle can contain individual products or other bundles. This pattern is useful when creating a product hierarchy that includes complex combinations of products and services.

Here is an example illustrating the Composite Pattern in Salesforce Apex:

Step 1: Define a common component interface.

public interface IProductComponent {
    Decimal getPrice();
    String getDescription();
}

Step 2: Create leaf objects that represent individual products.

public class Product implements IProductComponent {
    private Decimal price;
    private String description;

    public Product(Decimal price, String description) {
        this.price = price;
        this.description = description;
    }

    public Decimal getPrice() {
        return this.price;
    }

    public String getDescription() {
        return this.description;
    }
}

Step 3: Create a composite object that can contain other products or product bundles.

public class ProductBundle implements IProductComponent {
    private List<IProductComponent> children = new List<IProductComponent>();
    private String description;

    public ProductBundle(String description) {
        this.description = description;
    }

    public void add(IProductComponent component) {
        children.add(component);
    }

    public void remove(IProductComponent component) {
        children.remove(component);
    }

    public List<IProductComponent> getChildren() {
        return children;
    }

    public Decimal getPrice() {
        Decimal total = 0;
        for (IProductComponent child : children) {
            total += child.getPrice();
        }
        return total;
    }

    public String getDescription() {
        return this.description;
    }
}

Step 4: Use the composite in a CPQ scenario.

ProductBundle mainBundle = new ProductBundle('Main Product Bundle');

// Individual products
Product product1 = new Product(100.00, 'Product 1');
Product product2 = new Product(200.00, 'Product 2');
mainBundle.add(product1);
mainBundle.add(product2);

// Sub-bundle
ProductBundle subBundle = new ProductBundle('Sub Product Bundle');
Product subProduct1 = new Product(50.00, 'Sub Product 1');
Product subProduct2 = new Product(75.00, 'Sub Product 2');
subBundle.add(subProduct1);
subBundle.add(subProduct2);

// Add sub-bundle to the main bundle
mainBundle.add(subBundle);

// Calculating the total price of the main bundle
System.debug(mainBundle.getDescription() + ' Total Price: ' + mainBundle.getPrice());

In the example above, Product represents a leaf node, and ProductBundle represents a composite node that can have child nodes. Both implement the IProductComponent interface, allowing clients to treat individual products and bundles of products uniformly. When calculating the total price of a bundle, the composite iterates over its children and sums the prices, whether they are individual products or nested bundles.

Share This:    Facebook Twitter

0 comments:

Post a Comment

Total Pageviews

My Social Profiles

View Sonal's profile on LinkedIn

Tags

__proto__ $Browser Access Grants Accessor properties Admin Ajax AllowsCallouts Apex Apex Map Apex Sharing AssignmentRuleHeader AsyncApexJob Asynchronous Auth Provider AWS Callbacks Connected app constructor Cookie CPU Time CSP Trusted Sites CSS Custom settings CustomLabels Data properties Database.Batchable Database.BatchableContext Database.query Describe Result Destructuring Dynamic Apex Dynamic SOQL Einstein Analytics enqueueJob Enterprise Territory Management Enumeration escapeSingleQuotes featured Flows geolocation getGlobalDescribe getOrgDefaults() getPicklistValues getRecordTypeId() getRecordTypeInfosByName() getURLParameters Google Maps Governor Limits hasOwnProperty() Heap Heap Size IIFE Immediately Invoked Function Expression Interview questions isCustom() Javascript Javascript Array jsForce Lightning Lightning Components Lightning Events lightning-record-edit-form lightning:combobox lightning:icon lightning:input lightning:select LockerService Lookup LWC Manual Sharing Map Modal Module Pattern Named Credentials NodeJS OAuth Object.freeze() Object.keys() Object.preventExtensions() Object.seal() Organization Wide Defaults Override PDF Reader Performance performance.now() Permission Sets Picklist Platform events Popup Postman Primitive Types Profiles Promise propertyIsEnumerable() prototype Query Selectivity Queueable Record types Reference Types Regex Regular Expressions Relationships Rest API Rest Operator Revealing Module Pattern Role Hierarchy Salesforce Salesforce Security Schema.DescribeFieldResult Schema.DescribeSObjectResult Schema.PicklistEntry Schema.SObjectField Schema.SObjectType Security Service Components Shadow DOM Sharing Sharing Rules Singleton Slots SOAP API SOAP Web Services SOQL SOQL injection Spread Operator Star Rating stripInaccessible svg svgIcon Synchronous this Token Triggers uiObjectInfoApi Upload Files VSCode Web Services XHR
Scroll To Top