A blog dedicated to Salesforce Ohana

Implementing Decorator Design Pattern in Apex

This post is part of the series - Design Pattern in Apex

I am sure as a developer, we all faced some situations where we need to have some kind of temporary fields just for calculation or displaying in the UI, but we don't want to store that information in the database or more specific in object. To solve this type of problems, we have Decorator Design Pattern, which allows a user to add a new functionality to an existing object without modifying it's internal structure. 


This pattern create a decorator class which wraps the original class and provides additional functionalities keeping class method signature same.


Where I should use this design pattern?
Below are few user cases, where we can use this design pattern -
  • Say in a table, we are displaying a list of records and want to perform some operations on selected records. We can perform the same operation on each record, but from user interaction point of view, if we can provide some check-boxes so that user can select multiple records inside the table and perform the same operation on all the selected records. We can display check-box against each row, but that check-box information we will not store into the object level, these are only for Visual Force pages.
  • Say when we are creating new accountss we are passing the same account information to some MDM (Master Data Management) system via integration. Once the account information is getting stored into MDM (i.e. we received SUCCESS from MDM), we need to display some information in the account SF page layout indicating that synchronization between SF and MDM is done. In this case, we will just use a text message "Sync Done" / "Sync in progress" to be displayed in Visual Force page, but no information need to be stored into SF.
In the below screenshot, you will find few more use cases from SF documentation.
Implementation -

Problem statement -

Let's say we need to display list of expenses in Visual Force page. All the expenses are stored in an object called "Expenses" where they are stored in $ format. While showing the information in Visual Force, we need to display the amount in INR, EURO, CHF format. 

Below is the object structure -


Let's start with the decorator class -
Apex Class - DecoratorExpense

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public with sharing class DecoratorExpense {
 public List<ConvertedExpenses> allConvertedExpenses{set; get;}
 
 public DecoratorExpense(){
  List<sudipta__Expense__c> allExpenses = [SELECT ID, Name, sudipta__Amount__c FROM sudipta__Expense__c];
  if(allExpenses.size() > 0){
   allConvertedExpenses = new List<ConvertedExpenses>();
   for(sudipta__Expense__c singleExpense: allExpenses){
    allConvertedExpenses.add(new ConvertedExpenses(singleExpense));
   }
  }
 }
 
 public class ConvertedExpenses{
  //TODO - Below conversion rates should come either from custom settings or via integration from websites 
  //like xe.com, but from simplicity purpose, I just made it hard-coded here.
  private Double DOLLAR_INR = 63.7847;
  private Double DOLLAR_EURO = 0.894601;
  private Double DOLLAR_CHF = 0.927985;
  
  public String expenseName {get;set;}
  public Double expenseInDollar {get;set;}
  public Double expenseInInr {get;set;}
  public Double expenseInEuro {get;set;}
  public Double expenseInChf {get;set;}
  
  public ConvertedExpenses(sudipta__Expense__c singleExpense){
   expenseName = singleExpense.Name;
   expenseInDollar = singleExpense.sudipta__Amount__c;
   expenseInInr = expenseInDollar * DOLLAR_INR;
   expenseInEuro = expenseInDollar * DOLLAR_EURO;
   expenseInChf = expenseInDollar * DOLLAR_CHF;
  }
 }
}

The above code shows how the decorator class wraps the sudipta__Expense__c for the extended functionalities. In the object level i.e. sudipta__Expense__c we are not storing the converted expense amounts, rather we are calculating the converted expenses and showing them in the Visual Force page. Below is the Visual Force page.

Visual Force page - ShowAllExpenses


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<apex:page controller="DecoratorExpense">
 <apex:form >
  <apex:pageBlock title="All Expenses">
   <apex:pageBlockTable value="{!allConvertedExpenses}" var="eachConvertedExpenses">
    <apex:column headerValue="Expense Name" value="{!eachConvertedExpenses.expenseName}" />
    <apex:column headerValue="Expense in Dollar" value="{!eachConvertedExpenses.expenseInDollar}"/>
    <apex:column headerValue="Expense in Inr" value="{!eachConvertedExpenses.expenseInInr}"/>
    <apex:column headerValue="Expense in Euro" value="{!eachConvertedExpenses.expenseInEuro}"/>
    <apex:column headerValue="Expense in Chf"  value="{!eachConvertedExpenses.expenseInChf}"/>
   </apex:pageBlockTable>
  </apex:pageBlock>
 </apex:form>
</apex:page>

Below is the result -

To know more about you, I highly recommend you to read this one 
https://developer.salesforce.com/page/Apex_Design_Patterns_-_Decorator_sObject

Please let me know if you have any comments/feedback. Thanks.
Share:

Implementing Strategy Design Pattern in Apex


This post is part of the series - Design Pattern in Apex

The strategy design pattern is the one which allows an algorithm's behavior to be chosen at run time. It is used to define a set of algorithms to solve a common problem. It allows unique logic per algorithm via encapsulations, but ensures that all algorithms are interchangeable at run time. Here the abstraction is achieved by an interface, whereas individual implementations are done at derived classes. So basically it looks like -
Where I should use this design pattern?
This design pattern should be used when you are planning to perform an operation that has a common end goal, but there can be different approaches/ways to achieve that goal. All these approaches can be chosen by client at run-time.

Let me tell you few real-life Salesforce based example where this design pattern can be used -
  • Let's say in the account detail page, you want to display the current temperature of the city where the office located. Now based on the country/state, you may need to collect the temperature information from different websites, but your final goal is always the same i.e. showing the temperature.
  • Let's say you are calculating discounts per product based on month. Every month, the discount amount is getting calculated by different complex algorithms/formulas. Here also, your final goal is same i.e. calculating the discounts.
  • Let's say you want to set contact's preferences based on his/her geography. There can be one algorithm which takes care of all Apac contacts, whereas another one takes care of Europe contacts, etc. So here also you have different algorithms to select the preferences, but at the end, you final goal is same i.e. setting preferences.
Now let's come to the point -
"Open-closed principle" is one of the important strategy of object oriented design. As the below picture tells, in this strategy, developer encapsulate interface details in base class, and bury implementation details in derived classes. Client can couple themselves to an interface. As a result client will never experience any impact due to changes : no impact when the number of derived classes changes, or no impact when implementation of derived class changes.



Components of Strategy Design Pattern -
  • Client - This is the entry point of the strategy pattern.
  • Context - This is the place where decision will be taken at run-time to identify the strategy.
  • Interface Strategy - An interface, which defines a set of methods that will be implemented by the concrete strategy classes.
  • Concrete Strategy - A group of classes that implement the methods defined by the strategy Interface. These classes encapsulate any logic that is unique to that particular concrete strategy.
UML -



Implementation -

Problem statement -
Design a solution to retrieve the current temperature for an account. Based on the geography, temperature information will be collected from different freely available Weather APIs. The design must be expandable for future Weather APIs.

UML -

Description -
  • Weather.cls - Context
  • WeatherService.cls - Interface Strategy
  • WeatherForcastType1 - Concrete Strategy
  • WeatherForcastType2 - Concrete Strategy
Code -

WeatherService.cls - Interface Strategy -
public interface WeatherService {
    Double getTemperatureInCelsius();
    Double getTemperatureInFarhenheit();
}
Now we need to implement the above interface to create concrete classes/strategies.
Below are the concrete strategies -
WeatherForcastType1 - Concrete Strategy
public class WeatherForcastType1 implements WeatherService {
    public Double getTemperatureInCelsius() {
        //Fetch Temperature from Weather API# 1
        return temperature; 
    }
    
    public Double getTemperatureInFarhenheit() {
         //Fetch Temperature from Weather API# 1
         return temperature; 
    }
}

WeatherForcastType2 - Concrete Strategy
public class WeatherForcastType2 implements WeatherService {
    public Double getTemperatureInCelsius() {
        //Fetch Temperature from Weather API# 2
        return temperature; 
    }
    
    public Double getTemperatureInFarhenheit() {
         //Fetch Temperature from Weather API# 2
         return temperature; 
    }
}

Now it's turn for the context class -
Weather.cls -
public class Weather {
    private WeatherService weatherServiceType;
 
    private Set<String> forecastType1Countries = new Set<String>{'United Kingdom','Europe', 'North America', 'South America', 'Switzerland'};
    private Set<String> forecastType2Countries = new Set<String>{'India','Antartica', 'Australia', 'Asia'};
 
    public Weather(String continent) {
 
        if(forecastType1Countries.contains(continent)) {
            weatherServiceType = new WeatherForcastType1();
        } else if (forecastType2Countries.contains(continent)) {
            weatherServiceType = new WeatherForcastType2();
        } 
    }
 
    public Double getTemperatureInCelsius() {
        return weatherServiceType.getTemperatureInCelsius(weatherResponse);
    }
    
    public Double getTemperatureInFarhenheit() {
        return weatherServiceType.getTemperatureInFarhenheit(weatherResponse);
    }
}

Finally, strategies can be executed by client like -
Weather weather = new Weather('India');
Double tempCel = weather.getTemperatureInCelsius();
Double tempFar = weather.getTemperatureInFarhenheit();
or
Weather weather = new Weather('Switzerland');
Double tempCel = weather.getTemperatureInCelsius();
Double tempFar = weather.getTemperatureInFarhenheit();

As you can see in the above example, we can use different weather APIs for WeatherForcastType1  and WeatherForcastType2. But which API is getting used is completely unknown to the client. At the same time, at any point, we can modify any of the concrete classes to change the Weather API, but client will not never notice any impact.

That's the beauty of Strategy Design Pattern. If you have any feedback/comment, please let me know. Thanks.
Share:

How to use Salesforce Describe Methods – Record Types, Fields, and Global Describe

 In this post, I will try to explain how to use Salesforce Describe Methods to fetch record types, fields etc.

Record Type Describe -
If you want to fetch an object's RecordType ID, you don't need to do SOQL operation. There is a method called getRecordTypeInfosByName is there for you. Don't go by the name of the method, as this method will return you the record type id searching by label, not by name. The label is case sensitive. So if the label does not match the exact spelling and case, a null pointer exception will be thrown. So as a developer, you need to add proper error handling mechanism.

When you have more than one record type then you can put the record type information into a map. Below is the code to do that -

sObject Field Describe -
This will return a map of field tokens for an sObject type and then the field describe method can provide a number of useful information about that field. With this, you can make your code flexible to work for any object. Below is the code -

You can refer to the Salesforce Documentation for all the methods . Click Here

Global Describe -
This will return a map of sObject tokens for all sObjects. Below is the method -

Note - Fetch sObject Type from Record Id
The Schema.SObjectType can be retrieved from a Record Id. This is really helpful when you are working with Task or Event. The reason is WhatId field can refer to multiple types of objects. By fetching sObject type from WhatId field, dynamically you can decide your business logic.
Here is the code snippet -



Share:

Implementing Singleton Design Pattern in Apex - Use Case III


This post is part of the series - Design Pattern in Apex

Today in this post I will explain how Singleton Design Pattern can 
be used to call global describe only once.

Requirement -

When someone inserts an account record, you need to inspect all the fields in the account object.

Implementation -
Below is the trigger to start with -
MyAccountTrigger-

AccountHelper -

The problem with this approach is that when someone enters huge number of accounts with dataloader, this code will work like -
For each insert, it will create a new instance of AccountHelper which in turn will execute GlobalDescribe(). Very soon we will be hit by LimitException.

To avoid that, we have to implement Singleton Design Pattern and below are the changes we need to do that -
AccountHelper -

MyAccountTrigger-

Now you can see for a single transaction, we are calling GlobalDescribe only once because we are now not instantiating AccountHelper object for each Account insert, rather we are only instantiating one AccountHelper object per transaction.

Hope you understood the usages of Singleton Design Pattern. If you have implemented this design pattern in any other situation, requesting you to share here. Thanks for your feedback. Thanks.
Share:

Implementing Singleton Design Pattern in Apex - Use Case II


This post is part of the series - Design Pattern in Apex
Today in this post I will explain how Singleton Design Pattern can be used to stop calling the same trigger twice.

Consider the situation - You as a developer, is updating a field in Trigger which in turns calls a workflow and in that workflow action you are again updating some other field from the same object. And to your surprise, the same trigger is getting triggered again. Getting confused, right?

Let's become more specific with the situation.
Consider the below object - Airport__c

The requirements are -
  • Req 1: Send an email if the country and type of an airport changed.
  • Req 2: If the country of an airport changed to "India", change the type to "International". 
To achieve the above two requirements, we have implemented -
  • One trigger, which will send the email if the country and type of an airport changed.
  • One workflow, which will change the type to "International" (Workflow action) if the country of an airport changed to "India".
Here is the trigger -

The trigger looks really simple. But you know what will happen, when you will change the country of an airport to "India", you will get two emails. You know why?

First email you will get from Line#6
After that, workflow action will change the type of the airport to "International". Due to this change you will get another email from Line#11.

To solve this we need to implement Singleton Design Patten as shown below -
StopRecursive

MyAirportTrigger -

With the above approach, as you can see we are checking for boolean value in the trigger(line# 4 & 10). If the value is false, then only we are sending the loop and at the same time changing the value to true. So the next time, in the same transaction, even if the trigger is getting called, it will not do any operation, because we have changed the boolean value to true.

I hope you have understood how singleton design pattern can be used to stop calling same trigger recursively. Please let me know your feedback. Thanks.
Share:

Follow Me

Enter your email address:

Delivered by FeedBurner

Popular Posts

Labels

Salesforce (105) Apex (44) admin (27) ADM (20) visualforce (20) dev 501 (19) integration (18) learn salesforce (18) 501 (16) SOAP (13) lightning (12) tutorial (11) Certification. (9) javascript (8) Trigger (7) test class (7) unit testing (7) Sharing and Visibility (6) design pattern (6) report (6) security (6) trailhead (6) Advanced Admin (5) Certification (5) New Features (5) SOQL (5) css (5) dashboard (5) debug (5) developer (5) formula (5) mobile (5) salesforce release (5) service cloud (5) solution management (5) use case (5) JSON (4) Kitchener Developer Group (4) Lightning Experience (4) WebSphere (4) best practice (4) cast iron (4) component (4) deployment (4) github (4) html (4) polymer (4) profiles (4) responsive (4) tdd (4) ui (4) Advanced Apex (3) Architect (3) Live Chat (3) Performance (3) Products (3) Role (3) Sales Cloud (3) Salesforce DX (3) Scratch Org (3) Study Notes. (3) Summer15 (3) Tips (3) Web Technology (3) dynamic apex (3) event (3) license (3) map (3) mapbox (3) singleton (3) version controlling (3) Bulkify (2) Data Architecture and Management Certification (2) Distributed Version Controlling (2) ES6 (2) Eclipse (2) Einstein (2) Enterprise Territory Management (2) Financial Services Cloud (2) Force.com IDE (2) Governor Limit (2) Groups (2) IBM (2) Implicit Sharing (2) JourneyToCTA (2) Lightning Design System (2) Live Agent (2) Metadata (2) Online Event (2) Opportunity (2) Price Book (2) REST (2) SOSL (2) Sharing (2) Spring 15 (2) Summer17 (2) Territory (2) ant (2) automation tool (2) basic (2) chatter (2) coding (2) communication (2) console (2) controller (2) documentation (2) flow (2) git (2) jquery (2) logging (2) object (2) permission (2) process builder (2) release (2) salesforce1 (2) strategy (2) xml (2) Action Plan (1) Action Plan Template (1) Agent Productivity (1) Analytics (1) Apex Sharing (1) Arrow (1) Asynchronous callout (1) Aura Framework (1) Bots (1) Browser (1) Bulk data load (1) CTA (1) Calendar (1) Canon (1) Case Management (1) Cheat Sheet (1) Classic (1) Community (1) Constructor (1) Contact Center (1) Continuation (1) Continuous Integration (1) Convert (1) Cookie (1) Custom Metadata (1) Custom Object (1) Customer (1) Decorator Design Pattern (1) Dev Hub (1) Devops (1) Diwali (1) Email (1) FSC (1) Function (1) Goals (1) Guide (1) Household (1) Ideas (1) Improvement (1) KPIs (1) Kitchener User Group (1) Large Data Volume (1) LastModifiedDate (1) Lightning Web Component (1) Manual Sharing (1) Metrics (1) New (1) OOPS (1) OWD (1) Omni-Channel (1) Partner (1) Person Account (1) Photo (1) Platform Developer I (1) Presentation (1) Product Schedule (1) Profile (1) Promise (1) Prototype (1) Public Site (1) Query Plan (1) QuickReference (1) Reports (1) Retrieve (1) Role Hierarchy (1) SFDX (1) Salesforce Optimizer (1) Session (1) Sharing Rule (1) Sharing Sets (1) Site (1) Skills (1) Snap-ins (1) Spring 17 (1) Summer14 (1) Summer16 (1) Switch (1) SystemModStamp (1) User License (1) Users (1) Webservice (1) Winter'15 (1) Winter'17 (1) access (1) agile (1) app (1) approval process (1) aura (1) awesome (1) backup (1) bitbucket (1) book (1) campaign (1) change set (1) code (1) code coverage (1) configuration (1) csv (1) custom button (1) custom settings (1) customization (1) data loader (1) database (1) delegate Admin (1) describe (1) dom (1) dreamforce (1) duplicate (1) dynamic (1) equals (1) error (1) field-level security (1) folder (1) ftp (1) generic (1) gift (1) global describe (1) hashcode (1) import wizard (1) jenkins (1) keynote (1) long running requests (1) monitoring (1) mysql (1) page layout (1) personal (1) power of one (1) record type (1) relationship (1) request (1) review (1) sub-tab (1) tab (1) username (1) visual workflow (1) workflow (1)

Total Subscribers

Total Pageviews