So-Called Advent Calendar Day 18 - Fire Drills - You have to slow down to speed up

In the spirit of the holiday season, this is a series of short blog posts covering random things I have learned while doing Salesforce development, one for each day of Advent.

fire hydrant
Rushing into a problem generally doesn't help

We have all been there before. You get the message on Slack, a panicked chat message. The dreaded P0 issue. Something is broken and we have to fix it NOW.

Generally my first instinct is to dive into the code and figure out what’s wrong. Churn out the code, get it tested, merge it into master, and get it pushed to production as soon as possible. Deployments in Salesforce can take up to an hour in some of the orgs I have worked in, so we need to move quickly!

Looking back now, this is almost always the wrong way to react. Before you even touch the code, every one needs to stop and align on the problem. Set up a meeting, either in person or remotely, with everyone that needs to be involved. You may end up inviting individuals that don’t really need to be involved, but given the critical nature of the issue, it’s better to be overcommunicative than under.

Now take the time align everyone on the issue:

  • What is not working properly? How should it be working?
  • How many people are affected? What is the consequence of not fixing the problem?
  • How should we should find the cause of the issue?
  • Who should be working on it?
  • How will we test if we have actually resolved the issue?
  • Have we accounted for all use cases?
  • What are the potential consequences of pushing out this fix?
  • Do we need to do any communication to customers? Both during and after the fix is made?

After it is clear everyone’s role needed to execute, only then should you execute. You have to slow down first and align or you risk making things even worse. And after everything has settled down, you have to do a retro on the issue with everyone involved. Here are a few questions to answer, but it should not be limited to this

  • What caused the issue?
  • Could we have caught this earlier? What improvements do we have to make?
  • Are there any unintended consequences?
  • Was there any fallout from this issue?
  • Are there any actions items moving forward?

And most importantly, take a moment to praise each other for jumping on board. Regardless of how it goes, recognize the hard work involved in resolving these issues. You will undoubtedly make mistakes, but they were the best calls you could make at the time.

As a side lesson - because of the time and resources required to address the issue, before you sound that alarm, ask yourself is this really an emergency?

So-Called Advent Calendar Day 17 - What are you trying to do?

In the spirit of the holiday season, this is a series of short blog posts covering random things I have learned while doing Salesforce development, one for each day of Advent.

collaboration
How you ask about the root problem is just as important as getting to it

When I worked in the industry side, maintaining and implementing a company’s Salesforce instance, I would get a lot of requests directly from end users. They would generally be sales team members, or people in operations. Can you add this field? Can you add a picklist value? Things like that. When I first started my career, I would just do it. After all, it only took a few minutes and look at my turn around time! Quickly I learned that’s how nightmare orgs are created, so in attempt to think more long term I started first asking:

What are you trying to do?

I felt pretty good about this - let’s figure out the root of the problem so we can find a solution that genuinely solves it. But I’m starting to realize that this isn’t very helpful either. It made me too much of a gatekeeper, shutting down their idea that they probably genuinely believe is the right solution (and it may very well be so). A lot of end users would get frustrated, which would inevitably lead to conflict.

I’m starting to realize that the question “What are you trying to do?” is a little derisive, as if to say “You don’t know what you want - stop trying to unclog that toilet with a clothes hanger, use a plunger.”

Instead, I’ve started to ask:

“Can you give me more context?”

By doing that, I am deferring to them for their expertise in the situation. It puts me into more of a learning mindset as a oppose to a “poke holes in their solution” mindset. Because sometimes the plunger is missing and someone’s coming over and there’s no time to go to the store and all you’ve got are a ton of hangers so you figure you might as well try and this totally hasn’t happened to me before.

By asking for context, you come from a place of understanding their situation and it creates the opportunity to really collaborate on a solution.

So-Called Advent Calendar Day 16 - The Composite Pattern in Apex

In the spirit of the holiday season, this is a series of short blog posts covering random things I have learned while doing Salesforce development, one for each day of Advent.

composite pattern UML
source: https://developer.salesforce.com/page/Apex_Design_Patterns_-_Composite

On the 13th advent day we started to talk about building a rules engine in Apex. Before we get into that implementation, a key part of it was using the Composite design pattern to evaluate a logical expression. In summary, the composite pattern is used to represent a group of objects that are treated the same way as a single instance of the same type of object.

For example, consider the logical expression 1 AND 2. As a whole, it can be evaluated to true or false. However, the statement is also two separate statements: the statement 1 and the statement 2, both of which can also be evaluated to true or false. Using the composite pattern, we would be able to capture these statments into objects that can evaluate to true or false.

Salesforce actually has a great article on the topic: https://developer.salesforce.com/page/Apex_Design_Patterns_-_Composite

They even use the example of capturing workflow rule logic! When I found this I thought I didn’t have to write anything new after all and I could just use this code. But later down I read the following:

Note: This article will not cover developing the actual screen or parsing the expression - this article is limited to representing an expression in Apex.

Alright fine, make me do work. Unfortunately the parsing of the expression was what I was really worried about, but at least this gets us half way there in evaluating the parsed expression. Let’s walk through their code sample:

First, there is the Expression interface.

public interface Expression {
    Expression add(Expression expr);
    Expression set(String name, Boolean value);
    Boolean evaluate();
}

Let’s not get too into the details yet, but for now let’s just consider an Expression as something that can be evaluated (i.e. it returns true or false).

In their example, their first implementation of Expression is an abstract class called Composite

public abstract class Composite implements Expression{
    public List<Expression> children {get; private set;} 
    public Composite(){ this.children = new List<Expression>(); }
    public Expression add(Expression expr){
        children.add(expr); return this;
    }
    public Expression set(String name, Boolean value){
        for(Expression expr : children) expr.set(name,value);
        return this;
    }
    public abstract Boolean evaluate();
    public Boolean hasChildren{get{ return !children.isEmpty(); }}
}

You can think of a Composite object as a collection of Expressions, which in this case it captures in the children property. And by evaluating the children objects, the Composite object is itself an Expression that can also be evaluated to true or false.

Let’s look at the extensions of the Composite class to see how this evaluation works:

The AndComposite class has one implemenation of the evaluate method. Basically it iterates over every Expression object in children and if all of them evaluate to true, then it returns true. That fits the description of an “AND” logical statement - all of its parts must evaluate to true in order to be true.

public class AndComposite extends Composite{
    public override Boolean evaluate(){
        for(Expression expr : children) {
            if(!expr.evaluate()) {
              return false;
            }
        }

        return true;
    }
}

The OrComposite class works in a similar fashion, except only ONE of the Expression objects in children needs to evaluate to true. That also fits the description of how an “OR” logical statement works. Only one part of it must evaluate to true in order to be true.

public class OrComposite extends Composite{
    public override Boolean evaluate(){
        for(Expression expr : children) {
            if(expr.evaluate()) {
                return true;
            }
        }
        return false;
    }
}

The last part we need to capture are the most granular logical statements. For example, if 1 AND 2 can be represented by an AndComposite object, we need something to represent the children expressions for the tokens 1 and 2. Here is where the Variable class comes in:

public class Variable implements Expression{
    public String  name  {get;private set;}
    public Boolean value {get;private set;}

    public Variable(String name){ this.name = name; }

    public Expression add(Expression expr){ return this; }

    public Expression set(String name, Boolean value){ 
        if(this.name != null && this.name.equalsIgnoreCase(name)) {
            this.value = value;
        }
        return this; 
    }
    public Boolean evaluate(){ return value; }
}

The Variable object has a name to help us track our it within the Composite as well as value to track its Boolean value. But as you can see, all of these different implementations are Expression objects and as such each of them can evaluate to true or false. We can evaluate a Variable on it’s own or evaluate them together in a Composite. And because Composites evaluate to a single boolean value, they can be combined to create even more complex statements.

For example, let’s say you have the statement (1 AND 2) OR (3 AND 4)

Let’s break this down into it’s parts:

  • (1 AND 2) will evaluate into a single Boolean, which we can call A
  • (3 AND 4) will evaluate into a single Boolean, which we can call B
  • That condenses our statement into a more simple expressions A OR B

You can start to see how breaking it down like this allows you to condense more complex logic.

Now let’s see these classes in action:

First a simple expression: 1 AND 2

Expression expr = new AndComposite();
expr.add(new Variable('1')); //Add a variable with the name `1` to our composite
expr.add(new Variable('2')); //Add a variable with the name `2` to our composite

//the Composite class iterates through all of it's children variables and sets the Boolean value based on its name
expr.set('1', true); 
expr.set('2', false);

System.debug(expr.evaluate()); //false

Now let’s try our more complex statement (1 AND 2) OR (3 AND 4)

//Break down our expression into parts:
Expression exprA = new AndComposite();
expr.add(new Variable('1'));
expr.add(new Variable('2'));

Expression exprB = new AndComposite();
expr.add(new Variable('3'));
expr.add(new Variable('4'));

//Combine those parts
Expression complexExpression = new OrComposite();
complexExpression.add(exprA);
complexExpression.add(exprB);

//The complex composite can still set the children variables directly
complexExpression.set('1', true); 
complexExpression.set('2', false);
complexExpression.set('3', true); 
complexExpression.set('4', true);

System.debug(complexExpression.evaluate()); //true

It can be a lot to wrap your head around, but the beauty of the composite pattern is how it creates an elegant way to simplify representing very complex logic. This sets the stage for our rules engine, and next time we’ll cover how we can use this pattern to help us parse logical statements.