LET'S LEARN TOGETHER. THE BEAUTIFUL THING ABOUT LEARNING IS NOBODY CAN TAKE IT AWAY FROM YOU.

Another Powerful Trailhead module - Event Monitoring



Salesforce introduces Trailhead – a fun way to learn Salesforce. It doesn’t matter whether you are Salesforce Admin or Salesforce developer, there are bunch of modules available for your based on your career path. The more modules you complete, you will get more badges and those badges will be attached to your profile. So you can see yourself going stronger and stronger day by day. That is the primary goal of using Salesforce Trailhead – Make yourselves a better Salesforce Admin or a better Salesforce Developer.

To achieve your goal, Salesforce Trailhead team recently introduces three new admin modules –
Out of these above three modules, the module which really looks very interesting to me is the Event Monitoring module. I immediately jumped into it and completed the same. Once completed, I have realized the power of event monitoring. Monitoring event is so important to a Salesforce Admin. In my daily day to day to work, I normally receive so many requests which now I can answer quickly with the help of event monitoring.

Let me tell you what makes this module so interesting.

This module consists of three sub modules as shown below –



The first sub-module - Get Started with Event Monitoring –
This sub-module explains the basic like what is event monitoring, what are different types of events present, use cases where event monitoring should be used. But the key part of this sub-module is: the API first approach. This event monitoring is an API only feature. You will not get this feature inside setup area. It explains in which object event logs are stored and how you can retrieve the same.

Like any other modules in Trailhead, this module is also having an area – which I normally call – “Judge yourself”. You have to answer few multiple choice questions and if successful you will get 100 points.

Once I have completed this sub-module and earned my 100 points, it inspired me even more to go to the next sub-module Query Event Log Files

The second sub-module - Query Event Log Files –
This module is one for which I was waiting – how to query event log files. This module will explain what is API first approach. This module also explains how we can query an EventLogFile object using SOQL and REST explorer. Another important part of this sub-module is that it compares SOAP and REST APIs for querying event log files.

This sub-module also comes with multiple choice questions, but the questions are getting harder here. So you need to read the questions and answers very carefully to choose the right answer. At the end of this, you be awarded with 100 points.

The final sub-module - Download and Visualize Event Log Files   -
This module is having many information, so completing this module is not possible in 15 mins. At least it took 45 mins for me to complete this sub-module. This module describes the structure of the downloaded event log files, how to read the downloaded file. As downloaded event log file can have many information which may be you are not interested, so this sub-module will explain how to extract only the important information from downloaded log file. This sub-module comes with multiple choice questions (mainly programmatic questions) and same like other sub-modules, here also you will be awarded 100 point upon completion.

Finally – I received the badge on my profile. I would request all to complete this module and make yourself a better admin/developer. 


Share:

Book Review - “Salesforce Reporting and Dashboards” by Johan Yu


Recently I was reading the book – “Salesforce Reporting and Dashboards” by Johan Yu. 

Johan is a very familiar face within Salesforce community.
You can always reach Johan @simplysfdc, Linkedin and last but not the least his blog SimpleSFDC. I am a big fan of his blog.

The book - “Salesforce Reporting and Dashboards” contains a good selection of guides for solving reporting requirements. It started very well, I mean starting from very basic and then slowly moving towards more and more complex reporting requirements. When I started reading this book, I thought what makes this book different from Salesforce’s Trailhead session on reporting - Reports & Dashboards. And here is what I feel. When Trailhead session is good to make you comfortable with Salesforce’s Reporting concept, but still there are so many complex scenarios which you need to handle in your day to day work. And this book is definitely an answer to those complex scenarios. This book will make sure that you can call yourself a “Reporting and Dashboard Expert” once you have gone through the entire book. Yes you hear it correctly – It’s “Reporting and Dashboard Expert”.

I have experienced some difficulties during my career as Salesforce Administrator/Developer to provide solutions to some of my client’s reporting requirements. So when I was going through this book, I realized this book contains some effective remedies to many common problems. The solutions are provided in a very straightforward way – no unnecessary waffle – just straight to the point and explaining step by step how to implement the solution.

I personally love few sections from this book. Like
  • Hands-on – subscribing to a report – This really explains how to subscribe to a report and see the subscription in Salesforce1. Integration Salesforce1 in the hands-on is really a plus point to me.
  • Chapter 5 – Learning Advanced Report Configuration – This chapter is the jewel. Many important  configurations like bucket field, formula field, Grouping, Scheduling report etc. are explained here in a very simple way. To me this chapter is the one I need to refer again and again.
  • Chapter 8 - Accessing Historical Data – This is also a very important chapter. Accessing historical data over report is a very common requirements, but to implement the solution, one should have a very clear understanding on how it should be done, what can be done and what cannot be done. This chapter is a one stop shop for all these answers.
  • And finally Chapter 9 – Dashboard and Reports in Salesforce1 – Believe me this chapter is the differentiator. This chapter explains the concept and most important the limitations of Salesforce1 app. Understanding limitation is very important in the context of Salesforce and it will make the design more concrete.
In summary, if you are a Salesforce Admin looking to explore some of the advances concepts of Salesforce Reporting and Dashboard, then “Salesforce Reporting and Dashboards” is a must have. I am now encouraging all of my admin colleagues to read this book and challenge their solutions – because I believe by challenging ourselves, our best will come out.

You can buy this book from Amazon, PACKTPUB.


Share:

INTEGRATE MAPBOX WITH VISUALFORCE TO CREATE BEAUTIFUL MAP - Part III

In continuation with my previous two posts -
today, I will explain how you can fetch geographic data from Salesforce and accordingly show them in Salesforce.

To start with let me first create an object - Household where I can store geographic information. Below you can find the object details - 
Now the Visualforce page - Mapbox Click here

Now when you will open the page you will see the three locations plotted.

In this example, I am using apex:repeat to prepare the GeoJSON data. To understand what is GeoJSON data, below is what Wikipedia stating -

Once the GeoJSON data is ready, I am adding the same with featurelayer -

L.mapbox.featureLayer(geojson).addTo(map);

Finally, I am using the click event to show the Household name when user clicks on the points inside map. The code for that - 

//Show popup with information on mouse click
myLayer.on('click',function(e){
     e.layer.openPopup();
}); 

In my next post, I will explain how you can draw geographic areas inside map using Mapbox. Please provide your feedback. Thanks.
Share:

INTEGRATE MAPBOX WITH VISUALFORCE TO CREATE BEAUTIFUL MAP - Part II

In continuation to my previous post - INTEGRATE MAPBOX WITH VISUALFORCE TO CREATE BEAUTIFUL MAP - Part I, today, I will play with few attributes from Mapbox to make the map more interactive.

Below are the things I will do -
  • I will add different layers and explain how to toggle between layers.
  • I will add scale control
  • I will add attribution control
  • I will set the location in the map
To understand what is layer and how Mapbox works, I would request you to go through the official Mapbox tutorial @ https://www.mapbox.com/guides/how-mapbox-works/. Since from this post, we will go into deep with Mapbox, so it is better to have your basic clear in terms of how Mapbox works and what are the terminologies they use.

Let's go directly to the Visualforce Page Mapbox_2 click here

Now if you open the Visualforce page, you will see - 
Clicking on Layer icon, you will see -
Choosing Sudipta First Map, you will see different map like -

Cool!!. There are many more attributes available which you can check from Mapbox Developer resource @ https://www.mapbox.com/mapbox.js/api/v2.2.1/

In my next post, I will explain how you can retrieve geographical data from Salesforce object and show them in map with Mapbox API. Sounds interesting, right!! I am working on this now, very soon I will share the information with you all.

Till then, if you have any feedback, please share with me. Thanks.
Share:

INTEGRATE MAPBOX WITH VISUALFORCE TO CREATE BEAUTIFUL MAP - Part I

Maps are very powerful application to visualise information. In today's world, map plays a very important role as many customers want to integrate maps with their applications to represent their account, contact, lead and many more information visually through map.

In one of my recent project, I came across a similar requirement where I need to integrate map with Visualforce to show lead information visually in map. To implement this requirement, I have chosen Mapbox. I know you have the question in mind - Why Mapbox, why not Google Map? The reason why I have chosen Mapbox, not the Google Map - I will come to it later. But for the time being let's keep our focus completely on Mapbox.

In this post, I will explain how you can integrate Mapbox with Visualforce page. I will start with a very basic example and then dig into more and more complex ones. I believe in this way, you will also feel more comfortable with Mapbox+Visualforce integration.

Note - The day I am writing this post, the version of Mapbox API is: Version 2.2.1.

Step 1 - Create Mapbox account
First you need to create a Mapbox account. You can do that by clicking on Signup button.

Step 2 - Get Default Public Token 
Once you have logged in, go to your profile, followed by click on Apps to get your default public token. Below is the screenshot -

Step 3 - Create your first project
You can create your first project by clicking on the project icon at the top. Once the project is created you will get the project id.

With the above three steps, our Mapbox configuration is completed. Let's move into our first basic example -

Example - Display Mapbox With Visualforce Page -

Below is the Mapbox_1 Visualforce page. Click here

Now when you will open this page, you will see the map like below -

In my next post, I will play with few attributes to make the map more interactive. Till then, if you have any feedback or specific requirement, I will really appreciate if you can post it to me. Thanks.

Share:

APEX TRIGGER DESIGN PATTERN

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

I know it was discussed number of times earlier about Apex Trigger Design Pattern. Below are few excellent posts -
I have learned a lot from the above two posts by Steve Andersen and Mike Leach.
But the post by Abhinav Gupta really inspires me a lot and I am going to explain the pattern/template here with few use cases.

The motivations for this design pattern are -
  • Write Trigger with minimum code
  • Follow Salesforce Best Practice - One Trigger per object
  • Follow another Salesforce Best Practice - Move all code from Trigger to Apex Classes - Handler Classes
  • Ability to add and order multiple handlers for the same trigger event.
  • Easy to maintain code base.
Here is the Apex Trigger template - MyTriggers (Again inspired by Abhinav Gupta)
Now using the above template, below is the account trigger handler - AccountTriggerHandler

And finally the trigger - AccountTrigger

Now the trigger code is very neat and clean. At the same time all our operations against trigger events are moved to handler class.

So now let's consider few use cases -
Use Case 1 -
While inserting new accounts, if the Account Rating is marked as 'Hot', then mark those accounts as Active and make the Customer Priority as 'Medium'.
Implementation -
To implement the above requirement, what we need to do is simply add the functionality in AccountTriggerHandler.AccountBeforeInsertHandler class. No changes in Apex trigger code is required.
Here is the updated AccountTriggerHandler

Use Case 2 -
While updating accounts, if Account Name changed, find how many account name changed and print the count.
Implementation -
To implement the above requirement, what we need to do is simply add the functionality in AccountTriggerHandler.AccountBeforeUpdateHandler class. You can do the same in AfterUpdate also. :-)
Here is the updated AccountTriggerHandler

Please provide your feedback. Thanks.
Share:

HOW TO PASS PARAMETERS BETWEEN TWO VISUALFORCE PAGES HAVING SAME CONTROLLER

Let me discuss about another use case where it is required to pass information from one VisualForce page to another VisualForce page while both the VisualForce pages are sharing the same controller. I know this is a very basic example, but I would like to include this use case as part of my previous post - HOW TO PASS PARAMETERS TO VISUALFORCE PAGES AND BETWEEN PAGES. Special thanks to Joseph McNulty for pointing this to me.

To start with let us first create the common controller – SingleController


Here is the first VisualForce Page – FirstPage.


Here is the second VisualForce Page – SecondPage.


As you can see from FirstPage, I am setting the name to the controller variable - name and then clicking on the commandButton,  goToSecondPage() method from controller is getting called. This goToSecondPage() method is returning a PageReference to the SecondPage. The point to notice here is that inside the method goToSecondPage(), I am making the setRedirect(false). I will explain what will happen if I set it to true later in this post. So what is happening after clicking on the button is that a SecondPage is getting displayed with Welcome message. But another interesting thing to notice here is that URL is not getting changed i.e. URL is still pointing to /apex/FirstPage though the content is from SecondPage.

So before going further inside, I hope you now know how you can pass information from one VisualForce page to another where both the pages are having common controller.

Now the interesting part –
With setRedirect(false) – redirect is happening through a server side redirect and the URL is not getting changed. In our case, since the target page is using the same controller that is why the view state is preserved. As a result, in the new page i.e. SecondPage; you can see the name after Welcome message.
But with setRedirect(true) - redirect is happening through a client side redirect and the URL is getting changed. View state is also not preserved and you will not see the name after Welcome message.

I am thinking of a more detailed post on setRedirect method. It may look very simple, but it is basically doing many interesting stuffs at the back stage. As a developer, we should understand this method very clearly.
If you have any feedback, please pass it to me. I really appreciate it. Thanks.

Share:

HOW TO PASS PARAMETERS TO VISUALFORCE PAGES AND BETWEEN PAGES


I am sure we all came to different situations where we need to pass parameters to VisualForce pages while doing Salesforce development. So I thought of putting all scenarios together in a single post with the solution approach. So without any further introduction, let's get into the actual agenda quickly.

First let me explain the basic -

WHAT IS A PARAMETER ?
A parameter is a name-value pair which is embedded at the end of the url of a page. The first parameter always starts with '?' and all the subsequent parameters start with a '&'.
Let's take the below example -

http://sudipta-deb.blogspot.in/?firstname=Sudipta&lastname=Deb
  • The first parameter is firstname=Sudipta where name is firstname and value is Sudipta
  • The second parameter is lastname=Deb where name is lastname and value is Deb
With the basic explained, let me start with different scenarios and solution approach

SCENARIO 1 - PASSING PARAMETER FROM CUSTOM BUTTON
Sometimes it may be required that by clicking on custom button we need to open a new VisualForce page and pass parameters to that new page. For example - if we create a custom button for Account object, while configuring if we choose VisualForce page we can select only those VisualForce pages having standardController="Account" set. To overcome this, we need to choose Content Source as url while configuring Custom Button. Screenshot is given below -
Below is the VisualForce Page - showAccountName

SCENARIO 2 -PASSING PARAMETERS THROUGH COMMAND LINK OR COMMAND BUTTON
In order to pass parameters from one VisualForce page to another one, we can use command link or command button. Let's start with an example where clicking on command link a new VisualForce Page will be displayed along with the message passed from the previous page.

First create a simple VisualForce Page - FirstPage

As you can see in this page, I have used a command link which is passing a parameter with key value pair as firstName=Sudipta to a new Page - SecondPage

So now create the second VisualForce Page - SecondPage


As you can see that SecondPage needs a controller - SecondPageController. This controller will capture the parameter passed to it and set it to a variable.
Here comes the controller - SecondPageController


In this controller, the below line is important which is used to capture the message passed from FirstPage -
firstName = System.currentPageReference().getParameters().get('firstName');

With this approach, we need to keep in mind few things -

  1. All the parameters we are passing this way will be displayed in the page url. So if you are thinking of passing some confidential information, better not to do that. Otherwise you confidential stuffs will become public properties. :-(
  2. If you want to pass something having special character like accountName as "Batman & Superman", it will create problem. So it is always better to pass Salesforce ID or something unique identification field.
Please pass your comments. Thanks.
Share:

DYNAMIC VISUALFORCE BINDINGS

Today in this post, I will explain about "Dynamic VisualForce Bindings". This was introduced in Spring'11 release and it allows developer to choose the list of fields to be displayed at run time, rather than at compile time. As a result, developer can write generic VisualForce pages which will display information about records without necessarily knowing the list of fields.

Dynamic VisualForce Binding is supported for both standard and custom objects. The general form is
reference[expression]
where -
  • reference - It can be either an sObject, or an Apex Class, or a global variable.
  • expression - It evaluates to a String that is the name of a field, or a related object. In case of related object, it can be used recursively to select another related object or field.
Important point - Dynamic VisualForce Page should always use a standard controller for the object and then implement any further customization through controller extensions.

The below example will show how dynamic visualforce binding can be implemented to display list of fields from Account object at run time.

Controller - ShowDynamicAccountFieldController

 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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public with sharing class ShowDynamicAccountFieldController {
 public ShowDynamicAccountFieldController(ApexPages.StandardController controller){
  controller.addFields(dynamicFields);
  Account acc = (Account) controller.getRecord();
 }
 
 public List<String> dynamicFields{
  get{
   if(dynamicFields == null){
    dynamicFields = new List<String>();
    dynamicFields.add('Name');
    dynamicFields.add('AccountSource');
    dynamicFields.add('NumberOfEmployees');
    dynamicFields.add('Rating');
   }
   return dynamicFields;
  }
  private set;
 }
 
 public void showFirstSet(){
  checkAndInitiate();
  dynamicFields.clear();
  dynamicFields.add('Name');
  dynamicFields.add('AccountSource');
 }
 
 public void showSecondSet(){
  checkAndInitiate();
  dynamicFields.clear();
  dynamicFields.add('Name');
  dynamicFields.add('Rating');
 }
 
 public void doReset(){
  checkAndInitiate();
  dynamicFields.clear();
  dynamicFields.add('Name');
  dynamicFields.add('AccountSource');
  dynamicFields.add('NumberOfEmployees');
  dynamicFields.add('Rating');
 }
 
 private void checkAndInitiate(){
  if(dynamicFields == null){
   dynamicFields = new List<String>();
  }
 }
}

VisualForce Page - ShowDynamicAccountFieldPage

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<apex:page standardController="Account" extensions="ShowDynamicAccountFieldController">
 <apex:form >
  <apex:pageBlock title="Control Room">
   <apex:pageBlockSection columns="3">
    <apex:commandButton action="{!showFirstSet}" value="First Button" id="firstButton"/>
    <apex:commandButton action="{!showSecondSet}" value="Second Button" id="secondButton"/>
    <apex:commandButton action="{!doReset}" value="Reset" id="resetButton"/>
   </apex:pageBlockSection>
  </apex:pageBlock>
  <apex:pageBlock title="Display Account" mode="edit">
   <apex:pageBlockSection columns="2">
    <apex:repeat value="{!dynamicFields}" var="f">
     <apex:outputField value="{!Account[f]}"/>
    </apex:repeat>
   </apex:pageBlockSection>
  </apex:pageBlock>
 </apex:form>
</apex:page>

Let me explain what is happening here -

  • Controller "ShowDynamicAccountFieldController" creates a list of strings where each string maps to a field from the Account standard object.
  • The visualforce page uses an tag to loop through the strings.
  • Clicking on "First Button", method showFirstSet() is getting called which will select the list of account fields at run-time and the same set of fields are getting displayed in the visualforce page.
  • Clicking on "Second Button", method showSecondSet() is getting called which will select the list of account fields at run-time and the same set of fields are getting displayed in the visualforce page.
  • Clicking on "Reset", method doReset() is getting called which will select the list of account fields at run-time and the same set of fields are getting displayed in the visualforce page.
Below are screenshots of the Visualforce page -

Initial Load of the page -


After clicking on "First Button" -














After clicking on "Second Button" -

















After clicking on "Reset" button -














As you can see the list of fields are getting decided at run time, so this feature - Dynamic VisualForce Bindings is very powerful. 

I will write few more examples in my up coming posts to explain more about it's features. Till then enjoy learning. Please provide your comments below. Thanks.
Share:

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:

Follow Me

Enter your email address:

Delivered by FeedBurner

Labels

Salesforce (105) Apex (47) admin (27) visualforce (21) ADM (20) dev 501 (19) integration (18) learn salesforce (18) 501 (16) lightning (15) SOAP (13) javascript (13) tutorial (11) Certification. (10) Kitchener Developer Group (8) Certification (7) Trigger (7) security (7) test class (7) unit testing (7) Advanced Admin (6) Advanced Apex (6) Sharing and Visibility (6) design pattern (6) developer (6) report (6) salesforce release (6) service cloud (6) trailhead (6) Lightning Experience (5) New Features (5) SOQL (5) css (5) dashboard (5) debug (5) formula (5) mobile (5) solution management (5) use case (5) JSON (4) Kitchener User Group (4) Lightning Web Component (4) Sales Cloud (4) Salesforce DX (4) Tips (4) WebSphere (4) best practice (4) cast iron (4) component (4) deployment (4) event (4) github (4) html (4) polymer (4) profiles (4) responsive (4) tdd (4) ui (4) Architect (3) Live Chat (3) Online Event (3) Opportunity (3) Performance (3) Products (3) REST (3) Role (3) Salesforce Certification (3) Scratch Org (3) Study Notes. (3) Summer15 (3) Web Technology (3) automation tool (3) dynamic apex (3) license (3) map (3) mapbox (3) release (3) singleton (3) version controlling (3) visual studio code (3) Asynchronous callout (2) Aura Framework (2) Bulkify (2) Community (2) Data Architecture and Management Certification (2) Devops (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) Lightning Feature (2) Live Agent (2) Metadata (2) PD II (2) Price Book (2) SOSL (2) Sharing (2) Spring 15 (2) Summer17 (2) Territory (2) Virtual Event (2) ant (2) basic (2) chatter (2) coding (2) communication (2) configuration (2) console (2) controller (2) documentation (2) dreamforce (2) flow (2) git (2) jquery (2) logging (2) object (2) permission (2) process builder (2) salesforce1 (2) strategy (2) xml (2) Action Plan (1) Action Plan Template (1) Activity Timeline (1) Advanced Currency (1) Agent Productivity (1) Analytics (1) Apex Sharing (1) AppExchange (1) Arrow (1) Article (1) Asynchronous Apex (1) Batch (1) Bots (1) Browser (1) Bulk data load (1) CTA (1) Calendar (1) Canon (1) Case Management (1) Celebration (1) Cheat Sheet (1) Classic (1) Compare (1) Confetti (1) Constructor (1) Contact Center (1) Continuation (1) Continuous Integration (1) Convert (1) Cookie (1) CumulusCI (1) Custom Metadata (1) Custom Object (1) Custom Permission (1) Customer (1) Dated Exchange Rate (1) Decorator Design Pattern (1) Dev Hub (1) Development (1) Diwali (1) EDA (1) ESLint (1) Education Cloud (1) Email (1) FSC (1) Function (1) Future (1) Global Gathering (1) Goals (1) Guest Access (1) Guest Profile (1) Guest User Sharing Rule (1) Guide (1) HEDA (1) Higher Education (1) Household (1) Husky (1) IDE (1) Ideas (1) Improvement (1) KPIs (1) Knowledge Management (1) LWC (1) Large Data Volume (1) LastModifiedDate (1) Manage Currencies (1) Manual Sharing (1) Metrics (1) Multi Currency (1) New (1) New Feature (1) OOPS (1) OWD (1) Omni-Channel (1) Partner (1) Permission Set (1) Person Account (1) Photo (1) Pipeline (1) Platform Developer I (1) Platform Developer II (1) Presentation (1) Prettier (1) Product Schedule (1) Profile (1) Promise (1) Prototype (1) Public Site (1) Query Plan (1) Queueable (1) QuickReference (1) Related records (1) Reports (1) Retrieve (1) Role Hierarchy (1) SAL (1) SFDX (1) Salesfor (1) Salesforce Advisor Link (1) Salesforce Labs (1) Salesforce Optimizer (1) SalesforceDx (1) Schedule (1) Session (1) Sharing Rule (1) Sharing Sets (1) Site (1) Skills (1) Snap-ins (1) Spring 17 (1) Spring 20 (1) Summer14 (1) Summer16 (1) Summer19 (1) Switch (1) SystemModStamp (1) Timeline (1) Unauthorized Access (1) User License (1) Users (1) VS Code (1) Validation Rule (1) Webservice (1) Winter'15 (1) Winter'17 (1) access (1) actionFunction (1) actionPoller (1) actionRegion (1) actionSupport (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) csv (1) custom button (1) custom settings (1) customization (1) data loader (1) database (1) delegate Admin (1) describe (1) dom (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)

Popular Posts

Total Subscribers

Total Pageviews

Contact Me

Name

Email *

Message *