Andy in the Cloud

From BBC Basic to Force.com and beyond…

Preview of Advanced Apex Enterprise Patterns Session

7 Comments

At this years Dreamforce i will be presenting not one, but two sessions on Apex Enterprise Patterns this year. The first will be re-run of last years session, Apex Enterprise Patterns : Building Strong Foundations. The second will be a follow on session dealing with more advanced topics around the patterns. Imaginatively entitled Advanced Apex Enterprise Patterns. The current abstract for this session is as follows…

Complex code can easily get out of hand without good design, so in this deep dive you will better understand how to apply the advanced design patterns used by highly experienced Salesforce developers. Starting with Interface & Base Class examples of OO design we quickly move on to new design features including: Application Factory, Field Level Security Support, Selector FieldSet support and Dependency Injection, Mock Testing of Services, Domain and Selector layers.​ By the end you will have a better understanding of how and when to apply these advanced Apex patterns.

If you attended the FinancialForce.com DevTalk in June this year, you will have got a sneak peak of some of the improvements being made to the supporting library for the patterns available in this repo. If you didn’t you’ll have to wait till Dreamforce! Oh go on then, i’ll give you a teaser here…

  • Introduction
  • Selector Enhancements, FieldSet and QueryFactory Support
  • Application Factory Introduction
  • Using Apex Interfaces to implement Common Service Layer Functionality
  • Introducing ApexMocks
  • Using ApexMocks with Service, Selector and Domain Layers
  • Field Level Security Experiment
  • Q&A 

I’m quite excited about all this content, but perhaps if pushed, i’d have to highlight the new Application Factory concept along with the integration with the exciting new ApexMocks library (also from FinancialForce.com R&D). This brings with it easier support for implementing polymorphic use cases in your application and the ability to mock layers of the patterns, such as Unit Of Work, Domain, Selector and Service layers. Allowing to develop true unit tests that are fast to execute by the platform and plentiful in terms of the variation of tests you’ll be able to develop without fear of extending the time your sat waiting for tests to execute!

Its is against my nature to publish a blog without a code sample in it, so i’ll leave you to ponder the following….

	public void applyDiscounts(Set<ID> opportunityIds, Decimal discountPercentage)
	{
		// Create unit of work to capture work and commit it under one transaction
	    fflib_ISObjectUnitOfWork uow = Application.UnitOfWork.newInstance();

		// Query Opportunities
		List<Opportunity> oppRecords =
			OpportunitiesSelector.newInstance().selectByIdWithProducts(opportunityIds);

		// Apply discount via Opportunties domain class behaviour
		IOpportunities opps = Opportunities.newInstance(oppRecords);
		opps.applyDiscount(discountPercentage, uow);

		// Commit updates to opportunities
		uow.commitWork();
	}

Here is a more generic service layer example, leveraging polymorphic Domain classes!

	public void generate(Set<Id> sourceRecordIds)
	{
		// Create unit of work to capture work and commit it under one transaction
		fflib_ISObjectUnitOfWork uow = Application.UnitOfWork.newInstance();

		// Invoicing Factory helps domain classes produce invoices
		InvoicingService.InvoiceFactory invoiceFactory = new InvoicingService.InvoiceFactory(uow);

		// Construct domain class capabile of performing invoicing
		fflib_ISObjectDomain domain =
			Application.Domain.newInstance(
				Application.Selector.selectById(sourceRecordIds));
		if(domain instanceof InvoicingService.ISupportInvoicing)
		{
			// Ask the domain object to generate its invoices
			InvoicingService.ISupportInvoicing invoicing = (InvoicingService.ISupportInvoicing) domain;
			invoicing.generate(invoiceFactory);
			// Commit generated invoices to the database
			uow.commitWork();
			return;
		}

		// Related Domain object does not support the ability to generate invoices
		throw new fflib_Application.ApplicationException('Invalid source object for generating invoices.');
	}

This last example shows how ApexMocks has been integrated into Application Factory concept via the setMock methods. The following is true test of only the service layer logic, by mocking the unit of work, domain and selector layers.

	@IsTest
	private static void callingServiceShouldCallSelectorApplyDiscountInDomainAndCommit()
	{
		// Create mocks
		fflib_ApexMocks mocks = new fflib_ApexMocks();
		fflib_ISObjectUnitOfWork uowMock = new fflib_SObjectMocks.SObjectUnitOfWork(mocks);
		IOpportunities domainMock = new Mocks.Opportunities(mocks);
		IOpportunitiesSelector selectorMock = new Mocks.OpportunitiesSelector(mocks);

		// Given
		mocks.startStubbing();
		List<Opportunity> testOppsList = new List<Opportunity> {
			new Opportunity(
				Id = fflib_IDGenerator.generate(Opportunity.SObjectType),
				Name = 'Test Opportunity',
				StageName = 'Open',
				Amount = 1000,
				CloseDate = System.today()) };
		Set<Id> testOppsSet = new Map<Id, Opportunity>(testOppsList).keySet();
		mocks.when(domainMock.sObjectType()).thenReturn(Opportunity.SObjectType);
		mocks.when(selectorMock.sObjectType()).thenReturn(Opportunity.SObjectType);
		mocks.when(selectorMock.selectByIdWithProducts(testOppsSet)).thenReturn(testOppsList);
		mocks.stopStubbing();
		Decimal discountPercent = 10;
		Application.UnitOfWork.setMock(uowMock);
		Application.Domain.setMock(domainMock);
		Application.Selector.setMock(selectorMock);

		// When
		OpportunitiesService.applyDiscounts(testOppsSet, discountPercent);

		// Then
		((IOpportunitiesSelector)
			mocks.verify(selectorMock)).selectByIdWithProducts(testOppsSet);
		((IOpportunities)
			mocks.verify(domainMock)).applyDiscount(discountPercent, uowMock);
		((fflib_ISObjectUnitOfWork)
			mocks.verify(uowMock, 1)).commitWork();
	}

All these examples will be available in the sample application repo once i’ve completed the prep for the session in a few weeks time.

Sadly the FinancialForce.com session on ApexMocks was not selected for Dreamforce 2014, however not to worry! FinancialForce.com will be hosting a DevTalk event during Dreamforce week where Jesse Altman will be standing in for the library author Paul Hardaker (get well soon Paul!), book your place now!

Finally, if you have been using the patterns for a while and have a question you want to ask in this session, please feel free to drop your idea into the comments box below this blog post!

7 thoughts on “Preview of Advanced Apex Enterprise Patterns Session

  1. Pingback: 35 Rockstar Developers You Should Meet at Dreamforce 2014! | The Salesforce Mobile guy!

  2. Looking forward to your session! Apex SOC and Enterprise Patterns are critical to the success of any moderately complex SFDC Implementation. I am amazed at some of the deliverables I see in SFDC that don’t implement this critical foundation. It should be standard reading material for any developer on the platform in my opinion.

    • Thanks Cory, looking forward to delivering it and catching up with you for sure! Meanwhile yes indeed we continue to shed the light on SOC! 🙂

  3. Pingback: Creating, Assigning and Checking Custom Permissions | Andy in the Cloud

  4. Pingback: Stumbled on another AWESOME Apex blog! - Salesforce coding lessons for the 99%

  5. Pingback: Unit Testing with Apex Enterprise Patterns and ApexMocks – Part 1 | Andy in the Cloud

  6. Thank you for sharing thhis

Leave a comment