# Monday, 14 October 2013

Notes from presentation at the Silicon Valley Developer Users Group on Oct 15th, 2013

Monday, 14 October 2013 14:32:08 (Pacific Daylight Time, UTC-07:00)
# Friday, 06 September 2013

Not to be confused with "rapper" class.

The concept of a "wrapper class" occurs frequently in Force.com development. Object oriented design encourages the use of classes to encapsulate data and behaviors that may mutate the data, or interact with other classes.

The goals of an Apex wrapper class are:

  • Decouple data (records) from behaviors (methods)
  • Validate inputs
  • Minimize side effects
  • Enable unit testing
  • Handle exceptions

This article provides an example wrapper class template to address these goals and explores each aspect of the wrapper class individually.

Register for Dreamforce 13 and attend my session on "Leap: An Apex Development Framework" for training on how to use the Leap framework to generate wrapper classes, triggers, and more. Follow @codewithleap on Twitter for updates on Apex design patterns.

All Apex wrapper classes share a few common properties and methods. To avoid repeatedly cut-n-pasting the same common code into each wrapper class, a base class is created for all wrapper classes to inherit through the "extends" keyword.

public abstract class WrapperClassBase {
     public Id id;  
     public boolean success = true;
     public List<String> errors = new List<String>();
     public boolean hasErrors(){ return errors.size() > 0;}
     public void clearErrors() { success = true; errors.clear();}
}

Now, with a base class available, the simple wrapper class looks like the following:

public with sharing class Order extends WrapperClassBase {
     public Order__c record   = null;
     public static final String SFIELDS = 'Id, Name'; // ... add other fields here
     
     public Order(){}
     
     public Order withSObject(Order__c orderRecord){
          this.record = orderRecord;
          this.id = orderRecord.Id;
          return this;
     }
     
     public Order withId(ID recordId){
          id = recordId;
          String sFieldsToQuery = Order.SFIELDS;
          record = Database.query('SELECT ' + Order.SFIELDS + ' FROM Order__c WHERE Id=:id LIMIT 1');
          return this;
     }
     
     public Order validate(){         
          /*
          Validate fields here. Set this.success = false and populate this.errors.add('err message');
          */
          return this;
     }
     
     public Order doSomething(){
          return this;
     }
     
     private Map<ID,LineItem> m_lineItems = null;
     public Map<Id,LineItem> lineItems{
          get{
               if(m_lineItems == null){
                    m_lineItems = LineItem.fromRecords( this.lineItemRecords );
               }
               return m_lineItems;
          }
     }
     
     private List<OrderLineItem__c> m_lineItemRecords = null;
     public List<OrderLineItem__c> lineItemRecords{
          get{
               if(m_lineItemRecords == null){
                    m_lineItemRecords = Database.query('SELECT ' + LineItem.SFIELDS + ' FROM OrderLineItem__c WHERE Order__c=:id');
               }
               return m_lineItemRecords;
          }
     }
     
     public static Map<ID,Order> fromRecords(List<Order__c> records){
          Map<ID,Order> orders = new Map<ID,Order>();
          for(Order__c o : records){
               orders.put(o.Id, new Order().withSObject(o));
          }
          return orders;
     }
     
     public String toJSON(){
          Map<String, String> r = new Map<String, String>();
          List<String> fieldNames = Order.SFIELDS.split(',');
          for(String fName : fieldNames){
               r.put(fName, String.valueOf( this.record.get(fName) ));
          }
          return JSON.serialize(r);
     }
}

Inheritance

As of this writing, Apex does not allow inheriting the core SObject class (which would be ideal).

Record encapsulation uses the strongly typed Order__c record, rather than the abstractly typed SObject, in order to use the benefits of strongly typed objects in the Force IDE, such as auto-complete of the fields. Moving the record to the base class would require constantly casting SObject to the strong type.

Class Name

For custom objects, it's common to remove the namespace prefix and __c suffix from the wrapper class name. For standard objects, always prefix the class name with "SFDC", or some other naming convention, to avoid conflicts.

Wrapping Standard Objects

Creating wrapper classes with the same name as standard objects, although possible, is discouraged. Class names supersede standard object names, such that if the intent is to create a standard Account object, but a class named 'Account' already exists, the code will not compile because the compiler is trying to create an instance of the wrapper class and not the standard object.

To get around this, use a standard naming convention; SFDCAccount, SFDCContact, or SFDCLead; to differentiate the wrapper class names from their respective standard objects.

Construction

SObjects are constructed in 2 contexts:

  • withSObject(SObject record): The record has already been retrieved via a SOQL statement and the data just needs to be wrapped in a class container.
  • withId(ID recordId): The ID of a record is known, but has not yet been retrieved from the database.
The actual class constructor accepts no arguments. The builder pattern is used to construct the class and kick off a fluent chain of subsequent methods in a single line.

Once constructed, SObject fields are accessed directly through the public 'record' property, as in:

new Order().withID(someid).record.Custom_Field__c

This convention is chosen over creating getCustomField() and setCustomField() properties for brevity and to make use of code auto-complete features,. However, if mutability of the SObject record, or it's fields, are a concern then the public accessor can be modified to 'private' and corresponding get/set properties added.

SFIELDS

Each wrapper class exposes a static public string named SFIELDS for use in selecting all fields for a record. This is equivalent to writing "SELECT * FROM TABLE_NAME" in traditional SQL syntax.

The SFIELDS string can be periodically auto-generated from a Leap task to keep wrapper class field definitions in sync with the data model, or manually updated with just a subset of fields to be used by the wrapper class.

Builder Pattern

The real magic in the wrapper class template is it's ability to chain several methods together in a single line, commonly referred to as the Builder Pattern and discussed in a previous article, Developing Fluent Interfaces With Apex.

Using the Order__c wrapper class example above, the following is possible:

     Order o = new Order().withSObject(objectList.get(0)).doSomething();
     if(o.validate().hasErrors()){
          //handle exceptions
     }

The return types of builder methods must be the same as the wrapper class type. Each builder method returns 'this' to allow method chaining. Builder pattern is useful in the early stages of development when the exact method behaviors and system architecture is not entirely known (see 40-70 Rule to Technical Architecture) and allows a compositional flow to development, incrementally adding new features without significant refactoring effort.

Child Object Relationships

A wrapper class represents a single instance of a Salesforce record. Depending on how lookup relationships are defined, wrapper classes will usually be either a parent (master) or child (detail) of some other records, which also have wrapper classes defined.

The "fromRecords" utility method is provided to easily construct collections of child objects retrieved from SOQL queries. Collections of child wrapper classes are stored as Maps that support the quick lookup of child wrapper classes by their record ID.

Properties and Side Effects

The #1 cause of software entropy in Apex development is unwanted "side effects", which is the dependency on class variables that can be modified by other methods.

The wrapper class template encourages lazy initialization of properties to protect access to member variable. Lazy initialization also avoids repeated queries for the same records, which is a common cause for exceeding governor limits.

Java has not yet evolved to support class properties. But Apex does, and wrapper classes are an opportunity to use them whenever possible. For the sake of brevity, properties are preferred over methods, whenever possible. This Microsoft .NET article on choosing between properties and methods is very applicable to Apex.

For Developers doing a lot of client-side Javascript development in the UI, the use of server-side Apex properties closely approximates the associative array behavior of Javascript objects, and maintains a consistent coding style across code bases.

Unit Testing

Wrapper classes provide a clean interface for unit testing behaviors on objects. The Winter '14 release requires that unit tests be managed in a separate file from the wrapper class. Common convention is to always create a unit test file for each wrapper class with a suffix of 'Tests' in the class name.

Exception Handling

Without a clear exception handling strategy, it can be confusing for Developers to know how a class handles exceptions. Does it consistently bubble up, or catch all exceptions? There is no equivalent to the Java 'throws' keyword in Apex. To remedy this, the wrapper class template base provides a boolean 'success' flag that can be set by any method at any time.

When setting success=false, the exception handling code should also add to the List errors collection, giving an explanation of what went wrong in the transaction. It is the responsibility of calling objects/methods to check for success or hasErrors() after any transaction.

JSON Serialization

Wrapper classes can be serialized to JSON and returned to requesting clients for use in UI binding. The ToJSON() method is provided in the wrapper class template and can be customized to serialize the class.

Friday, 06 September 2013 10:46:42 (Pacific Daylight Time, UTC-07:00)
# Tuesday, 01 January 2013

Note: Apex can now be called from workflows as Invocable Methods using the Process Builder.

Here is a simple hack to call Apex classes from workflow rules.

Problem: Salesforce has a magnificently declarative environment for creating point-and-click applications and workflows, but one area that gets particularly gnarly is executing business rules in response to changes in state.

Given a problem like "When Opportunity stage equals 'Closed-Won', send the order to the back office system for processing", the Business Analyst has a good idea of "when" the business process should be executed. The Developer knows "how" the process should be executed.

The result is often the development of a trigger that includes both the "when" and "how" logic merged into a single class. The trigger ultimately ends up containing code to detect state changes; a task otherwise best left to workflow rule conditions.

Future enhancements to the business rules require the BA to submit a change request to the Developer, impairing the overall agility of the system.

(Some discussions of detecting record state in trigger can be found here, here, and here.)

The Solution: Calling Apex From Outbound Messages
Empower the System Administrator/BA to create workflow rules that call Apex classes in response to declarative conditions.

Create a workflow rule with an outbound message action that calls a message handler (hosted on Heroku), that in turn calls back to a Salesforce REST resource.

Components of the Outbound Message:

  1. The endpoint URL is hosted on Heroku. The outbound message handler receives the message and issues a callback to Salesforce using the path provided after the root URL.
  2. Pass the session ID to the endpoint (Note: the 'User to send as' must have permissions to call and invoke the Apex REST web service)
  3. Pass only the Id of object meeting the workflow condition. This gets passed back to the REST service as an "oid" parameter (object id).

Getting Started:

Download the Heroku outbound message handler from Github (link).

git clone https://github.com/cubiccompass/sfdc-om-workflow
Build the solution and deploy to Heroku.
mvn package
git init
git commit -am "Initial commit"
heroku apps:create omhandler
git push heroku master
Create a workflow rule with an outbound message action that calls the Heroku hosted endpoint.
Create a Salesforce REST resource for handling the callback.

To see the workflow in action, view the Heroku web service logs while updating records in Salesforce that trigger the workflow rule.
heroku logs -tail

Errata:

IWorkflowTask: In the real world, I'm evolving this design pattern to include an IWorkflowTask interface to clearly distinguish which business objects handle workflow actions. The execute() method takes a WorkflowContext object that includes more details from the outbound message.

Daisy Chaining Workflows: It's important that workflow tasks record or modify some state after executing a task in order to allow for triggering follow-up workflow actions. For example, an OrderProcessor workflow task might update an Order__c status field to "Processed". This allows System Administrators to create follow-up workflow rules/actions, such as sending out emails.

Security: Use HTTPS/SSL endpoints to ensure session information is not subject to man in the middle attacks.

Idempotence: Salesforce does not guarantee that each outbound message will be sent only once (although it's mostly consistent with 1:1 messaging). REST resources should be developed to handle the rare instance where a message might be received twice. In the use case above, the code should be designed to defend against submitting the same order twice; possibly by checking a 'Processed' flag on a record before submitting to a back-office system.

Governor Limits: Workflow tasks are called asynchronously, so there's a decent amount of processing and execution freedom using this pattern.

Tuesday, 01 January 2013 11:57:10 (Pacific Standard Time, UTC-08:00)
# Saturday, 15 December 2012

Technical Architects make many tough decisions on a daily basis, often with incomplete information. Colin Powell's 40-70 rule is helpful when facing such situations.

He says that every time you face a tough decision you should have no less than forty percent and no more than seventy percent of the information you need to make the decision. If you make a decision with less than forty percent of the information you need, then you're shooting from the hip and will make too many mistakes.

The second part of the decision making rule is what surprises many leaders. They often think they need more than seventy percent of the information before they can make a decision. But in reality, if you get more than seventy percent of the information you need to make the decision, then the opportunity to add value has usually passed, or the competition has beaten you to the punch. And with today's agile development and continuous integration (CI) methodologies, you can afford to iterate on an architecture with incomplete information.

A key element that supports Powell’s rule is the notion that intuition is what separates great Technical Architects from average ones. Intuition is what allows us to make tough decisions well, but many of us ignore our gut. We want certainty that we are making the right decision, but that's not possible. People who want certainty in their decisions end up missing opportunities, not leading.

Making decisions with only 40%-70% of the information requires responsibly communicating the technical architecture + how changes will be implemented as more information becomes available.

Architecture + Continuous Integration Process = Agility.

Architecture alone is not a sufficient solution and can leave a solution inflexible to change. "Release early and often" is the new mantra in cloud development.

The best way to manage risk as a TA with 40-70% of the information is to constantly ask yourself 2 questions:
1) What is the simplest possible solution to the current problem?
2) How will future changes be implemented?

Within the realm of Salesforce, a Technical Architecture conducive to CI is achieved primarily through 3 design patterns:
* Declarative configuration
* Custom Settings
* Hybrid apps / Web Tabs / Canvas

1) Declarative configuration. First and foremost, it's the obligation of a TA to maximize the point-and-click configuration of any solution. This is done by using as many out of box features as possible.
2) Custom settings: When coding is required, externalizing the behaviors and conditional branches to custom settings gives System Admins and Business Analysts the ability to fine tune a solution as more information becomes available. For example, rather than hardcoding a callout URL in a trigger, move the URL to a custom setting.
3) Hybrid / Web Tabs / Canvas: For ISVs and custom application development, an IFRAME wrapper to an app hosted on Heroku provides the greatest agility to pivot on a solution. Code changes can be pushed several times per day without having to go through the AppExchange package and review process. Matching the look and feel of Salesforce within a Hybrid or canvas app can provide the best of both worlds; a native Salesforce business application with code managed on a separate platform.

Saturday, 15 December 2012 13:44:55 (Pacific Standard Time, UTC-08:00)
# Wednesday, 28 November 2012

I've published an example of a self-documenting REST API to Github (source).

Why a self-documenting REST API?

A typical REST API sample is hosted at http://restdoc-sample.herokuapp.com/hello, using Heroku's embedded Tomcat Java example.

As a Developer, your initial questions may be:

  • "What does the 'hello' endpoint do?"
  • "Does the endpoint support GET, POST, PUT, DELETE?"
  • "What headers and message body payloads does this endpoint support?"

Fortunately, the RESTDoc project has already defined a specification for documenting REST APIs. The intent of RESTDocs is for each endpoint to support the OPTIONS method and return a structured RESTDoc for the particular API endpoint.

Getting back to the Heroku hosted sample, submitting a curl request for the 'hello' endpoint using the OPTIONS method returns the sample RESTDoc below.

curl -X OPTIONS http://restdoc-sample.herokuapp.com/hello

In addition to supporting the OPTIONS method, the github sample also supports appending '/describe' to any API endpoint to view RESTDocs in web browser. Example: http://restdoc-sample.herokuapp.com/hello/describe.

Standardizing on RESTDocs opens up a number of interesting possibilities. Since transitioning away from SOAP, the web development community has lost the ability to auto-generate object proxies for calling web services. Webhook and Enterprise Service Bus (ESB) platforms have lost the ability to auto-discover web service endpoints and their supported messages.

Self-describing REST APIs, using RESTDocs and the OPTIONS method, are a compelling solution for enabling the service oriented enterprise and integrating the cloud.

	{
	  "schemas" : {
	    "http://some.json/msg" : {
	      "type" : "inline",
	      "schema" : {
	        "type" : "object",
	        "properties" : {
	          "id" : {
	            "type" : "string"
	          },
	          "content" : {
	            "type" : "string"
	          }
	        }
	      }
	    }
	  },
	  // Headers can be described at the server level and/or per-method
	  "headers": {
	    "request": {
	      "Authorization": {
	        "description": "This server uses a custom authentication scheme. See http://myapi.com/docs/auth",
	        "required": true
	      }
	    },
	    "response": {
	      "X-RateLimit-Total": {
	        "description": "The number of API calls allowed per-hour"
	      },
	      "X-RateLimit-Remaining": {
	        "description": "Number of requests remaining until next refill"
	      },
	      "X-RateLimit-Reset": {
	        "description": "The time at which X-RateLimit-Remaining will be reset back to X-RateLimit-Total"
	      }
	    }
	  },
	  "resources": [
	    {
	      "id": "HelloMessage",
	      "description": "An example hello message",
	      "path": "/{locale}/{messageId}{?seasonal}", // representing query params with L3 URI templates
	      "params": { // URI parameters descriptions
	        "locale": {
	          "description": "A standard locale string, e.g. \"en_US.utf-8\"",
	          "validations": [ { "type": "match", "pattern": "[a-z]+(_[A-Z]+)?(\\\\.[a-z-]+)?" } ]
	        },
	        "messageId": {
	          "description": "A free-form message string",
	          "validations": [ { "type": "match", "pattern": "[a-z_]+" } ]
	        },
	        "seasonal": {
	          "description": "Whether the message is seasonal.",
	          "validations": [ { "type": "match", "pattern": "^(true|false|yes|no)$" } ]
	        }
	      },
	      "methods": {
	        "PUT": {
	          "description": "Update or create a message",
	          "statusCodes": { "201": "Created" },
	          "accepts": [   // Representations accepted by the method on this resource.
	            { "type": "text/plain" },
	            { "type": "application/json", "schema": "http://some.json/msg" }
	          ],
	          "headers": { // Request headers only, response headers are defined under 'response'
	            "X-User-Token": {
	              "description": "Used to identify the user creating the message"
	            }
	          },
	          "response": { // Response representations this resource/method provides
	            "types": [
	              { "type": "text/plain" },
	              { "type": "application/json", "schema": "http://some.json/msg" },
	            ],
	            "headers": {
	              "Location": {
	                "description": "The URL of the created message"
	              }
	            }
	          },
	          "examples": [
	            {
	              "path": "/en_US/greeting",
	              "body": "Hello, world!"
	            },
	            {
	              "path": "/en_US/greeting",
	              "headers": {"Content-Type": "application/json"},
	              "body": "{\"id\":\"greeting\",\"content\":\"Hello, world!\"}!"
	            }
	          ]
	        },
	        "GET": {
	          "description": "Retrieve a message",
	          "statusCodes": { 
	             "200": "Message retrieved successfully", 
	             "404": "Message not found"
	          }
	        }
	      }
	    },
	    {
	      // This resource has no human-readable documentation, but still provides some info on how to use it.
	      "id": "FallbackLocale",
	      "path": "/fallback/{locale}",
	      "params": {
	        "locale": { 
	          "validations": [ { "type": "match", "pattern": "[a-z]+(_[A-Z]+)?(\\\\.[a-z-]+)?" } ]
	        }
	      },
	      "methods": {
	        "GET": { "statusCodes": { "200": "OK" } },
	        "PUT": { "statusCodes": { "201": "Created" } }
	      }
	    }
	  ]
	}	
Wednesday, 28 November 2012 09:29:03 (Pacific Standard Time, UTC-08:00)
# Tuesday, 13 November 2012

Salesforce recently posted this tantalizing brainteaser question "When do you think Salesforce will reach 1B transactions per day?"

Analyzing the recent numbers from trust.salesforce.com reveals some interesting patterns and trends:

  • Peaks tend to occur most often on a Tuesday
  • Weekend traffic drops to about 1/3rd of weekday activity
  • The average growth between peaks is 0.52% per week
Extrapolating these numbers out reveals that Tuesday, December 18th, 2012 is the highest probability date to hit 1B transactions. But that date is pretty close to the holidays, so it's a tough call.

What is your prediction?

Tuesday, 13 November 2012 22:41:35 (Pacific Standard Time, UTC-08:00)
# Monday, 22 October 2012

I frequently use the FizzBuzz interview question when interviewing Salesforce developer candidates.

The original FizzBuzz interview question goes something like this:

Write a program that prints the numbers from 1 to 100. But for multiples of three print "Fizz" instead of the number and for the multiples of five print "Buzz". For numbers which are multiples of both three and five print "FizzBuzz".

The output from the first 15 numbers should look like this:

1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz

It's a great question because the interviewer can evolve the requirements and take the discussion in many different directions.

A good interview is a lot like auditioning a drummer for a rock band. You want to start off with something easy, then "riff" on an idea to get a sense of the candidates listening skills and ability to create variations on a theme (aka refactoring).

Unfortunately, most interviews have the intimidating premise of pass/fail, so the key to an effective interview is in setting up the question so that the interview candidate understands it is okay to constantly change and revise their answers, and that the interview will be evolving around a central concept; which is FizzBuzz.

The questions below gradually get harder by design, and at some point the candidate may not have an answer. That's okay. As an interviewer, you need to know:

a) How does the candidate respond when asked to do something they don't understand?
b) If we hired this person, what is the correct onboarding and mentoring plan for this candidate to help them be successful?

I'll drop hints during the question setup, using buzzwords like "TDD" (test-driven development), "unit testing", and "object oriented design", hoping the candidate might ask clarifying questions before jumping into code, like "Oh, you want to do TDD. Should I write the unit test first?"

So, on to the code. The fundamental logic for FizzBuzz requires a basic understanding of the modulo operator; which, in all fairness, is not a particularly valuable thing to know on a daily basis, but is often the minimum bar for testing the meets "Computer Science or Related 4 Year Degree" requirement in many job descriptions, since it's universally taught in almost all academic curriculums.

After the first round, the basic logic for FizzBuzz should look something like this:

function doFizzBuzz(){
     for(integer i=1; i <= 100; i++){
          String output = '';
          if( i % 3 == 0 ){
               output += 'Fizz';
          }
          if( i % 5 == 0 ){
               output += 'Buzz';
          }
          if(output == ''){
               output = string.valueOf(i);
          }
          System.debug(output);
     }
}

Some things interviewers will be looking for:

  • Use and understanding of the Modulo operator
  • Efficiency. Is mod calculated twice for each value to meet the compound "FizzBuzz" requirement?
  • Using a 0 based loop index and printing numbers 0-99 instead of 1-100
  • Unclear coding blocks or control flow (confusing use of parentheses or indenting)

Even if the candidate misses one of these points, they can usually get over the hurdle quickly with a bit of coaching.

"So, let's evolve this function into an Apex class."

For experienced Salesforce Developers, you can start gauging familiarity with Apex syntax; but be flexible. More experienced Developers/Architects will probably think faster in pseudo code, and Java Developers (if you're gauging potential to become a Force.com Developer) will want to use their syntax.

Refactoring the basic logic above into an Apex class might look something like this:

public class FizzBuzz {
     public void run(){
          for(integer i=1; i <= 100; i++){
               if(math.mod(i, 3) == 0){
                    System.debug('Fizz');
               }
               if(math.mod(i, 5) == 0){
                    System.debug('Buzz');
               }
               else{
                    System.debug(i);
               }
          }
     }
}

"Okay. How would you test that? Let's write a unit test".

If the candidate is not familiar with Force.com Development, now might be a good opportunity to explain that 75% minimum test coverage is required to deploy code.

A basic unit test should look something like:

     public static testMethod void mainTests(){    
          FizzBuzz fb = new FizzBuzz();
          fb.run();
     }    

The test runner will report 100% unit test coverage by virtue of executing the entire run() method within a testMethod. But is this really aligned with the true spirit and principle of unit testing? Not really.

A more precise follow-up question might be: "How would you Assert the expected output of FizzBuzz?"

In it's current state, FizzBuzz is just emitting strings. Does the candidate attempt to parse and make assertions on the string output?

At this point, it's helpful to start thinking in terms of TDD, or Test Driven Development, and attempt to write a unit test before writing code. One possible solution is the Extract Method design pattern, creating methods for isFizz() and isBuzz(), then test to assert those methods are working correctly.

public class FizzBuzz {    

     private void run(){    
          for(integer i=1; i <= 100; i++){
               String output = '';              
               if( isFizz(i) ){
                    output += 'Fizz';
               }
               if( isBuzz(i) ){
                    output += 'Buzz';
               }
               if(output == ''){
                    output = string.valueOf(i);
               }
               System.debug(output);
          }
     }
   
     static final integer FIZZ_MULTIPLE = 3;
     private boolean isFizz(integer n){
          return ( math.mod(n, FIZZ_MULTIPLE) == 0);
     }

     static final integer BUZZ_MULTIPLE = 5;
     private boolean isBuzz(integer n){
          return ( math.mod(n, BUZZ_MULTIPLE) == 0);
     }

     public static testmethod void fizzTests(){
          FizzBuzz fb = new FizzBuzz();
          System.assertEquals(false, fb.isFizz(1));
          System.assertEquals(false, fb.isFizz(2));
          System.assertEquals(true,  fb.isFizz(3));
          System.assertEquals(false, fb.isFizz(4));
          System.assertEquals(false, fb.isFizz(5));
     }
    
     public static testmethod void buzzTests(){
          FizzBuzz fb = new FizzBuzz();
          System.assertEquals(false, fb.isBuzz(1));
          System.assertEquals(false, fb.isBuzz(2));
          System.assertEquals(false, fb.isBuzz(3));
          System.assertEquals(false, fb.isBuzz(4));
          System.assertEquals(true,  fb.isBuzz(5));
     }   

     public static testmethod void fizzBuzzTests(){
          FizzBuzz fb = new FizzBuzz();
          System.assertEquals(true, fb.isFizz(15));
          System.assertEquals(true, fb.isBuzz(15));
     }
}

This is a considerable improvement, but the test coverage is now only at 40%. The run() method is still leaving some technical debt behind to be refactored.

I may drop the candidate a hint about Model-View-Controller and ask how they might deconstruct this class into it's constituent parts.

There are no DML or objects to access, so effectively there is no Model.

But the run() method is currently overloaded with FizzBuzz logic (controller) and printing the output (view). We can further extract the logic into a List of strings to be rendered in any form by the run() method.

public class FizzBuzz { 

     private void run(){    
          for(String element : this.getFizzBuzzList()){
               system.debug(element);
          }
     }
   
     private List<string> getFizzBuzzList(){
          List<string> fizzBuzzList = new List<string>();
          for(integer i=1; i <= 100; i++){
               string listElement = '';

               if( isFizz(i) ){
                    listElement = 'Fizz';
               }
               if( isBuzz(i) ){
                    listElement += 'Buzz';
               }
               if(listElement == ''){
                    listElement = string.valueOf(i);
               }

               fizzBuzzList.add(listElement);
          }
          return fizzBuzzList;
     }
    
     static final integer FIZZ_MULTIPLE = 3;
     private boolean isFizz(integer n){
          return ( math.mod(n, FIZZ_MULTIPLE) == 0);
     }
    
     static final integer BUZZ_MULTIPLE = 5;
     private boolean isBuzz(integer n){
          return ( math.mod(n, BUZZ_MULTIPLE) == 0);
     }
    
     public static testmethod void fizzTests(){
          FizzBuzz fb = new FizzBuzz();
          System.assertEquals(false, fb.isFizz(1));
          System.assertEquals(true,  fb.isFizz(3));
          System.assertEquals(false, fb.isFizz(5));
     }
    
     public static testmethod void buzzTests(){
          FizzBuzz fb = new FizzBuzz();
          System.assertEquals(false, fb.isBuzz(1));
          System.assertEquals(false, fb.isBuzz(3));
          System.assertEquals(true,  fb.isBuzz(5));
     }
    
     public static testmethod void fizzBuzzTests(){
          FizzBuzz fb = new FizzBuzz();
          System.assertEquals(true, fb.isFizz(15));
          System.assertEquals(true, fb.isBuzz(15));
     }
    
     public static testmethod void fizzBuzzListTests(){
          FizzBuzz fb = new FizzBuzz();
          //0 based offsets.
          System.assertEquals(100, fb.getFizzBuzzList().size() );
          System.assertEquals('1', fb.getFizzBuzzList().get(0) );
          System.assertEquals('Fizz', fb.getFizzBuzzList().get(2) );
          System.assertEquals('4', fb.getFizzBuzzList().get(3) );
          System.assertEquals('Buzz', fb.getFizzBuzzList().get(4) );
          System.assertEquals('FizzBuzz', fb.getFizzBuzzList().get(14) );
          System.assertEquals('FizzBuzz', fb.getFizzBuzzList().get(29) );
     }
}

Test coverage is now at 90% after extracting the run() print logic into a unit testable method that returns a list. The last 10% can be easily covered by calling run() anywhere inside a testMethod.

If there's time remaining in the interview, a good enhancement is to add dynamic ranges. Instead of printing 1-100, modify the class to support any range of numbers. Basically, this is just testing the candidate's ability to manage class constructor arguments.

public class FizzBuzz {    
     private final integer floor;
     private final integer ceiling;    

     public FizzBuzz(){
          floor      = 1;
          ceiling = 100;
     }
    
     public FizzBuzz(integer input_floor, integer input_ceiling){
          floor = input_floor;
          ceiling = input_ceiling;
     }
    
     private void run(){    
          for(String element : this.getFizzBuzzList()){
               system.debug(element);
          }
     }
    
     private List<string> getFizzBuzzList(){
          List<string> fizzBuzzList = new List<string>();
          for(integer i=floor; i <= ceiling; i++){
               string listElement = '';
               if( isFizz(i) ){
                    listElement = 'Fizz';
               }
               if( isBuzz(i) ){
                    listElement += 'Buzz';
               }
               if(listElement == ''){
                    listElement = string.valueOf(i);
               }
               fizzBuzzList.add(listElement);
          }

          return fizzBuzzList;
     }

    
     static final integer FIZZ_MULTIPLE = 3;
     private boolean isFizz(integer n){
          return ( math.mod(n, FIZZ_MULTIPLE) == 0);
     }
     
     static final integer BUZZ_MULTIPLE = 5;
     private boolean isBuzz(integer n){
          return ( math.mod(n, BUZZ_MULTIPLE) == 0);
     }

    
     public static testmethod void fizzTests(){
          FizzBuzz fb = new FizzBuzz();
          System.assertEquals(false, fb.isFizz(1));         
          System.assertEquals(true,  fb.isFizz(3));
          System.assertEquals(false, fb.isFizz(5));
     }
    
     public static testmethod void buzzTests(){
          FizzBuzz fb = new FizzBuzz();
          System.assertEquals(false, fb.isBuzz(1));         
          System.assertEquals(false, fb.isBuzz(3));         
          System.assertEquals(true,  fb.isBuzz(5));
     }
    
     public static testmethod void fizzBuzzTests(){
          FizzBuzz fb = new FizzBuzz();
          System.assertEquals(true, fb.isFizz(15));
          System.assertEquals(true, fb.isBuzz(15));
     }
   
     public static testmethod void fizzBuzzListTests(){
          //Use a 0 based index range to make fetching/testing list offsets easier.
          FizzBuzz fb = new FizzBuzz(0, 100);
          System.assertEquals(101, fb.getFizzBuzzList().size() );
          System.assertEquals('1', fb.getFizzBuzzList().get(1) );
          System.assertEquals('2', fb.getFizzBuzzList().get(2) );
          System.assertEquals('Fizz', fb.getFizzBuzzList().get(3) );
          System.assertEquals('4', fb.getFizzBuzzList().get(4) );
          System.assertEquals('Buzz', fb.getFizzBuzzList().get(5) );
          System.assertEquals('FizzBuzz', fb.getFizzBuzzList().get(15) );
          System.assertEquals('FizzBuzz', fb.getFizzBuzzList().get(30) );
     }
}

I will usually follow-up this question with questions about boundary checking and programmatic validation rules.

"Should FizzBuzz be allowed to accept negative numbers?"

"Should the ceiling value always be greater than the floor?"

If yes to either of these, then how would the candidate implement validation rules and boundary checks? This very quickly gets into writing more methods and more unit tests, but mirrors the reality of day-to-day Force.com development.

Once variables get introduced at class scope, then this is a good opportunity to have discussions about side-effects and immutability.

"What happens 6 months later when another Developer comes along and tries to modify the ceiling or floor variables in new methods?"

"How can you prevent this from happening?"

"What are the benefits of initializing variables only once and declaring them 'final'?"

An experienced Developer will likely have a grasp of functional programming techniques and the long-term benefits of minimizing side-effects and keeping classes immutable.

And finally, these unit tests are all written inline. How would the candidate separate tests from production classes?

For more information about refactoring patterns, check out this list of patterns or read Martin Fowler's brilliant book Refactoring: Improving the Design of Existing Code.

Monday, 22 October 2012 16:53:22 (Pacific Daylight Time, UTC-07:00)
# Monday, 09 July 2012

Heroku supports running non-web Java processes called "workers". Heroku Workers are an economical solution for executing long running processes, such as waiting for events in a messaging queue.

A worker is basically a Java class that sits in a while loop.

public class WorkerProcess 
{
	public static void main(String[] args)
	{
		while(true) {
			try { 
				Thread.sleep(1000);
			} catch(InterruptedException e) {}            
			System.out.println("Worker process woke up");        
		}
	}    
}

The worker process utilizes its dyno (virtual machine) 100%, therefore is billed at the full rate.

For processes that make asynchronous calls and wait for a response, a single threaded worker can be wasteful. The examples below demonstrate how to spawn several threads within a Heroku Java worker.

public class WorkerProcess
{
	public static void main(String[] args)
	{
		final int MAX_THREADS = 100;
		
		for(int i = 0; i < MAX_THREADS; i++){
			WorkerThread t = new WorkerThread (i);
			new Thread(t).start();
		}
	}
}
public class WorkerThread implements Runnable 
{
	final private int thread_id;

	WorkerThread(int n) 
    {    	
		this.thread_id = n; 
    }
    
    public void run() 
    {
    	while(true){
    		try{
    			System.out.println("Thread " + this.thread_id);
    			//Do something here
    		}
    		catch(Exception e){
    			
    		}
    	}
    }
}
This example of 100 threads runs fine on the Heroku cedar stack. At the time of this writing, Heroku worker threads were bound by memory and not a fixed number of threads.

Resources:
Run non-web Java processes on Heroku
Git repository of Heroku demo (replace the demo classes with the code above in this article)
Monday, 09 July 2012 22:20:59 (Pacific Daylight Time, UTC-07:00)
# Sunday, 27 May 2012



The announcement that Facebook intended to acquire Instagram made headlines. While the focus of these headlines primarily centered around the $1B valuation and 50 Million user audience, the true story went largely untold.

Instagram's story marks an inflection point in computing history whereby a start-up embracing cloud infrastructure is no longer the exception, but now considered the rule for building a successful company.

Consider the fundamentals of their meteoric rise over 2 years:
  • 2 people start with an idea
  • Create an iPhone application with hosting on Amazon Web Services (AWS)
  • Distribute the app on Apple's app store
  • Grow an audience
  • Evolve and enhance the product
  • Leverage elastic scalability on AWS
The costs for a v1 product were extraordinarily low and gave them an opportunity to pivot at any point without being grounded by capitalized infrastructure investments (i.e. building their own colo servers and doing their own hosting).

At the time of Instagram's acquisition they had added only 11 more employees, mostly hired in the few months leading up to their acquisition.

Some tips and lessons learned for other start-ups considering embracing the cloud as their development and hosting platform:

Choose a platform and master it: Instagram selected Amazon Web Services, but there are many options available. Don't hedge your bets by designing for platform portability. Dig deep into the capabilities of your chosen platform and exploit them.

Think Ephemeral: Your cloud web servers and storage can disappear at any point. Anticipate and design for this fact. If you have a client server background, then take a step back and grasp the concepts of ephemeral storage and computing before applying old world concepts to the cloud.

Share Knowledge: This is still a new frontier and we're all constantly learning new tips and tricks about how to best utilize cloud computing. Many people at Facebook (including myself) were fans of the Instagram Engineering blog long before the acquisition. Share what you've learned and others will reciprocate.

Build for the long term: The Instagram team did not build a company to be sold. They built a company that could have continued to grow indefinitely, and perhaps even overtaken competing services. There are so many legacy business processes and consumer applications whose growth is restricted by their architecture. Embrace the cloud with the intent to build something enduring and everlasting.

Sunday, 27 May 2012 10:26:04 (Pacific Daylight Time, UTC-07:00)
# Sunday, 30 October 2011

Integrating CRM with ERP/Financial systems can be a challenge. Particularly if the systems are from 2 different vendors, which is often the case when using Salesforce.com CRM.

At Facebook, we've gone through several iterations of integrating Salesforce with Oracle Financials and the team has arrived at a fairly stable and reliable integration process (kudos to Kumar, Suresh, Gopal, Trevor, and Sunil for making this all work).

Here is the basic flow (see diagram below):

1) The point at which Salesforce CRM needs to pass information to Oracle is typically once an Opportunity has been closed/won and an order or contract has been signed.

2) Salesforce is configured to send an outbound message containing the Opportunity ID to an enterprise service bus (ESB) that is configured to listen for specific SOAP messages from Salesforce.

3) The ESB accepts the outbound message (now technically an inbound message on the receiver side) and asserts any needed security policies, such as whitelist trusting the source of the message.

4) This is the interesting part. Because the Salesforce outbound message wizard only allows for the exporting of fields on a single object, the ESB must call back to retrieve additional information about the order; such as the Opportunity line items, Account, and Contacts associated with the Order.

In Enterprise Application Integration (EAI) speak, this is referred to as a Content Enrichment pattern.

5) An apex web service on Salesforce receives the enrichment request, queries all the additional order details, and returns a canonical XML message back to the ESB.

6) The ESB receives the enriched message and begins processing validation and de-duplication rules, then transforms the message into an object that can be consumed by Oracle.

7) The ESB then inserts the Order into Oracle.

8) The Oracle apps API inserts/updates the various physical tables for the order and throws any exceptions.

Sunday, 30 October 2011 17:15:23 (Pacific Standard Time, UTC-08:00)