There is plenty of content out there about the best practices and principles that should be followed when developing Apex or Lightning code, most of those practices are general software engineering practices that people new to the platform but that come with experience from other programming languages can relate to. The problem this article tries to address is the lack of these practices and principles being applied when developing more simple things through point-and-click features. This is an issue I have come across quite consistently over the years which over time has a high negative impact on the maintainability of an org.
The audience I am writing to is, admins at the beginner or intermediate level but also developers who do not usually follow these practices and principles when not writing code.
The usage of a naming convention for API names in custom objects, fields, email templates and many other non code features is particularly beneficial in mid to high level complexity orgs where more than two apps live, especially if these apps belong to different business areas with different development and product teams. The naming is usually derived from a prefix which represents the app they component belongs to. For example, a CLM app could have the prefix CLM for its components. Teams can decide what is the exact logic behind the prefix, what matters is that this is logic is used consistently.
The main benefit of using a naming convention is that reduces the effort to understand an org’s configuration. This is extremely valuable to new team members that need to do changes and that without having this in place would have to resort to reverse engineering, asking several people or simply risking breaking things.
Let’s get to the point here, the description section for objects, fields, email templates, and other core features is not there for decoration or because the team designing these pages needed to fill the space in the page... All joking aside, it is very rare to see developers who actually spend time filling this out, because in their mind, the purpose of the component should be obvious. But think about what happens when 5 years later someone with no involvement in the project, or without much background information is asked to do a change on a strangely named field which seems to be filled out only in rare scenarios, or understand why notifications are being sent using a very similar template that has almost the same name and no description, wouldn’t be nice if the description explained the purpose of them?
An even more valuable place to leave comments is validation rules. Many are unaware that you can actually leave comments on validation rules just as you can within code, needless to say, this would be very appreciated by the new dev who has to change a validation rule with multiple level of nested IF statements and obscure conditions.
This is really about highlighting the general importance of the previous two points and the idea behind them. Nobody should have to make a lot of effort to understand an org’s configuration. It should be easy for someone opening a flow, workflow rule, validation rule, etc, to understand the purpose of it, and how it is connected to the rest of the application. As quick and easy as it is to create solutions through clicks also imagine your boss is standing behind you when you do it, name it properly, make it easy for the next person, make it easy for you in 3 years, do it clean and elegantly.
Just as making an application very readable requires adopting a mindset, reusability beyond code also requires adopting this in your development mindset, often thinking of a way to create abstractions. Reusability is a lot about avoiding duplication of efforts to optimize cost and quality because duplication not only leads to higher cost but it also has a detrimental effect on quality as it increases the chance of breaking things.
You may be wondering right now, what are some places where you can apply reusability if is not apex code. I will give you a few examples of moments where you can question yourself if there is an opportunity for abstraction and reusability:
- When you find yourself developing a flow that does almost the same as another flow, ask yourself, can I change the existing flow slightly to branch out a condition specific to my requirement? Or can I move the duplicate section of the flow to a subflow and re-use it from several flows?
- Can I give a more reusable name to a field that has the potential to be used by a different processes instead of making it super specific to a rare use case?
- Do I really need to create a separate record type for this process? Isn’t this process exactly the same but with a slightly different page layout?. You could use dynamic forms.
Error Handling and Defensive Development
Error handling in declarative features goes into very specific areas, off the top of my head:
- Flows and Fault Paths: Fault paths are seldom used by developers which to me is just a symptom of the common problem I often see, which is, flows are mistakenly treated as simple configuration components rather than as declarative programming which is what they often are, therefore, they are not developed taking limits or failure scenarios into account.
- Some formula functions such as IMAGE with the option to specify alternative texts rather than a broken image but more in general, “else” or error conditions in formulas.
Although, error handling is part of doing defensive programming, the general idea behind defensive programming is that you consider the behavior of the application you are building under unforeseen circumstances. Some questions to ask yourself thinking defensively could be:
- When using a lookup, think about what will happen to your process builder or flow if the lookup were to be empty?
- What would happen to your email template if some of the merge fields were missing, do you want to send an email with missing information?
- Is the field upon which you are developing the base of your automation always required?
- Do I want all my notifications or automations to fire even when an admin is doing a mass update?
As you can see, defensive development is about asking yourself about the WHAT IFs when developing.
YAGNI (You ain’t gonna need it)
If I had got paid every time I heard someone say things like “Let’s add that field, I think we will need in the future”, I would not be writing this and would probably be retired drinking mojitos in some tropical island. But seriously, if you don’t need something in the application which right now would add very little or no value, you need to really think twice or three times before adding it.
Applications change and business evolve quicker than what you think, and that component you thought of adding just in case, most likely won’t be needed in the future and will be sitting there cluttering the page layout or adding unnecessary complexity.
Essentially, if there is no code, then what is the code to be reviewed you may be wondering... Well, you can still share your configuration design with a colleague. Don’t always assume that because you have it clear in your mind or because it works you found the best way to do it.
Leverage the team’s brain power and experience to get feedback on your design. Be open to receive constructive feedback, there may be a better way of doing things that you did not think through, not necessarily because you are not a good developer but maybe because someone in your team already faced that scenario before and has learned about a possible limitation you could face in the future, or they saw an elegant way of doing that in another implementation.
These config reviews are a commitment to deliver quality and not thinking about just getting things done. Furthermore, config reviews are an opportunity not only to learn but to teach, maybe your colleague was not aware that you could achieve this requirement declaratively and he would have done it with code instead.
I will keep it very short here as this could deserve its own article. The takeaway here is, any enterprise level org needs to be able to be built from the source repository. If your team is not doing this, you are doing it wrong. While you may think you are saving time by making changes directly in production, in reality you are just setting the org for failure, introducing quality holes, making the application harder to scale and maintain in the long term. While I can understand how doing source driven development in Salesforce was hard 10 years ago, this is not the case anymore and things have gotten much better, there is simply no excuse for it, it doesn't matter if you are changing an apex class or a formula field.