Monday, June 29, 2015

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.

0 comments:

Post a Comment