SlideShare a Scribd company logo
Building Strong Foundations
Apex Enterprise Patterns
Andrew Fawcett, FinancialForce.com, CTO
@andyinthecloud
All about FinancialForce.com
Revolutionizing the Back Office
#1 Accounting, Billing and PSA Apps on the Salesforce platform

▪ Native apps
▪ San Francisco HQ, 595 Market St
▪ R&D in San Francisco, Harrogate UK, and Granada ES
▪ We are hiring! Meet us at Rehab!
What's wrong with this picture?
What's wrong with this picture?

public with sharing class MyController
{
public String theId;

public MyController(ApexPages.StandardController standardController)
{
theId = (String) ApexPages.currentPage().getParameters().get('id');
}
public PageReference actionCheckInvoices()
{
// Read the Account record
Account accountRecord = [select Id, Name from Account where Id = :theId];
// Do some processing on the Account record ... then update it
update accountRecord;
return null;
}
}
public with sharing class MyBatchJob implements Database.Batchable<SObject>
{
public void execute(Database.batchableContext info, List<Account> accounts)
{
for(Account account : accounts)
{
MyController myController = new MyController(new ApexPages.StandardController(account));
myController.actionCheckInvoices();
}
}
public Database.QueryLocator start(Database.BatchableContext info) { ... }
public void finish(Database.batchableContext info) { ... }
}

Developer “A” writes an
Apex Controller first

Developer “B” writes an
Apex Batch job later.
So what was wrong with that picture?
MyController
MyController

Issue

Use of ApexPages.currentPage()

Unnecessary and fragile, utilize instead
stdController.getId() method

Error handling

No try/catch error handling on controller
method

Developer “A”

MyBatchJob

Issue

Use of ApexPages.currentPage()

Is not available in a Batch Apex context, the constructor
code will give an exception.

SOQL Query and DML Governors

Calling the controller method in a loop will cause a SOQL
query and DML governor issues.

Error Handling

No try/catch error handling in the the execute method

Separation of Concerns

Developer A did not originally develop the controller logic
expecting or anticipating Developer B’s would in the future
try to reuse it from a Batch Context as well.
They did not consider correct Separation of Concerns…

Developer “B”
Pattern Checklist
Separation of Concerns
Service Layer
Domain Layer
Selector Layer

☐
☐
☐
☐
So what is “Separation of Concerns” then?
“The goal is to design systems so that functions can be
optimized independently of other functions, so that failure of one
function does not cause other functions to fail, and in general to
make it easier to understand, design and manage complex
interdependent systems”
Wikipedia, “Separation of Concerns”
So what is “DRY” then?
Don’t Repeat Yourself
“Every piece of knowledge must have a single, unambiguous,
authoritative representation within a system.”
Wikipedia, “Don’t repeat yourself (DRY)”
Design Patterns for SOC & Force.com Best Practice
Service Layer
Domain Layer
▪ Yet another Wrapper / Trigger pattern!

Selector Layer
Reference Martin Fowler
▪

http://martinfowler.com/eaaCatalog/

▪

Author of “Patterns of Enterprise
Application Architecture”

Reference
▪

http://wiki.developerforce.com/page/Apex_Enterprise_Patterns_-_Separation_of_Concerns
Demo! “takeaway” a Sample Force.com Application!

GitHub: financialforcedev/fflib-apex-common-samplecode
Sample Application, what’s on the menu?
Platform Feature

Patterns Used

Custom Buttons

Building UI logic and calling Service Layer code
from Controllers

Batch Apex

Reusing Service and Selector Layer code from
with a Batch context

Integration API

Exposing an Integration API via Service Layer
using Apex and REST

Apex Triggers

Factoring your Apex Trigger logic via the Domain
Layer (wrappers)

VisualForce Remoting

Exposing Service Layer code to HTML5 /
JavaScript libraries such as JQuery

GitHub: financialforcedev/fflib-apex-common-samplecode
Pattern Checklist
Separation of Concerns
Service Layer
Domain Layer
Selector Layer

☑
☐
☐
☐
Introducing the Service Layer
Introducing the Service Layer
Naming Convention
▪ Suffix with ‘Service’, e.g. OpportunitiesService
▪ Methods named by purpose not usage, e.g. applyDiscounts
Introducing the Service Layer
Clear Code Factoring
▪ Encapsulates Processes / Tasks
▪ Caller Context Agnostic
Introducing the Service Layer
Defined Responsibilities
▪ Supports Bulkifcation
▪ Transaction management
Developing and calling a Service Layer

public with sharing class AccountService
{
public static void checkOutstandingInvoices(Set<Id> accountIds)
{
// Read the Account records
List<Account> accountRecords = [select Id, Name from Account where Id in :accountIds];
// Do some processing on the Account and Invoice records ... then update them.
update accountRecords;
}
}

Developer “A”
follows Service
Layer pattern.

AccountService.cls
Service Contract
public PageReference actionCheckInvoices()
{
try {
// Process the Account record
AccountService.checkOutstandingInvoices(new Set<Id> { theId });
} catch (Exception e) { ApexPage.addMessages(e); }
return null;
}

Developer “A”
writes Controller
code to consume
the Service.

MyController.cls
public void execute(Database.batchableContext info, List<Account> accounts)
{
try {
// Process Account records
Set<Id> accountIds = new Map<Id, Account>(accounts).keySet();
AccountService.checkOutstandingInvoices(accountIds);
} catch (Exception e) { emailError(e); }
}

MyBatch.cls

Developer “B”
then reuses the
Developer “A”
code safely.
Code Walkthrough : Sample Services
Managing DML and Transactions
▪ Unit of Work Pattern

Classes
OpportunitiesService.cls
Code Walkthrough : Custom Buttons
Custom Buttons
▪

Detail and List View

▪

Calling Visualforce Controller Code

Visualforce Controllers and Pages
▪

Error Handling

▪

Interacts with Service Layer
•

Utilize bulkified methods

•

Assume transaction containment

•

Catch exceptions and display them on the page

Classes and Pages
OpportunityApplyDiscountController.cls
• opportunityapplydiscount.page
• opportunityapplydiscounts.page
OpportunityCreateInvoiceController.cls
• opportunitycreateinvoice.page
• opportunitycreateinvoices.page
CodeHandling
Walkthrough : Batch Apex
▪ Error

Classes

▪ Interacts with Service Layer

CreatesInvoicesJob.cls

• Utilize bulkified methods
• Assume transaction containment
• Catch exceptions and logs them for later notificaiton
CodeHandling
Walkthrough : Exposing an Integration API
▪ Error
Classes

• Pass business logic exceptions to caller to handle
• Assume transaction containment

OpportunitiesResource.cls
OpportunitiesService.cls

▪ Exposing the API
• To Apex Developers > Mark Service class and methods as global!
–

Package to apply Apex versioning of the API

• To Web / Mobile Developers > Create RESTful API around Service layer
Code Walkthrough : Visualforce Remoting
An “Opportunities Discount Console”

Classes
OpportunityConsoleController.cls

▪ Developer uses a Rich HTML5 Client Library, such as JQuery
• Is not using traditional Visualforce markup or action functions on the controller

▪ Utilizing static “remote” methods on the controller (stateless controller)
• Able to consume the Service layer functions also!
• Assumes transactional integrity
• Assumes the caller (JavaScript client) to handle exceptions
Pattern Checklist
Separation of Concerns
Service Layer
Domain Layer
Selector Layer

☑
☑
☐
☐
Introducing the Domain Layer
Introducing the Domain Layer
Naming Convention
▪ Name uses plural name of object, e.g. Opportunities
Introducing the Domain Layer
Clear Code Factoring
▪ Encapsulates Validation
/ Defaulting of Fields
▪ Wraps Apex Trigger Logic
in Apex Class
(Trigger/Wrapper Pattern)
Introducing the Domain Layer
Defined Responsibilities
▪ Enforces Bulkifcation for logic
▪ Platform security best practice
(honors Users profile)
▪ Encapsulates ALL logic / behavior
for each object
• e.g. onValidate, onBeforeInsert and
applyDiscount
Introducing the Domain Layer : Apex Trigger Flow
Code Walkthrough : Domain Layer : Apex Triggers
What no code?!? ☺

Triggers
OpportunitiesTrigger.trigger
OpportunityLineItemsTrigger.trigger
Code Walkthrough : Domain Layer : Domain Classes
Bulkified Wrappers

▪ Base class fflib_SObjectDomain
▪ Apex Trigger Callers
▪ Support for DML Free Testing
▪ Able to apply Object Orientated Programming

Apex Classes
Opportunities.cls
OpportunityLineItems.cls
Accounts.cls
Code Walkthrough : Domain Layer : Service Callers
Apex Service Callers

▪ Create Domain Instances
▪ Bulkified Calls
Apex Classes
OpportunitiesService.cls
Code Walkthrough : Domain : Extends vs Interfaces
Extending Apex Domain Classes
▪ Extend or adjust existing behavior of classes of a similar nature
• Base class Chargeable ensures cost is recalculated on insert and update
• DeveloperWorkItems Domain Class extends to provide its own calc logic

Implementing Apex Domain Interfaces
▪ Good for applying behavior to different types of classes
• Interface InvoiceService.ISupportInvoicing
• Implemented by Opportunities Domain Class
Code Walkthrough : Domain Class Extension
Chargeable Base Class
▪ Apply to Custom Objects recording Work
▪ Require hours and cost calculations
▪ Performs recalculation on insert and update
Pattern Checklist
Separation of Concerns
Service Layer
Domain Layer
Selector Layer

☑
☑
☑
☐
Introducing the Selector Layer
Introducing the Selector Layer
Naming Convention
▪ Plural object name suffixed by Selector
• e.g. OpportunitiesSelector
Introducing the Selector Layer
Clear Code Factoring
▪ Encapsulates Query Logic
Introducing the Selector Layer
Defined Responsibilities
▪ Consistency over queried fields
▪ Platform security best practice
▪ Encapsulates ALL query logic
Code Walkthrough : Selector Layer
Encapsulate Query Fields and Logic
▪ Base class fflib_SObjectSelector
▪ Defines Common Fields
▪ Default SOQL Helpers, FieldSet Support

Apex Classes
OpportunitiesSelector.cls
OpportunityLineItemsSelector.cls
ProductsSelector.cls
PricebooksSelector.cls
PricebookEntriesSelector.cls
Code Walkthrough : Selector Layer : Callers

Service Layer Logic : OpportunitiesSelector.selectByIdWithProducts

Apex Class
OpportunitiesService.cls

Domain Layer Logic : AccountsSelector.selectByOpportunity

Apex Class
Opportunities.cls
Code Walkthrough : Selector Layer : Callers
Batch Apex : OpportunitiesSelector.queryLocatorReadyToInvoice

Apex Class
CreatesInvoicesJob.cls
Pattern Checklist
Separation of Concerns
Service Layer
Domain Layer
Selector Layer

☑
☑
☑
☑
Summary
Summary
When is SOC / DRY appropriate (a rough guide)?
Solution / Code
Base Size

Developers

Requirements Scope

Number of Client Types
and Interactions

SOC/DRY
Appropriate?

Small

1 to 2

•

Well known and unlikely to
change
One off solutions
Limited number of objects

•
•
•
•
•

Standard UI
Simple VF / Triggers
No Batch Mode
No API
No Mobile

Typically not

Well known but may need to
evolve rapidly
Growing number objects and
processes interacting
Product deliverable or larger
duration projects

•
•
•
•
•

Standard UI
Advanced VF / JQuery
Batch Mode
API (on roadmap)
Mobile (on roadmap)

Worth
considering

Scope driven by multiple
customers and user types
Large number of objects
Generic product or solution
aimed at Mid to Enterprise
market with Customer or
Partner Integrations.
Growing development team!

•
•
•
•
•
•

Standard UI
Advanced VF / JQuery
Batch Mode
Developer / Partner API
Mobile Clients
New Platform Feature
Ready, Chatter Actions!

•
•
Small to Medium

1 to 6

•
•
•

Large

>6

•
•
•

•

Definite benifits
Other Design Patterns Helping with SOC/DRY
Alternative Domain Layer Patterns
▪ ‘Apex Trigger Pattern’ (Tony Scott)
• http://developer.force.com/cookbook/recipe/trigger-pattern-for-tidy-streamlined-bulkified-triggers

▪ ‘Salesforce Apex Wrapper Class’ (Mike Leach)
• http://www.embracingthecloud.com/2013/09/06/SalesforceApexWrapperClass.aspx

▪ ‘Trigger Architecture Framework’ (Hari Krishnan)
• http://krishhari.wordpress.com/category/technology/salesforce/apex-triggers/
Andrew Fawcett
CTO,
@andyinthecloud
Apex Enterprise Patterns: Building Strong Foundations
Ad

More Related Content

What's hot (20)

Introduction to Apex for Developers
Introduction to Apex for DevelopersIntroduction to Apex for Developers
Introduction to Apex for Developers
Salesforce Developers
 
Building strong foundations apex enterprise patterns
Building strong foundations apex enterprise patternsBuilding strong foundations apex enterprise patterns
Building strong foundations apex enterprise patterns
andyinthecloud
 
Salesforce Integration Patterns
Salesforce Integration PatternsSalesforce Integration Patterns
Salesforce Integration Patterns
usolutions
 
Integrating with salesforce
Integrating with salesforceIntegrating with salesforce
Integrating with salesforce
Mark Adcock
 
Salesforce Development Best Practices
Salesforce Development Best PracticesSalesforce Development Best Practices
Salesforce Development Best Practices
Vivek Chawla
 
Salesforce Integration
Salesforce IntegrationSalesforce Integration
Salesforce Integration
Joshua Hoskins
 
Apex Design Patterns
Apex Design PatternsApex Design Patterns
Apex Design Patterns
Salesforce Developers
 
Introduction to the Salesforce Security Model
Introduction to the Salesforce Security ModelIntroduction to the Salesforce Security Model
Introduction to the Salesforce Security Model
Salesforce Developers
 
Exploring the Salesforce REST API
Exploring the Salesforce REST APIExploring the Salesforce REST API
Exploring the Salesforce REST API
Salesforce Developers
 
Apex Design Patterns
Apex Design PatternsApex Design Patterns
Apex Design Patterns
Salesforce Developers
 
Salesforce admin training 1
Salesforce admin training 1Salesforce admin training 1
Salesforce admin training 1
HungPham381
 
Data model in salesforce
Data model in salesforceData model in salesforce
Data model in salesforce
Chamil Madusanka
 
Introduction to Apex Triggers
Introduction to Apex TriggersIntroduction to Apex Triggers
Introduction to Apex Triggers
Salesforce Developers
 
Introduction to Visualforce
Introduction to VisualforceIntroduction to Visualforce
Introduction to Visualforce
Salesforce Developers
 
Introduction to apex code
Introduction to apex codeIntroduction to apex code
Introduction to apex code
EdwinOstos
 
Salesforce integration best practices columbus meetup
Salesforce integration best practices   columbus meetupSalesforce integration best practices   columbus meetup
Salesforce integration best practices columbus meetup
MuleSoft Meetup
 
Record sharing model in salesforce
Record sharing model in salesforceRecord sharing model in salesforce
Record sharing model in salesforce
Sunil kumar
 
Integration using Salesforce Canvas
Integration using Salesforce CanvasIntegration using Salesforce Canvas
Integration using Salesforce Canvas
Dhanik Sahni
 
Apex code (Salesforce)
Apex code (Salesforce)Apex code (Salesforce)
Apex code (Salesforce)
Mohammed Safwat Abu Kwaik
 
Getting Started With Apex REST Services
Getting Started With Apex REST ServicesGetting Started With Apex REST Services
Getting Started With Apex REST Services
Salesforce Developers
 
Building strong foundations apex enterprise patterns
Building strong foundations apex enterprise patternsBuilding strong foundations apex enterprise patterns
Building strong foundations apex enterprise patterns
andyinthecloud
 
Salesforce Integration Patterns
Salesforce Integration PatternsSalesforce Integration Patterns
Salesforce Integration Patterns
usolutions
 
Integrating with salesforce
Integrating with salesforceIntegrating with salesforce
Integrating with salesforce
Mark Adcock
 
Salesforce Development Best Practices
Salesforce Development Best PracticesSalesforce Development Best Practices
Salesforce Development Best Practices
Vivek Chawla
 
Salesforce Integration
Salesforce IntegrationSalesforce Integration
Salesforce Integration
Joshua Hoskins
 
Introduction to the Salesforce Security Model
Introduction to the Salesforce Security ModelIntroduction to the Salesforce Security Model
Introduction to the Salesforce Security Model
Salesforce Developers
 
Salesforce admin training 1
Salesforce admin training 1Salesforce admin training 1
Salesforce admin training 1
HungPham381
 
Introduction to apex code
Introduction to apex codeIntroduction to apex code
Introduction to apex code
EdwinOstos
 
Salesforce integration best practices columbus meetup
Salesforce integration best practices   columbus meetupSalesforce integration best practices   columbus meetup
Salesforce integration best practices columbus meetup
MuleSoft Meetup
 
Record sharing model in salesforce
Record sharing model in salesforceRecord sharing model in salesforce
Record sharing model in salesforce
Sunil kumar
 
Integration using Salesforce Canvas
Integration using Salesforce CanvasIntegration using Salesforce Canvas
Integration using Salesforce Canvas
Dhanik Sahni
 
Getting Started With Apex REST Services
Getting Started With Apex REST ServicesGetting Started With Apex REST Services
Getting Started With Apex REST Services
Salesforce Developers
 

Viewers also liked (20)

Development lifecycle guide (part 1)
Development lifecycle guide (part 1)Development lifecycle guide (part 1)
Development lifecycle guide (part 1)
Abdelhakim Mouttaqui ☁
 
Apex collection patterns
Apex collection patternsApex collection patterns
Apex collection patterns
Sathishkumar Periyasamy
 
Salesforce Coding techniques that keep your admins happy (DF13)
Salesforce Coding techniques that keep your admins happy (DF13)Salesforce Coding techniques that keep your admins happy (DF13)
Salesforce Coding techniques that keep your admins happy (DF13)
Roy Gilad
 
From Sandbox To Production: An Introduction to Salesforce Release Management
From Sandbox To Production: An Introduction to Salesforce Release ManagementFrom Sandbox To Production: An Introduction to Salesforce Release Management
From Sandbox To Production: An Introduction to Salesforce Release Management
Salesforce Developers
 
Secure Development on the Salesforce Platform - Part 3
Secure Development on the Salesforce Platform - Part 3Secure Development on the Salesforce Platform - Part 3
Secure Development on the Salesforce Platform - Part 3
Mark Adcock
 
Advanced Apex Development - Asynchronous Processes
Advanced Apex Development - Asynchronous ProcessesAdvanced Apex Development - Asynchronous Processes
Advanced Apex Development - Asynchronous Processes
Salesforce Developers
 
Salesforce Release Management - Best Practices and Tools for Deployment
Salesforce Release Management - Best Practices and Tools for DeploymentSalesforce Release Management - Best Practices and Tools for Deployment
Salesforce Release Management - Best Practices and Tools for Deployment
Salesforce Developers
 
Secure Development on the Salesforce Platform - Part I
Secure Development on the Salesforce Platform - Part ISecure Development on the Salesforce Platform - Part I
Secure Development on the Salesforce Platform - Part I
Salesforce Developers
 
The Ideal Salesforce Development Lifecycle
The Ideal Salesforce Development LifecycleThe Ideal Salesforce Development Lifecycle
The Ideal Salesforce Development Lifecycle
Joshua Hoskins
 
Salesforce Data Structures
Salesforce Data StructuresSalesforce Data Structures
Salesforce Data Structures
Idealist Consulting
 
Salesforce.com process map (from lead to opportunity)
Salesforce.com process map (from lead to opportunity)Salesforce.com process map (from lead to opportunity)
Salesforce.com process map (from lead to opportunity)
Roger Borges Grilo
 
Secure Development on the Salesforce Platform - Part 2
Secure Development on the Salesforce Platform - Part 2Secure Development on the Salesforce Platform - Part 2
Secure Development on the Salesforce Platform - Part 2
Salesforce Developers
 
Enterprise Architecture Salesforce
Enterprise Architecture SalesforceEnterprise Architecture Salesforce
Enterprise Architecture Salesforce
Peter Doolan
 
Introduction to Campaigns in Salesforce - Create, Manage, Launch, and Measure
Introduction to Campaigns in Salesforce - Create, Manage, Launch, and MeasureIntroduction to Campaigns in Salesforce - Create, Manage, Launch, and Measure
Introduction to Campaigns in Salesforce - Create, Manage, Launch, and Measure
Shell Black
 
Salesforce com-architecture
Salesforce com-architectureSalesforce com-architecture
Salesforce com-architecture
drewz lin
 
Top 10 Checklist For Successful Salesforce Implementation
Top 10 Checklist For Successful Salesforce ImplementationTop 10 Checklist For Successful Salesforce Implementation
Top 10 Checklist For Successful Salesforce Implementation
Intelligentia IT Systems Pvt. Ltd.
 
Build Cloud & Mobile App on Salesforce Force.com Platform in 15 mins
Build Cloud & Mobile App on Salesforce Force.com Platform in 15 minsBuild Cloud & Mobile App on Salesforce Force.com Platform in 15 mins
Build Cloud & Mobile App on Salesforce Force.com Platform in 15 mins
Kashi Ahmed
 
Salesforce Presentation
Salesforce PresentationSalesforce Presentation
Salesforce Presentation
Chetna Purohit
 
Salesforce CRM 7 domains of Success
Salesforce CRM 7 domains of SuccessSalesforce CRM 7 domains of Success
Salesforce CRM 7 domains of Success
Kevin Sherman
 
Salesforce.com Overview
Salesforce.com OverviewSalesforce.com Overview
Salesforce.com Overview
Edureka!
 
Salesforce Coding techniques that keep your admins happy (DF13)
Salesforce Coding techniques that keep your admins happy (DF13)Salesforce Coding techniques that keep your admins happy (DF13)
Salesforce Coding techniques that keep your admins happy (DF13)
Roy Gilad
 
From Sandbox To Production: An Introduction to Salesforce Release Management
From Sandbox To Production: An Introduction to Salesforce Release ManagementFrom Sandbox To Production: An Introduction to Salesforce Release Management
From Sandbox To Production: An Introduction to Salesforce Release Management
Salesforce Developers
 
Secure Development on the Salesforce Platform - Part 3
Secure Development on the Salesforce Platform - Part 3Secure Development on the Salesforce Platform - Part 3
Secure Development on the Salesforce Platform - Part 3
Mark Adcock
 
Advanced Apex Development - Asynchronous Processes
Advanced Apex Development - Asynchronous ProcessesAdvanced Apex Development - Asynchronous Processes
Advanced Apex Development - Asynchronous Processes
Salesforce Developers
 
Salesforce Release Management - Best Practices and Tools for Deployment
Salesforce Release Management - Best Practices and Tools for DeploymentSalesforce Release Management - Best Practices and Tools for Deployment
Salesforce Release Management - Best Practices and Tools for Deployment
Salesforce Developers
 
Secure Development on the Salesforce Platform - Part I
Secure Development on the Salesforce Platform - Part ISecure Development on the Salesforce Platform - Part I
Secure Development on the Salesforce Platform - Part I
Salesforce Developers
 
The Ideal Salesforce Development Lifecycle
The Ideal Salesforce Development LifecycleThe Ideal Salesforce Development Lifecycle
The Ideal Salesforce Development Lifecycle
Joshua Hoskins
 
Salesforce.com process map (from lead to opportunity)
Salesforce.com process map (from lead to opportunity)Salesforce.com process map (from lead to opportunity)
Salesforce.com process map (from lead to opportunity)
Roger Borges Grilo
 
Secure Development on the Salesforce Platform - Part 2
Secure Development on the Salesforce Platform - Part 2Secure Development on the Salesforce Platform - Part 2
Secure Development on the Salesforce Platform - Part 2
Salesforce Developers
 
Enterprise Architecture Salesforce
Enterprise Architecture SalesforceEnterprise Architecture Salesforce
Enterprise Architecture Salesforce
Peter Doolan
 
Introduction to Campaigns in Salesforce - Create, Manage, Launch, and Measure
Introduction to Campaigns in Salesforce - Create, Manage, Launch, and MeasureIntroduction to Campaigns in Salesforce - Create, Manage, Launch, and Measure
Introduction to Campaigns in Salesforce - Create, Manage, Launch, and Measure
Shell Black
 
Salesforce com-architecture
Salesforce com-architectureSalesforce com-architecture
Salesforce com-architecture
drewz lin
 
Build Cloud & Mobile App on Salesforce Force.com Platform in 15 mins
Build Cloud & Mobile App on Salesforce Force.com Platform in 15 minsBuild Cloud & Mobile App on Salesforce Force.com Platform in 15 mins
Build Cloud & Mobile App on Salesforce Force.com Platform in 15 mins
Kashi Ahmed
 
Salesforce Presentation
Salesforce PresentationSalesforce Presentation
Salesforce Presentation
Chetna Purohit
 
Salesforce CRM 7 domains of Success
Salesforce CRM 7 domains of SuccessSalesforce CRM 7 domains of Success
Salesforce CRM 7 domains of Success
Kevin Sherman
 
Salesforce.com Overview
Salesforce.com OverviewSalesforce.com Overview
Salesforce.com Overview
Edureka!
 
Ad

Similar to Apex Enterprise Patterns: Building Strong Foundations (20)

Developing Next-Gen Enterprise Web Application
Developing Next-Gen Enterprise Web ApplicationDeveloping Next-Gen Enterprise Web Application
Developing Next-Gen Enterprise Web Application
Mark Gu
 
Evolutionary db development
Evolutionary db development Evolutionary db development
Evolutionary db development
Open Party
 
Tdd,Ioc
Tdd,IocTdd,Ioc
Tdd,Ioc
Antonio Radesca
 
Intro to Ruby on Rails
Intro to Ruby on RailsIntro to Ruby on Rails
Intro to Ruby on Rails
Mark Menard
 
Intro to ColdBox MVC at Japan CFUG
Intro to ColdBox MVC at Japan CFUGIntro to ColdBox MVC at Japan CFUG
Intro to ColdBox MVC at Japan CFUG
Ortus Solutions, Corp
 
C:\Fakepath\Combating Software Entropy 2
C:\Fakepath\Combating Software Entropy 2C:\Fakepath\Combating Software Entropy 2
C:\Fakepath\Combating Software Entropy 2
Hammad Rajjoub
 
C:\Fakepath\Combating Software Entropy 2
C:\Fakepath\Combating Software Entropy 2C:\Fakepath\Combating Software Entropy 2
C:\Fakepath\Combating Software Entropy 2
Hammad Rajjoub
 
Coding Naked 2023
Coding Naked 2023Coding Naked 2023
Coding Naked 2023
Caleb Jenkins
 
CQRS / ES & DDD Demystified
CQRS / ES & DDD DemystifiedCQRS / ES & DDD Demystified
CQRS / ES & DDD Demystified
Vic Metcalfe
 
Apex Code Analysis Using the Tooling API and Canvas
Apex Code Analysis Using the Tooling API and CanvasApex Code Analysis Using the Tooling API and Canvas
Apex Code Analysis Using the Tooling API and Canvas
Salesforce Developers
 
Appengine Nljug
Appengine NljugAppengine Nljug
Appengine Nljug
Paul Bakker
 
Silverlight 2 for Developers - TechEd New Zealand 2008
Silverlight 2 for Developers - TechEd New Zealand 2008Silverlight 2 for Developers - TechEd New Zealand 2008
Silverlight 2 for Developers - TechEd New Zealand 2008
Jonas Follesø
 
Hands-On Workshop: Introduction to Development on Force.com for Developers
Hands-On Workshop: Introduction to Development on Force.com for DevelopersHands-On Workshop: Introduction to Development on Force.com for Developers
Hands-On Workshop: Introduction to Development on Force.com for Developers
Salesforce Developers
 
Hands-On Workshop: Introduction to Coding for on Force.com for Admins and Non...
Hands-On Workshop: Introduction to Coding for on Force.com for Admins and Non...Hands-On Workshop: Introduction to Coding for on Force.com for Admins and Non...
Hands-On Workshop: Introduction to Coding for on Force.com for Admins and Non...
Salesforce Developers
 
Summer '16 Realease notes
Summer '16 Realease notesSummer '16 Realease notes
Summer '16 Realease notes
aggopal1011
 
C# .NET Developer Portfolio
C# .NET Developer PortfolioC# .NET Developer Portfolio
C# .NET Developer Portfolio
cummings49
 
Containerisation Hack of a Legacy Software Solution - Alex Carter - CodeMill ...
Containerisation Hack of a Legacy Software Solution - Alex Carter - CodeMill ...Containerisation Hack of a Legacy Software Solution - Alex Carter - CodeMill ...
Containerisation Hack of a Legacy Software Solution - Alex Carter - CodeMill ...
CodeMill digital skills
 
How to generate customized java 8 code from your database
How to generate customized java 8 code from your databaseHow to generate customized java 8 code from your database
How to generate customized java 8 code from your database
Speedment, Inc.
 
Silicon Valley JUG - How to generate customized java 8 code from your database
Silicon Valley JUG - How to generate customized java 8 code from your databaseSilicon Valley JUG - How to generate customized java 8 code from your database
Silicon Valley JUG - How to generate customized java 8 code from your database
Speedment, Inc.
 
#CNX14 - Intro to Force
#CNX14 - Intro to Force#CNX14 - Intro to Force
#CNX14 - Intro to Force
Salesforce Marketing Cloud
 
Developing Next-Gen Enterprise Web Application
Developing Next-Gen Enterprise Web ApplicationDeveloping Next-Gen Enterprise Web Application
Developing Next-Gen Enterprise Web Application
Mark Gu
 
Evolutionary db development
Evolutionary db development Evolutionary db development
Evolutionary db development
Open Party
 
Intro to Ruby on Rails
Intro to Ruby on RailsIntro to Ruby on Rails
Intro to Ruby on Rails
Mark Menard
 
C:\Fakepath\Combating Software Entropy 2
C:\Fakepath\Combating Software Entropy 2C:\Fakepath\Combating Software Entropy 2
C:\Fakepath\Combating Software Entropy 2
Hammad Rajjoub
 
C:\Fakepath\Combating Software Entropy 2
C:\Fakepath\Combating Software Entropy 2C:\Fakepath\Combating Software Entropy 2
C:\Fakepath\Combating Software Entropy 2
Hammad Rajjoub
 
CQRS / ES & DDD Demystified
CQRS / ES & DDD DemystifiedCQRS / ES & DDD Demystified
CQRS / ES & DDD Demystified
Vic Metcalfe
 
Apex Code Analysis Using the Tooling API and Canvas
Apex Code Analysis Using the Tooling API and CanvasApex Code Analysis Using the Tooling API and Canvas
Apex Code Analysis Using the Tooling API and Canvas
Salesforce Developers
 
Silverlight 2 for Developers - TechEd New Zealand 2008
Silverlight 2 for Developers - TechEd New Zealand 2008Silverlight 2 for Developers - TechEd New Zealand 2008
Silverlight 2 for Developers - TechEd New Zealand 2008
Jonas Follesø
 
Hands-On Workshop: Introduction to Development on Force.com for Developers
Hands-On Workshop: Introduction to Development on Force.com for DevelopersHands-On Workshop: Introduction to Development on Force.com for Developers
Hands-On Workshop: Introduction to Development on Force.com for Developers
Salesforce Developers
 
Hands-On Workshop: Introduction to Coding for on Force.com for Admins and Non...
Hands-On Workshop: Introduction to Coding for on Force.com for Admins and Non...Hands-On Workshop: Introduction to Coding for on Force.com for Admins and Non...
Hands-On Workshop: Introduction to Coding for on Force.com for Admins and Non...
Salesforce Developers
 
Summer '16 Realease notes
Summer '16 Realease notesSummer '16 Realease notes
Summer '16 Realease notes
aggopal1011
 
C# .NET Developer Portfolio
C# .NET Developer PortfolioC# .NET Developer Portfolio
C# .NET Developer Portfolio
cummings49
 
Containerisation Hack of a Legacy Software Solution - Alex Carter - CodeMill ...
Containerisation Hack of a Legacy Software Solution - Alex Carter - CodeMill ...Containerisation Hack of a Legacy Software Solution - Alex Carter - CodeMill ...
Containerisation Hack of a Legacy Software Solution - Alex Carter - CodeMill ...
CodeMill digital skills
 
How to generate customized java 8 code from your database
How to generate customized java 8 code from your databaseHow to generate customized java 8 code from your database
How to generate customized java 8 code from your database
Speedment, Inc.
 
Silicon Valley JUG - How to generate customized java 8 code from your database
Silicon Valley JUG - How to generate customized java 8 code from your databaseSilicon Valley JUG - How to generate customized java 8 code from your database
Silicon Valley JUG - How to generate customized java 8 code from your database
Speedment, Inc.
 
Ad

More from Salesforce Developers (20)

Sample Gallery: Reference Code and Best Practices for Salesforce Developers
Sample Gallery: Reference Code and Best Practices for Salesforce DevelopersSample Gallery: Reference Code and Best Practices for Salesforce Developers
Sample Gallery: Reference Code and Best Practices for Salesforce Developers
Salesforce Developers
 
Maximizing Salesforce Lightning Experience and Lightning Component Performance
Maximizing Salesforce Lightning Experience and Lightning Component PerformanceMaximizing Salesforce Lightning Experience and Lightning Component Performance
Maximizing Salesforce Lightning Experience and Lightning Component Performance
Salesforce Developers
 
Local development with Open Source Base Components
Local development with Open Source Base ComponentsLocal development with Open Source Base Components
Local development with Open Source Base Components
Salesforce Developers
 
TrailheaDX India : Developer Highlights
TrailheaDX India : Developer HighlightsTrailheaDX India : Developer Highlights
TrailheaDX India : Developer Highlights
Salesforce Developers
 
Why developers shouldn’t miss TrailheaDX India
Why developers shouldn’t miss TrailheaDX IndiaWhy developers shouldn’t miss TrailheaDX India
Why developers shouldn’t miss TrailheaDX India
Salesforce Developers
 
CodeLive: Build Lightning Web Components faster with Local Development
CodeLive: Build Lightning Web Components faster with Local DevelopmentCodeLive: Build Lightning Web Components faster with Local Development
CodeLive: Build Lightning Web Components faster with Local Development
Salesforce Developers
 
CodeLive: Converting Aura Components to Lightning Web Components
CodeLive: Converting Aura Components to Lightning Web ComponentsCodeLive: Converting Aura Components to Lightning Web Components
CodeLive: Converting Aura Components to Lightning Web Components
Salesforce Developers
 
Enterprise-grade UI with open source Lightning Web Components
Enterprise-grade UI with open source Lightning Web ComponentsEnterprise-grade UI with open source Lightning Web Components
Enterprise-grade UI with open source Lightning Web Components
Salesforce Developers
 
TrailheaDX and Summer '19: Developer Highlights
TrailheaDX and Summer '19: Developer HighlightsTrailheaDX and Summer '19: Developer Highlights
TrailheaDX and Summer '19: Developer Highlights
Salesforce Developers
 
Live coding with LWC
Live coding with LWCLive coding with LWC
Live coding with LWC
Salesforce Developers
 
Lightning web components - Episode 4 : Security and Testing
Lightning web components  - Episode 4 : Security and TestingLightning web components  - Episode 4 : Security and Testing
Lightning web components - Episode 4 : Security and Testing
Salesforce Developers
 
LWC Episode 3- Component Communication and Aura Interoperability
LWC Episode 3- Component Communication and Aura InteroperabilityLWC Episode 3- Component Communication and Aura Interoperability
LWC Episode 3- Component Communication and Aura Interoperability
Salesforce Developers
 
Lightning web components episode 2- work with salesforce data
Lightning web components   episode 2- work with salesforce dataLightning web components   episode 2- work with salesforce data
Lightning web components episode 2- work with salesforce data
Salesforce Developers
 
Lightning web components - Episode 1 - An Introduction
Lightning web components - Episode 1 - An IntroductionLightning web components - Episode 1 - An Introduction
Lightning web components - Episode 1 - An Introduction
Salesforce Developers
 
Migrating CPQ to Advanced Calculator and JSQCP
Migrating CPQ to Advanced Calculator and JSQCPMigrating CPQ to Advanced Calculator and JSQCP
Migrating CPQ to Advanced Calculator and JSQCP
Salesforce Developers
 
Scale with Large Data Volumes and Big Objects in Salesforce
Scale with Large Data Volumes and Big Objects in SalesforceScale with Large Data Volumes and Big Objects in Salesforce
Scale with Large Data Volumes and Big Objects in Salesforce
Salesforce Developers
 
Replicate Salesforce Data in Real Time with Change Data Capture
Replicate Salesforce Data in Real Time with Change Data CaptureReplicate Salesforce Data in Real Time with Change Data Capture
Replicate Salesforce Data in Real Time with Change Data Capture
Salesforce Developers
 
Modern Development with Salesforce DX
Modern Development with Salesforce DXModern Development with Salesforce DX
Modern Development with Salesforce DX
Salesforce Developers
 
Get Into Lightning Flow Development
Get Into Lightning Flow DevelopmentGet Into Lightning Flow Development
Get Into Lightning Flow Development
Salesforce Developers
 
Integrate CMS Content Into Lightning Communities with CMS Connect
Integrate CMS Content Into Lightning Communities with CMS ConnectIntegrate CMS Content Into Lightning Communities with CMS Connect
Integrate CMS Content Into Lightning Communities with CMS Connect
Salesforce Developers
 
Sample Gallery: Reference Code and Best Practices for Salesforce Developers
Sample Gallery: Reference Code and Best Practices for Salesforce DevelopersSample Gallery: Reference Code and Best Practices for Salesforce Developers
Sample Gallery: Reference Code and Best Practices for Salesforce Developers
Salesforce Developers
 
Maximizing Salesforce Lightning Experience and Lightning Component Performance
Maximizing Salesforce Lightning Experience and Lightning Component PerformanceMaximizing Salesforce Lightning Experience and Lightning Component Performance
Maximizing Salesforce Lightning Experience and Lightning Component Performance
Salesforce Developers
 
Local development with Open Source Base Components
Local development with Open Source Base ComponentsLocal development with Open Source Base Components
Local development with Open Source Base Components
Salesforce Developers
 
TrailheaDX India : Developer Highlights
TrailheaDX India : Developer HighlightsTrailheaDX India : Developer Highlights
TrailheaDX India : Developer Highlights
Salesforce Developers
 
Why developers shouldn’t miss TrailheaDX India
Why developers shouldn’t miss TrailheaDX IndiaWhy developers shouldn’t miss TrailheaDX India
Why developers shouldn’t miss TrailheaDX India
Salesforce Developers
 
CodeLive: Build Lightning Web Components faster with Local Development
CodeLive: Build Lightning Web Components faster with Local DevelopmentCodeLive: Build Lightning Web Components faster with Local Development
CodeLive: Build Lightning Web Components faster with Local Development
Salesforce Developers
 
CodeLive: Converting Aura Components to Lightning Web Components
CodeLive: Converting Aura Components to Lightning Web ComponentsCodeLive: Converting Aura Components to Lightning Web Components
CodeLive: Converting Aura Components to Lightning Web Components
Salesforce Developers
 
Enterprise-grade UI with open source Lightning Web Components
Enterprise-grade UI with open source Lightning Web ComponentsEnterprise-grade UI with open source Lightning Web Components
Enterprise-grade UI with open source Lightning Web Components
Salesforce Developers
 
TrailheaDX and Summer '19: Developer Highlights
TrailheaDX and Summer '19: Developer HighlightsTrailheaDX and Summer '19: Developer Highlights
TrailheaDX and Summer '19: Developer Highlights
Salesforce Developers
 
Lightning web components - Episode 4 : Security and Testing
Lightning web components  - Episode 4 : Security and TestingLightning web components  - Episode 4 : Security and Testing
Lightning web components - Episode 4 : Security and Testing
Salesforce Developers
 
LWC Episode 3- Component Communication and Aura Interoperability
LWC Episode 3- Component Communication and Aura InteroperabilityLWC Episode 3- Component Communication and Aura Interoperability
LWC Episode 3- Component Communication and Aura Interoperability
Salesforce Developers
 
Lightning web components episode 2- work with salesforce data
Lightning web components   episode 2- work with salesforce dataLightning web components   episode 2- work with salesforce data
Lightning web components episode 2- work with salesforce data
Salesforce Developers
 
Lightning web components - Episode 1 - An Introduction
Lightning web components - Episode 1 - An IntroductionLightning web components - Episode 1 - An Introduction
Lightning web components - Episode 1 - An Introduction
Salesforce Developers
 
Migrating CPQ to Advanced Calculator and JSQCP
Migrating CPQ to Advanced Calculator and JSQCPMigrating CPQ to Advanced Calculator and JSQCP
Migrating CPQ to Advanced Calculator and JSQCP
Salesforce Developers
 
Scale with Large Data Volumes and Big Objects in Salesforce
Scale with Large Data Volumes and Big Objects in SalesforceScale with Large Data Volumes and Big Objects in Salesforce
Scale with Large Data Volumes and Big Objects in Salesforce
Salesforce Developers
 
Replicate Salesforce Data in Real Time with Change Data Capture
Replicate Salesforce Data in Real Time with Change Data CaptureReplicate Salesforce Data in Real Time with Change Data Capture
Replicate Salesforce Data in Real Time with Change Data Capture
Salesforce Developers
 
Modern Development with Salesforce DX
Modern Development with Salesforce DXModern Development with Salesforce DX
Modern Development with Salesforce DX
Salesforce Developers
 
Integrate CMS Content Into Lightning Communities with CMS Connect
Integrate CMS Content Into Lightning Communities with CMS ConnectIntegrate CMS Content Into Lightning Communities with CMS Connect
Integrate CMS Content Into Lightning Communities with CMS Connect
Salesforce Developers
 

Recently uploaded (20)

Automation Dreamin': Capture User Feedback From Anywhere
Automation Dreamin': Capture User Feedback From AnywhereAutomation Dreamin': Capture User Feedback From Anywhere
Automation Dreamin': Capture User Feedback From Anywhere
Lynda Kane
 
Role of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered ManufacturingRole of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered Manufacturing
Andrew Leo
 
Big Data Analytics Quick Research Guide by Arthur Morgan
Big Data Analytics Quick Research Guide by Arthur MorganBig Data Analytics Quick Research Guide by Arthur Morgan
Big Data Analytics Quick Research Guide by Arthur Morgan
Arthur Morgan
 
Build Your Own Copilot & Agents For Devs
Build Your Own Copilot & Agents For DevsBuild Your Own Copilot & Agents For Devs
Build Your Own Copilot & Agents For Devs
Brian McKeiver
 
2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx
Samuele Fogagnolo
 
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath MaestroDev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
UiPathCommunity
 
How Can I use the AI Hype in my Business Context?
How Can I use the AI Hype in my Business Context?How Can I use the AI Hype in my Business Context?
How Can I use the AI Hype in my Business Context?
Daniel Lehner
 
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdfSAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
Precisely
 
Leading AI Innovation As A Product Manager - Michael Jidael
Leading AI Innovation As A Product Manager - Michael JidaelLeading AI Innovation As A Product Manager - Michael Jidael
Leading AI Innovation As A Product Manager - Michael Jidael
Michael Jidael
 
Asthma presentación en inglés abril 2025 pdf
Asthma presentación en inglés abril 2025 pdfAsthma presentación en inglés abril 2025 pdf
Asthma presentación en inglés abril 2025 pdf
VanessaRaudez
 
Buckeye Dreamin 2024: Assessing and Resolving Technical Debt
Buckeye Dreamin 2024: Assessing and Resolving Technical DebtBuckeye Dreamin 2024: Assessing and Resolving Technical Debt
Buckeye Dreamin 2024: Assessing and Resolving Technical Debt
Lynda Kane
 
Into The Box Conference Keynote Day 1 (ITB2025)
Into The Box Conference Keynote Day 1 (ITB2025)Into The Box Conference Keynote Day 1 (ITB2025)
Into The Box Conference Keynote Day 1 (ITB2025)
Ortus Solutions, Corp
 
Rock, Paper, Scissors: An Apex Map Learning Journey
Rock, Paper, Scissors: An Apex Map Learning JourneyRock, Paper, Scissors: An Apex Map Learning Journey
Rock, Paper, Scissors: An Apex Map Learning Journey
Lynda Kane
 
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
Alan Dix
 
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes
 
Hands On: Create a Lightning Aura Component with force:RecordData
Hands On: Create a Lightning Aura Component with force:RecordDataHands On: Create a Lightning Aura Component with force:RecordData
Hands On: Create a Lightning Aura Component with force:RecordData
Lynda Kane
 
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdfComplete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Software Company
 
"Client Partnership — the Path to Exponential Growth for Companies Sized 50-5...
"Client Partnership — the Path to Exponential Growth for Companies Sized 50-5..."Client Partnership — the Path to Exponential Growth for Companies Sized 50-5...
"Client Partnership — the Path to Exponential Growth for Companies Sized 50-5...
Fwdays
 
AI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global TrendsAI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global Trends
InData Labs
 
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc
 
Automation Dreamin': Capture User Feedback From Anywhere
Automation Dreamin': Capture User Feedback From AnywhereAutomation Dreamin': Capture User Feedback From Anywhere
Automation Dreamin': Capture User Feedback From Anywhere
Lynda Kane
 
Role of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered ManufacturingRole of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered Manufacturing
Andrew Leo
 
Big Data Analytics Quick Research Guide by Arthur Morgan
Big Data Analytics Quick Research Guide by Arthur MorganBig Data Analytics Quick Research Guide by Arthur Morgan
Big Data Analytics Quick Research Guide by Arthur Morgan
Arthur Morgan
 
Build Your Own Copilot & Agents For Devs
Build Your Own Copilot & Agents For DevsBuild Your Own Copilot & Agents For Devs
Build Your Own Copilot & Agents For Devs
Brian McKeiver
 
2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx
Samuele Fogagnolo
 
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath MaestroDev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
UiPathCommunity
 
How Can I use the AI Hype in my Business Context?
How Can I use the AI Hype in my Business Context?How Can I use the AI Hype in my Business Context?
How Can I use the AI Hype in my Business Context?
Daniel Lehner
 
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdfSAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
SAP Modernization: Maximizing the Value of Your SAP S/4HANA Migration.pdf
Precisely
 
Leading AI Innovation As A Product Manager - Michael Jidael
Leading AI Innovation As A Product Manager - Michael JidaelLeading AI Innovation As A Product Manager - Michael Jidael
Leading AI Innovation As A Product Manager - Michael Jidael
Michael Jidael
 
Asthma presentación en inglés abril 2025 pdf
Asthma presentación en inglés abril 2025 pdfAsthma presentación en inglés abril 2025 pdf
Asthma presentación en inglés abril 2025 pdf
VanessaRaudez
 
Buckeye Dreamin 2024: Assessing and Resolving Technical Debt
Buckeye Dreamin 2024: Assessing and Resolving Technical DebtBuckeye Dreamin 2024: Assessing and Resolving Technical Debt
Buckeye Dreamin 2024: Assessing and Resolving Technical Debt
Lynda Kane
 
Into The Box Conference Keynote Day 1 (ITB2025)
Into The Box Conference Keynote Day 1 (ITB2025)Into The Box Conference Keynote Day 1 (ITB2025)
Into The Box Conference Keynote Day 1 (ITB2025)
Ortus Solutions, Corp
 
Rock, Paper, Scissors: An Apex Map Learning Journey
Rock, Paper, Scissors: An Apex Map Learning JourneyRock, Paper, Scissors: An Apex Map Learning Journey
Rock, Paper, Scissors: An Apex Map Learning Journey
Lynda Kane
 
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
Alan Dix
 
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes Partner Innovation Updates for May 2025
ThousandEyes
 
Hands On: Create a Lightning Aura Component with force:RecordData
Hands On: Create a Lightning Aura Component with force:RecordDataHands On: Create a Lightning Aura Component with force:RecordData
Hands On: Create a Lightning Aura Component with force:RecordData
Lynda Kane
 
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdfComplete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Software Company
 
"Client Partnership — the Path to Exponential Growth for Companies Sized 50-5...
"Client Partnership — the Path to Exponential Growth for Companies Sized 50-5..."Client Partnership — the Path to Exponential Growth for Companies Sized 50-5...
"Client Partnership — the Path to Exponential Growth for Companies Sized 50-5...
Fwdays
 
AI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global TrendsAI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global Trends
InData Labs
 
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc
 

Apex Enterprise Patterns: Building Strong Foundations

  • 1. Building Strong Foundations Apex Enterprise Patterns Andrew Fawcett, FinancialForce.com, CTO @andyinthecloud
  • 2. All about FinancialForce.com Revolutionizing the Back Office #1 Accounting, Billing and PSA Apps on the Salesforce platform ▪ Native apps ▪ San Francisco HQ, 595 Market St ▪ R&D in San Francisco, Harrogate UK, and Granada ES ▪ We are hiring! Meet us at Rehab!
  • 3. What's wrong with this picture?
  • 4. What's wrong with this picture? public with sharing class MyController { public String theId; public MyController(ApexPages.StandardController standardController) { theId = (String) ApexPages.currentPage().getParameters().get('id'); } public PageReference actionCheckInvoices() { // Read the Account record Account accountRecord = [select Id, Name from Account where Id = :theId]; // Do some processing on the Account record ... then update it update accountRecord; return null; } } public with sharing class MyBatchJob implements Database.Batchable<SObject> { public void execute(Database.batchableContext info, List<Account> accounts) { for(Account account : accounts) { MyController myController = new MyController(new ApexPages.StandardController(account)); myController.actionCheckInvoices(); } } public Database.QueryLocator start(Database.BatchableContext info) { ... } public void finish(Database.batchableContext info) { ... } } Developer “A” writes an Apex Controller first Developer “B” writes an Apex Batch job later.
  • 5. So what was wrong with that picture? MyController MyController Issue Use of ApexPages.currentPage() Unnecessary and fragile, utilize instead stdController.getId() method Error handling No try/catch error handling on controller method Developer “A” MyBatchJob Issue Use of ApexPages.currentPage() Is not available in a Batch Apex context, the constructor code will give an exception. SOQL Query and DML Governors Calling the controller method in a loop will cause a SOQL query and DML governor issues. Error Handling No try/catch error handling in the the execute method Separation of Concerns Developer A did not originally develop the controller logic expecting or anticipating Developer B’s would in the future try to reuse it from a Batch Context as well. They did not consider correct Separation of Concerns… Developer “B”
  • 6. Pattern Checklist Separation of Concerns Service Layer Domain Layer Selector Layer ☐ ☐ ☐ ☐
  • 7. So what is “Separation of Concerns” then? “The goal is to design systems so that functions can be optimized independently of other functions, so that failure of one function does not cause other functions to fail, and in general to make it easier to understand, design and manage complex interdependent systems” Wikipedia, “Separation of Concerns”
  • 8. So what is “DRY” then? Don’t Repeat Yourself “Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.” Wikipedia, “Don’t repeat yourself (DRY)”
  • 9. Design Patterns for SOC & Force.com Best Practice Service Layer Domain Layer ▪ Yet another Wrapper / Trigger pattern! Selector Layer Reference Martin Fowler ▪ http://martinfowler.com/eaaCatalog/ ▪ Author of “Patterns of Enterprise Application Architecture” Reference ▪ http://wiki.developerforce.com/page/Apex_Enterprise_Patterns_-_Separation_of_Concerns
  • 10. Demo! “takeaway” a Sample Force.com Application! GitHub: financialforcedev/fflib-apex-common-samplecode
  • 11. Sample Application, what’s on the menu? Platform Feature Patterns Used Custom Buttons Building UI logic and calling Service Layer code from Controllers Batch Apex Reusing Service and Selector Layer code from with a Batch context Integration API Exposing an Integration API via Service Layer using Apex and REST Apex Triggers Factoring your Apex Trigger logic via the Domain Layer (wrappers) VisualForce Remoting Exposing Service Layer code to HTML5 / JavaScript libraries such as JQuery GitHub: financialforcedev/fflib-apex-common-samplecode
  • 12. Pattern Checklist Separation of Concerns Service Layer Domain Layer Selector Layer ☑ ☐ ☐ ☐
  • 14. Introducing the Service Layer Naming Convention ▪ Suffix with ‘Service’, e.g. OpportunitiesService ▪ Methods named by purpose not usage, e.g. applyDiscounts
  • 15. Introducing the Service Layer Clear Code Factoring ▪ Encapsulates Processes / Tasks ▪ Caller Context Agnostic
  • 16. Introducing the Service Layer Defined Responsibilities ▪ Supports Bulkifcation ▪ Transaction management
  • 17. Developing and calling a Service Layer public with sharing class AccountService { public static void checkOutstandingInvoices(Set<Id> accountIds) { // Read the Account records List<Account> accountRecords = [select Id, Name from Account where Id in :accountIds]; // Do some processing on the Account and Invoice records ... then update them. update accountRecords; } } Developer “A” follows Service Layer pattern. AccountService.cls Service Contract public PageReference actionCheckInvoices() { try { // Process the Account record AccountService.checkOutstandingInvoices(new Set<Id> { theId }); } catch (Exception e) { ApexPage.addMessages(e); } return null; } Developer “A” writes Controller code to consume the Service. MyController.cls public void execute(Database.batchableContext info, List<Account> accounts) { try { // Process Account records Set<Id> accountIds = new Map<Id, Account>(accounts).keySet(); AccountService.checkOutstandingInvoices(accountIds); } catch (Exception e) { emailError(e); } } MyBatch.cls Developer “B” then reuses the Developer “A” code safely.
  • 18. Code Walkthrough : Sample Services Managing DML and Transactions ▪ Unit of Work Pattern Classes OpportunitiesService.cls
  • 19. Code Walkthrough : Custom Buttons Custom Buttons ▪ Detail and List View ▪ Calling Visualforce Controller Code Visualforce Controllers and Pages ▪ Error Handling ▪ Interacts with Service Layer • Utilize bulkified methods • Assume transaction containment • Catch exceptions and display them on the page Classes and Pages OpportunityApplyDiscountController.cls • opportunityapplydiscount.page • opportunityapplydiscounts.page OpportunityCreateInvoiceController.cls • opportunitycreateinvoice.page • opportunitycreateinvoices.page
  • 20. CodeHandling Walkthrough : Batch Apex ▪ Error Classes ▪ Interacts with Service Layer CreatesInvoicesJob.cls • Utilize bulkified methods • Assume transaction containment • Catch exceptions and logs them for later notificaiton
  • 21. CodeHandling Walkthrough : Exposing an Integration API ▪ Error Classes • Pass business logic exceptions to caller to handle • Assume transaction containment OpportunitiesResource.cls OpportunitiesService.cls ▪ Exposing the API • To Apex Developers > Mark Service class and methods as global! – Package to apply Apex versioning of the API • To Web / Mobile Developers > Create RESTful API around Service layer
  • 22. Code Walkthrough : Visualforce Remoting An “Opportunities Discount Console” Classes OpportunityConsoleController.cls ▪ Developer uses a Rich HTML5 Client Library, such as JQuery • Is not using traditional Visualforce markup or action functions on the controller ▪ Utilizing static “remote” methods on the controller (stateless controller) • Able to consume the Service layer functions also! • Assumes transactional integrity • Assumes the caller (JavaScript client) to handle exceptions
  • 23. Pattern Checklist Separation of Concerns Service Layer Domain Layer Selector Layer ☑ ☑ ☐ ☐
  • 25. Introducing the Domain Layer Naming Convention ▪ Name uses plural name of object, e.g. Opportunities
  • 26. Introducing the Domain Layer Clear Code Factoring ▪ Encapsulates Validation / Defaulting of Fields ▪ Wraps Apex Trigger Logic in Apex Class (Trigger/Wrapper Pattern)
  • 27. Introducing the Domain Layer Defined Responsibilities ▪ Enforces Bulkifcation for logic ▪ Platform security best practice (honors Users profile) ▪ Encapsulates ALL logic / behavior for each object • e.g. onValidate, onBeforeInsert and applyDiscount
  • 28. Introducing the Domain Layer : Apex Trigger Flow
  • 29. Code Walkthrough : Domain Layer : Apex Triggers What no code?!? ☺ Triggers OpportunitiesTrigger.trigger OpportunityLineItemsTrigger.trigger
  • 30. Code Walkthrough : Domain Layer : Domain Classes Bulkified Wrappers ▪ Base class fflib_SObjectDomain ▪ Apex Trigger Callers ▪ Support for DML Free Testing ▪ Able to apply Object Orientated Programming Apex Classes Opportunities.cls OpportunityLineItems.cls Accounts.cls
  • 31. Code Walkthrough : Domain Layer : Service Callers Apex Service Callers ▪ Create Domain Instances ▪ Bulkified Calls Apex Classes OpportunitiesService.cls
  • 32. Code Walkthrough : Domain : Extends vs Interfaces Extending Apex Domain Classes ▪ Extend or adjust existing behavior of classes of a similar nature • Base class Chargeable ensures cost is recalculated on insert and update • DeveloperWorkItems Domain Class extends to provide its own calc logic Implementing Apex Domain Interfaces ▪ Good for applying behavior to different types of classes • Interface InvoiceService.ISupportInvoicing • Implemented by Opportunities Domain Class
  • 33. Code Walkthrough : Domain Class Extension Chargeable Base Class ▪ Apply to Custom Objects recording Work ▪ Require hours and cost calculations ▪ Performs recalculation on insert and update
  • 34. Pattern Checklist Separation of Concerns Service Layer Domain Layer Selector Layer ☑ ☑ ☑ ☐
  • 36. Introducing the Selector Layer Naming Convention ▪ Plural object name suffixed by Selector • e.g. OpportunitiesSelector
  • 37. Introducing the Selector Layer Clear Code Factoring ▪ Encapsulates Query Logic
  • 38. Introducing the Selector Layer Defined Responsibilities ▪ Consistency over queried fields ▪ Platform security best practice ▪ Encapsulates ALL query logic
  • 39. Code Walkthrough : Selector Layer Encapsulate Query Fields and Logic ▪ Base class fflib_SObjectSelector ▪ Defines Common Fields ▪ Default SOQL Helpers, FieldSet Support Apex Classes OpportunitiesSelector.cls OpportunityLineItemsSelector.cls ProductsSelector.cls PricebooksSelector.cls PricebookEntriesSelector.cls
  • 40. Code Walkthrough : Selector Layer : Callers Service Layer Logic : OpportunitiesSelector.selectByIdWithProducts Apex Class OpportunitiesService.cls Domain Layer Logic : AccountsSelector.selectByOpportunity Apex Class Opportunities.cls
  • 41. Code Walkthrough : Selector Layer : Callers Batch Apex : OpportunitiesSelector.queryLocatorReadyToInvoice Apex Class CreatesInvoicesJob.cls
  • 42. Pattern Checklist Separation of Concerns Service Layer Domain Layer Selector Layer ☑ ☑ ☑ ☑
  • 45. When is SOC / DRY appropriate (a rough guide)? Solution / Code Base Size Developers Requirements Scope Number of Client Types and Interactions SOC/DRY Appropriate? Small 1 to 2 • Well known and unlikely to change One off solutions Limited number of objects • • • • • Standard UI Simple VF / Triggers No Batch Mode No API No Mobile Typically not Well known but may need to evolve rapidly Growing number objects and processes interacting Product deliverable or larger duration projects • • • • • Standard UI Advanced VF / JQuery Batch Mode API (on roadmap) Mobile (on roadmap) Worth considering Scope driven by multiple customers and user types Large number of objects Generic product or solution aimed at Mid to Enterprise market with Customer or Partner Integrations. Growing development team! • • • • • • Standard UI Advanced VF / JQuery Batch Mode Developer / Partner API Mobile Clients New Platform Feature Ready, Chatter Actions! • • Small to Medium 1 to 6 • • • Large >6 • • • • Definite benifits
  • 46. Other Design Patterns Helping with SOC/DRY Alternative Domain Layer Patterns ▪ ‘Apex Trigger Pattern’ (Tony Scott) • http://developer.force.com/cookbook/recipe/trigger-pattern-for-tidy-streamlined-bulkified-triggers ▪ ‘Salesforce Apex Wrapper Class’ (Mike Leach) • http://www.embracingthecloud.com/2013/09/06/SalesforceApexWrapperClass.aspx ▪ ‘Trigger Architecture Framework’ (Hari Krishnan) • http://krishhari.wordpress.com/category/technology/salesforce/apex-triggers/