Showing posts with label learn to code. Show all posts
Showing posts with label learn to code. Show all posts

Friday, November 17, 2017

The Eisenhower Matrix Fallacy

Road trips reveal truths and clarify ideas, at least that's what my Auntie Pat Tern insists. On a recent trip with her and cousin Tim Toady,  this came up when Tim requested a bathroom stop. What he said was, "I could use a bathroom some time soon." And as we flew past exit after exit, Auntie Pat Tern said he should let her know if it becomes urgent, otherwise she wanted to find a good spot to stop for lunch too. That got me thinking about competing interests when it comes to programming and the Fallacy of the Eisenhower Matrix.

Jastrow, J. (1899). Popular Science Monthly US public domain
Duck or Rabbit? It may depend on how long

you allow yourself to analyze the problem.
In a speech at Northwestern University, President Dwight D. Eisenhower said "I have two kinds of problems, the urgent and the important. The urgent are not important, and the important are never urgent. "   


Prioritizing Competing Requirements

Important issues and urgent ones often compete. On our road trip, Auntie Pat Tern knew that a nice place to stop for lunch would also have a nice bathroom, that was part of her selection criteria. She also wanted to get as far as possible to her ultimate goal before the end of the day. Stopping both for lunch and for a separate bathroom pit-stop would delay her from reaching her ultimate goal. So she employed the Eisenhower statement as it was intended, to express that a thing cannot be both urgent and important.

Unfortunately, a lot of people in the business world have worked Eisenhower's statement into a matrix, which suggests that requirements can be both urgent and important.  Trying to accomplish a task as both important and urgent makes no sense. If it is important enough to need an optimal solution, then take the time to discover that optimal solution. If it is urgent enough to resolve immediately, do your best with what you have right now.

Importance means you have the time to be thoughtful and take time to discover the most optimal solution; it is the polar opposite of urgency.

As long as stopping for a bathroom break was important, it was worth waiting for the best location to stop both for food, which was also important, and for clean restrooms. But as soon as the need for a bathroom became urgent, the competing priority for food could be disregarded, at least to some extent. And with greater urgency, even the competing priority for a clean restroom might be set aside; the greatest urgency means you act now even if you have to pull off the road at that tree up ahead.

Eisenhower and Software Architecture 

For software architecture, the urgent and the important need to be kept separate because the important parts of the project should inevitably be the most stable code in the system. The least stable code is the stuff you write out of urgency, when things are likely to change, but we can't wait until we understand all the factors that cause change.

Don't believe the Eisenhower Matrix, it is a fallacy. Important and Urgent are like North and South ends of a magnet. Anything that is equally Important and Urgent lies in the middle, and that part of the magnet is neutral. The neutral zone is where we find the mindless and repetitive tasks that only become urgent when they are neglected for too long and only become important when something out of the ordinary arises.

For Tim Toady on our road trip, he appreciated waiting for a sandwich on Dutch Crunch and a clean restroom because he values good food; it's important as long as he doesn't have more urgent needs.

Sunday, November 12, 2017

Why Coders Use Interfaces

Going on a road trip with Auntie Pat Tern and cousin Tim Toady reveals a lot about them as only a road trip can. Tim was called a "whipper snapper" on more than one occasion for criticizing Auntie Pat Tern's driving. "I cannot wait for self-driving cars," he proclaimed while Auntie Pat Tern praised the freedom of the open road and the control she feels while driving a car. Which got me thinking about why interfaces are so important as part of my programming team's design decisions.

Tim Toady prefers to drive arcade games while Auntie Pat Tern craves a 64 1/2 mustang convertible. But they both drive reasonably well in the electric car they have at home and the gas guzzler we rented for our long drive. That's because the interface of gear shift, accelerator, brake, and steering wheel are universally well understood by users.

Accelerate, brake, steer, and shift.
The simplicity of a good interface.
That same interface translates inputs to a multitude of different systems from arcade games to tractor-trailer trucks. When it comes to deciding whether to accelerate or decelerate, the driver/user does not care if the vehicle is electric or gas-powered. A lot of people who drive electric cars even still say "gas pedal".

Autonomous driving vehicles use the same interface as people: shift, accelerate, brake, steer. By using the same interface, a person can take over in an emergency, or maybe just for the fun of driving.

Developers use good interfaces like this to future-proof their code. If the business rules are protected from the mechanism for inputting data thanks to a reliable interface, we can make sure the most important business rules continue to function as expected.

Sure, sometimes the interface has to change a bit with new business automations. When cars got automatic transmissions, the gear shift changed and we lost the clutch. The same happens with code, new automations require small changes to the programming interface, but the goal of an interface is to minimize the need for such changes. Ultimately, we want to put interfaces between systems to give ourselves flexibility to support new automation, like Tim Toady's self driving car, as easily as we support more manual systems, like Auntie Pat Tern's stick shift.

Saturday, June 11, 2016

More Better Bots

You know Auntie Pat Tern loves Jeopardy!, the tv show with all the answers, but we have an old friend named Eliza who believes we can find all the answers we need by asking ourselves the right questions.  My developers have been asking some of the right questions since their recent trip to the TrailheaDX conference (a conference for Salesforce Developers, similar to past conferences in 2007 and 2010).

First of all, the developers asked what we should do about all of our existing Visualforce pages now that users are craving Lightning Experience.  "What can we do to give them that look and feel without a wholesale rewrite of our UI?" they asked.  Their questions naturally led them to the answer that we should start simply with applying the Lightning Design System to what we have in Visualforce, as a first step.

Next, the developers asked what was going on with Salesforce and AI.  "What's the deal with bots?" they wondered.  While they mulled this over, I reached out to Eliza to see what she had to say:
> Hello. My name is Eliza.  How may I help you?
* Eliza, what's the difference between AI and machine learning?
> Ahh.  Please continue...
* Really, I have three issues: Artificial Intelligence, Machine Learning and Natural Language Processing.
> What does that suggest to you?
* Like Steve Wozniak said at TrailheaDX, Artificial Intelligence is nothing without Machine Learning.  Natural Language Processing benefits from the ability to learn better responses.
> I'm not sure I understand you fully.
* Well, GA Tech has done some cool stuff with bots.  One learned to answer frequently asked questions for students.
> Can you elaborate on that?
* For a class that prompted over 10,000 online questions per semester, the professor used Machine Learning and trained a bot using questions and answers from previous semesters.  The bot was set to respond to those familiar, frequently asked questions and to only respond to new questions if it calculated a 97 percent or higher confidence level for its answer.
> What does that suggest to you?
* It suggests that I can blend Natural Language Processing and Machine Learning to provide automated, interactive responses to FAQs.
> Say, do you have any psychological problems?
* Um, I do sometimes chat with bots.
Having a bot that can help customer service agents provide the best responses to Cases would help our service team reply quickly and consistently.  We also might want a bot to help provide strategies for the sales team, following the department's best practices. Bots, with the ability to learn from our org's data and best practices can also help us guide new employees and reduce their frustration.

Auntie Pat Tern doesn't really like the term "Artificial Intelligence" because she believes that using code to process our human questions and requests is genuine intelligence.  And our old friend Eliza is curious to know how you feel about that.

Tuesday, May 17, 2016

SeeAllData = Fail

According to Auntie Pat Tern, it takes 21 days to break a bad habit, but Salesforce developers have had about that many API versions to break the bad habit of writing unit tests with "SeeAllData=true".

In most cases, this clause alone can render tests completely useless. Unit tests should prove that code functions according to specifications by asserting proper database manipulations--create, read, update, delete operations--as well as Visualforce navigation.

I looked at unit tests in my org and found this example of a test that failed to achieve its purpose:

This test should be asserting that the data for ordering samples can be created with just a contact and sample type defined.  Unfortunately the test relies on existing, live, org data rather than test 'silo' data because of "SeeAllData=true" in the first line. There are easy methods for unit tests to create their own test data without relying on live org data.

We encountered the following problems because of using "SeeAllData=true":
  • It required us to maintain test data among our real data.
  • When the test data was changed during data cleanup (in one case, Pat Tern's Account was deleted), the tests failed even though functionality was unchanged.
  • Tests were not reliable between Sandboxes and Production orgs due to data differences rather than actual functionality.
  • Apex Hammer Tests may not have been automatically monitored in our org for each Salesforce release since Hammer Tests are blind to live org data.
In the rare case where a specific piece of data may be required for your code to behave, consider using custom metadata types instead of Salesforce objects. Trailhead can help you learn more about how they allow you to move metadata and records between orgs and test functionality without needing to see all data in the org.

Saturday, May 7, 2016

Pay Down That Technical Debt

Auntie Pat Tern says we should pay with cash, or at least pay our credit cards off every month because "debt," she says, "is like fresh fish, it seems great at first but gets old fast and then it really stinks."

It's Hammer Time!
So I looked at my Salesforce org to assess the level of technical debt we had accrued and to plan how we would start paying down that debt.

Sometimes technical debt comprises the shortcuts or mistakes that no one has time to correct when a project needs to be completed. Technical debt also develops over time.  As businesses mature and change, their technical solutions can fall behind and create technical debt.

A Salesforce org can be especially prone to this since Salesforce offers a wealth of new features for all orgs three times each year and not all companies make an effort to rewrite their technical solutions based on these new features. Luckily, Salesforce offers some tools to help us assess some of the technical debt associated with our code.

First, I checked our Hammer Test Status.  The data silo gauge revealed that we still had old (and sadly a few new) unit tests that were using "seealldata=true", which we needed to update.  It also revealed a couple of tests that were failing and so needed some attention.

Next I checked the API version on our Apex Classes.  Any class that is 10 or more versions behind the current API version needed a review, both on the code side and on the process side.

The third step for me was reviewing our org's documentation for outdated information on our code.

My org review also included configuration, managed packages and basic processes, as well.

We may not be able to pay down all of our technical debt right away, but a monthly review and reminder of how it accumulates will help us develop better in the future.  And as Auntie Pat Tern says, "It's not just pay me now or pay me later, you know.  It's pay me now or pay me later with additional compounded interest!"

Sunday, April 10, 2016

Putting Governor Limits To The Test

My Auntie Pat Tern is pretty accepting of cousin Tim Toady's behavior. "He's a teenager, after all, there's no better time for him to test his limits," she explained. So I decided to ask my developers to test their limits in Salesforce.

One Master object with 13 Detail objects, 
some of which are Masters in other relationships as well.
I wanted them to see for themselves how governor limits benefit the overall performance of the code they write. And I wanted them to experiment with ways to push those limits by trying to break things.

They built Processes, wrote triggers, and configured some unwieldy objects that I would never want to see in production all in an effort to push good performance to the very edge of being bad.

Some limits include object relationships.
A couple of these experiments proved that what they understood about limits was untrue. In one example, when it comes to Master-Detail relationships on custom objects, the documentation described a limit of 2^3. Firstly, 2^3 does not equal 8 here. Instead, it indicates that an object can have two M-D relationships and those can be three levels deep.

Take the example Parent <-- Child <-- GrandChild <-- GreatGrandChild where all relationships are Master <-- Detail. Some of the limits on this relationship structure are as follows:

  • Parent cannot have a new Master (eg GrandParent) because of the limit on how deep the relationship levels can be. 
  • GreatGrandChild does not show up as available to be a Master in other relationships because we are limited to three levels deep.
  • Child cannot have a new Master because it already has two M <-- D relationships (even though only one of those points to a Master).
  • Child can have new Details, that is, new GrandChild-level objects can be created as Details for Child even though Child already has two M <-- D relationships.
  • Many Child-level objects can be created as Details for Parent (we stopped at over 50). 
  • A Child-level object cannot be used as a junction object between records of a single Parent-level object. M <-- D relationships cannot be immediately self referencing like that.
  • GrandChild-level and GreatGrandChild-level objects can have the same Master object as their Master, eg. GrandChild can point to Child and Parent as Masters even when Child already points to Parent as its Master. We daisy-chained six objects this way before hitting limits on the depth of the relationships.
  • Child-level objects with two relationships pointing to Master objects cannot be Masters to new GrandChild-level objects. An object can have two Masters or it can have one Master and many Detail relationships or it can have no Master and many Detail relationships.

It was a fun exercise and demonstrated how limits benefit performance and how hard some of them can be to break. It gave the developers a chance to challenge their assumptions, be creative and gain a better understanding of the implications of limits when it comes to writing better code.

Secretly, Auntie Pattern believes that testing limits can help us appreciate why limits are important, but she wouldn't tell Tim Toady that.

Friday, March 11, 2016

Static V. Instance, or, How Can A Variable Be Unchanging?

I asked my Auntie Pat Tern why she loves to watch Jeopardy! and she said, "if I watch it enough, I will see answers to all the questions in the world." So I looked through the questions that my developers ask to see if they could be answered by Jeopardy!

One of the questions that comes up frequently is whether use of the 'static' keyword is an antipattern or whether it is best practice. Of course, if it's used wrong, it is an antipattern, so understanding static versus instance methods, variables and initialization code is important.
Final Jeopardy! means there won't be
infinite answers this time.

Taking Jeopardy! as our example, the classic game show that contestants win by providing the most correct responses, we can see that some things don't change from week to week. The show's name, the show's host, these are constants and so of course are static because "static" means unchanging. A static response can be provided for questions about the host and show name.

Every show has three contestants and to create a show, its producers need to know who the three contestants will be. So they conduct tryouts to choose and schedule competitors. The names of the competitors change from night to night, so the list of competitors is variable, but show producers have to know who is scheduled before the show is created, so it is a static variable. A static response can be provided to the question of who will be the competitors for any specified date.

When the show is filmed, the responses that one contestant provides as part of the action of the show are defined by the instance of the show and depend on the inputs the contestant receives from the show and the interactions the contestant has with other contestants on that particular show. So these responses are non-static and depend on the instance of the show.

As an example let's consider three possible questions about the upcoming Jeopardy! college championship round:
  1. Who's the host? We expect one answer: 'Alex Trebek'. 
  2. Who are the competitors? We expect one answer: the three college students, depending on who is chosen for a specified day. 
  3. What is the contestant's 'question' and score for the first input in the first category? The response to this question depends on actually seeing the college championship round in action, knowing what the inputs are and seeing which contestant acts first and the result of that particular action.  
So the first two are static and the last one non-static and specific to its instance.  

In Apex, you can see an example of static vs. instance in the Date class. This class offers both static and instance methods. Let's consider three possible questions we could ask today:
  1. What is the date today? We expect one specific answer for this question and it doesn't need any additional information for us to ask it: Date.today().
  2. Is it a leap year? We expect only one answer for this question, depending on a specified year, for example: Date.isLeapYear(2016); or Date.isLeapYear(2023);.
  3. What is the year? The response depends on knowing the date in question -- we need an instance of Date in order to figure out the year of that specific date, for example: Date yearLater = Date.today().addYears(1); Integer nextYear = yearLater.year();.
Again, the first two are static methods while the third, determining the year, is specific to its instance. You might wonder, for example, what happens in Apex when you add a year to a leap day, will Apex give us February 28 or March 1 of the next year (or null)? You could run the following code to create an instance specific to a leap day and test it out:

The above code primarily uses instance methods, but using the 'static' keyword in Apex can be particularly useful when it comes to writing code called by Triggers. Since a single Trigger can result in a cascade of other Triggers firing, we may need to keep track of some information across all the business process automation associated with the cascade of Triggers. Having a separate class with a static method or variable for all of the Triggers allows us to share specific data across the code executing for multiple Triggers.

For example, a separate class that contains a static variable can indicate the number of times a particular automation has run to help avoid an infinite recursion

Infinite recursions need to be avoided in code, but Auntie Pat Tern may be correct that infinite episodes of Jeopardy! will contain all the answers to all the questions in the world.



Friday, March 4, 2016

Start Documenting Rather Than Accepting "No Comment"

My Auntie Pat Tern tried to convince my cousin Tim Toady that he should be using the 3/5 rule of essay writing he'd been taught -- three ideas, five paragraphs -- but, as usual, Tim insisted there is more than one way to do it (TIMTOWTDI). So I looked through the code in my Salesforce org to see if my developers were following the 3/5 rule for comments or if TIMTOWTDI had gotten into our code.  Unfortunately, I mostly found code with no comments at all.

Code without comments is like a research paper without a thesis statement to detail its purpose.  It's like doing something over and over without understanding why because comments should always clarify why it does what it does.  It's like burying treasure without leaving a proper map because good comments point to valuable resources the code uses or makes available.

Code comments should follow the 3/5 rule of comments:  there are three places where comments should occur and five specific topics that need to be addressed.

The three places where comments should be found in Apex code are:
  1. Block comments at the beginning of classes.
  2. Block comments at the beginning of methods.
  3. Line level comments for constants, loops, conditions, and where clarification is possible.
The five topics that should always be found in block comments are:
  1. Description of purpose and assumptions.
  2. Author/date for creation and modification.
  3. Parameters for methods that accept values, or none.
  4. Return values for methods that pass values, or none.
  5. References and dependencies.
Here's an example of code that follows the 3/5 rule of comments:



In this example, block comments appear at the start of the class and at the start of the methods while inline comments appear within methods and for named constants. The comments use Javadoc tags like "@description" to make the important topics easy to locate.  These comments even include "TBD" to indicate code that is incomplete and point out the limitation imposed by the choice of Integer as a data type rather than Long. Comments should always include information that may be reconsidered during the next phase of development.

We ask that developers and admins both be responsible for code comments because the admin should know how code effects data integrity and user experience.  Without that level of cooperation and understanding, admins have been known to implement validation rules that cause code to fail and developers have been known to implement code that causes user experience to decline.

Tim Toady is right, there is more than one way to do it with code.  That's why we ask for comments that explain why the code was written the way it was.  And we follow Auntie Pat Tern's 3/5 rule to make sure we have comments in three areas of code and covering 5 required topics.  Better comments lead to better collaboration and easier maintenance of the code and the org where it runs.

Wednesday, February 24, 2016

Using Trailhead To Resolve Unknown Unknowns

According to my Auntie Pat Tern, the only trouble with my cousin Tim Toady is that "like every teenager, he don't know what he don't know.  And that wouldn't be so bad if his teachers were better at knowing what he don't know."  So I took a look at the code in my org to see if I could pinpoint what it is that the developers don't know.

Luckily, the Trailhead team is great at foreseeing what it is that people don't know about Salesforce and have created a Trail for that, no matter what that is.  And while the developers might find the Apex trails on their own, they might not recognize that there is more about Salesforce they need to understand.  In fact, there is an entire Trail on the Salesforce Advantage, the core technology that differentiates Salesforce from other CRM systems and other development platforms.

Learn, or review, Salesforce Technology Basics
with the new Trailhead module.
One developer expressed concerns about "the Governor's limits", which indicates to me that they need to better understand multitenancy and performance.  Another expressed concern about Salesforce firewalls and security breaches, which indicates they need to learn about Salesforce security standards.  A third developer suggested we build custom objects for storing employee contact data and build content management and customer service solutions from scratch, which meant they need to learn more about fast app development with Salesforce customizations and third-party apps.

Happily, Salesforce has a new Trailhead module to help my group know more about all these topics, Salesforce Technology Basics.  Of course my developers are a lot like my cousin Tim Toady, they know they are a smart bunch but they often don't realize that there are things they don't know.  It's the Dunning-Kruger Effect, the unknown unknowns.

For those who are deeply familiar with Salesforce, Trailhead can help you avoid the "curse of knowledge" tendency to believe that if you know it then most people must know it as well.  Trailhead modules are thorough, starting with the basics and moving to more challenging information.  And they are entertaining, so anyone with a smattering of knowledge will find familiar topics fun to review and new topics informative.

With Trailhead, you can avoid the problem Auntie Pat Tern described for cousin Tim Toady, the unknown unknowns as well as the curse of knowledge.  Just encourage your team to earn Trailhead badges, which you can review in their Salesforce Community Profile pages, to bring the team up to speed even when you, or they, think they know what they need to know already.

Sunday, February 21, 2016

Code Smell Leads To Improved Interprocess Communications

My Auntie Pat Tern said she always knows when her teenage kids have guests over and her friend wondered how.  Is it the noise, the mess, the smell? "No," said Auntie Pat Tern, "I just ask them and they tell me."  So I thought I would look through the code in my org and pass this straight-forward idea for communication on to my developers.

When code review uncovers a lot of small problems, this can often bring larger problems to the surface. "Code Smell" refers to small problems that may reveal bigger concerns in code. I previously gave an example of code that uses a 'poltergeist' object to pass data from an external system into a custom Salesforce object before creating the data in the required Salesforce object.  The same code also uses 'hard coded' values that are not named constants.  And that "Code Smell" reveals the use of a database field for interprocess communications, setting a field value to 'success' when the record is created rather than relying on more direct means of communication.


Using the Apex Database class, as shown in the second code block, provides a direct means of communication that would make Auntie Pat Tern proud.

Sunday, February 14, 2016

Poltergeist Busters Get A Call

Auntie Pat Tern mentioned that she loves a good ghost story, so I looked through my code and told her about the Poltergeist object I found there.

Poltergeist objects exist simply for the purpose of passing data from one place to another and are essentially useless.  These objects don't serve a clear function relative to business or technology rules, instead they just take up space.  Poltergeists are unlike Leads, which are required by business rules to hold data until it can be verified and converted to Contacts.  Leads aren't Poltergeists because they service the business rules related to data verification.

The object I found in my code was no Lead, it was a troublesome Poltergeist.
In the above code, the Order object serves no purpose other than passing data from an external system into Salesforce.  Since there is no verification process defined, there doesn't need to be a holding bin for data, and it could be passed directly into the Sales Order object that already existed in our Salesforce org. We can simply refactor the code to write directly to the third-party object rather than the Poltergeist.

Auntie Pat Tern said she's seen a lot of weird stuff, but the code in my org might be the scariest of all.

Thursday, February 11, 2016

When To Soft Code Or Not To Soft Code

My Auntie Pat Tern got mad at my no good cousin when he told her he changes phone numbers every time he gets a new burner phone; she warned us to make sure we do business by the rules.  So I looked through my code and shared her suggestion with my developers.

It turns out they tried to correct a problem with badly implemented hard-coded values by soft-coding some values that represented software architecture decisions and similar business rules.

Previously, I showed you the example of a hard-coded username being assigned as record owner, which caused two problems in the org.  The first problem was that the username needed to be an API-only user rather than an employee who might leave the company whose username would be deactivated.  The second problem was that the username was hard-coded deep in the code rather than being represented as a constant at the beginning of the class.

The developer who tried to fix these problems decided to soft-code the username as follows:

Using Custom Settings allows the username to be changed outside of code at any time, multiple times.  The above example does not solve the first problem we had, though. Unfortunately, soft-coding the username defeats our business rule requiring data coming from integrations to be owned by a user or Queue specific to that integration.  In other words, our business rule required the use of a constant rather than a soft-coded value.

We had to take that code back to the drawing board one more time because, like Auntie Pat Tern demonstrates, code should behave according to the rules of business, and enforce those rules automatically.


Monday, February 1, 2016

Avoiding the Negative for Clear Code

My Auntie Pat Tern recently reminded me to avoid double negatives and use positive language as often as possible. So I looked through some of the code in my org and decided to share her advice with my developers. When we write conditional statements using NOT (or "!"), we are using negative syntax which is more difficult to understand than positive syntax. Here's an example written in negative syntax, then rewritten in positive syntax:

The conditions evaluate the same, but I find the negative syntax more difficult to read during code review and maintenance. Note that it can be improved upon further with a basic knowledge of String methods.

The first time I encountered super negative syntax, I thought the developers who used it were making a game of being abstruse.  But knowing that the two programmers were friends led me to discover that this was in fact a case of "cargo cult programming" where they were sharing and reusing a bad pattern because they hadn't taken the time to pick apart what the code needed to accomplish. Once they better understood what the code was doing, they learned to write it more clearly.

Tuesday, July 14, 2015

Agree on Guidelines Before Adding Code

Remember how your high school and college research papers were graded partly on niggling formatting concerns?  The point was to make sure we all used ibid, idem, op. cit. and loc. cit. correctly.  By getting us all following the same style, the teacher had an easier job understanding our work and we learned to better understand the work of others.  These are the same reason you should define code guidelines for your Salesforce org.
A good style guide provides grounding
without weighing you down.

Whether you are a Salesforce Administrator who works with vendors for your development needs or an in-house developer yourself, documenting basic code style and guidelines for your org should be considered a must.  Code guidelines help ensure that the code can be maintained for years to come and that the org is well documented down to the code level so that admins and developers alike have a thorough understanding of what takes place in the org.

A lot of Apex programmers start with the Google Java Style Guide, which is a great starting point, but you may want to create something brief to share among everyone writing code for your org.  Here are some suggestions for a brief Apex Style Guide:

Style

  1. Avoid unnecessary whitespace.  Whitespace is helpful for indicated blocks of code, using indentations at the beginnings of lines or blank lines before methods, for example.  But whitespace inside of lines of code adds to maintenance time.
  2. Use tab rather than spaces for indenting lines of code to ensure they line up properly and reduce character count.  Indent lines of code within a method by one level from the method.  Indent the code contained by a loop by one level from the line that sets up the loop, for example.
  3. Limit code to 100 columns wide, even in comments so that it can be read without scrolling.
  4. Break SOQL statements into multiple lines with new lines for each clause: From, Where, Order By, etc.  Selected fields should be listed in ascending alphabetical order.

  5.   Map<id,account> aMap = new Map<id,account>([SELECT Id,Name 
                                                  FROM Account 
                                                  LIMIT 50000]);

  6. Comments should appear at the beginning of every class and at the beginning of every method in block format (/* */).  
  7. At the beginning of each class, comments should
    • describe purpose and list related files (classes, triggers, components, VF pages, etc either called by or that will be calling this file) as well as HTTP services called, if any
    • list author name(s) and creation date
    • include modification dates and authors and purpose of modifications
    • list business processes in order they are addressed in the code as a brief summary of methods.
  8. At the beginning of each method, comments should
    • Describe purpose and detail parameters and returned values.
  9. Trigger logic should be contained in at least two files: the Trigger and the Handler(s) containing the business logic.
  10. All code should be ‘bulkified’ to avoid exceeding governor limits when multiple records are processed, at the very least, SOQL and DML statements should only appear outside of loops.

Naming Conventions

  1. File names should begin with a Primary sObject name, followed by a description of the action the code performs, followed by the type of class (eg. Controller, Extension, Helper, Utility, Test, Trigger).  For example, you might have the AccountAddressUpdate Visualforce page and the AccountAddressUpdateExtension controller extension.
  2. Avoid spaces and underscores in file, class, method and variable names.  Also avoid abbreviations when possible.  
  3. Method names begin with a lowercase verb.
  4. Classes should use camel case (eg. CamelCase) while Methods and Variables should use nerd case (eg. modifiedCamelCase).  You could have a controller extension class called AccountAddressUpdateExtension with method updateAddress and variable newStreet, as an example.
  5. Use all caps for constants such as MAXIMUM and MINIMUM.  Constants should be placed after the class header comments and before the first method and method header comments so they can be easily located and updated.
  6. Append “Test” to the class name for all test classes.  For example, the class AccountAddressUpdateExtension would have a corresponding AccountAddressUpdateExtensionTest. 
  7. Collection variables should be plural or otherwise represent the fact that they represent a collection (eg. recordMap, newAccountMap).

Deployment

  1. Remove System.debug statements before pushing code to production.
  2. Require positive and negative scenarios in unit tests using assertions that are clear. 
  3. Salesforce defines minimum code coverage as 75% but we prefer minimum code coverage of 90%.

Fundamentals

  1. For integrations, employ a 'single source of truth' model where possible—data should be stored in one location and referenced by other systems or pulled on an as needed basis only. A redundant system should be created for backup purposes, but should not be used as a data source except in the event of failure recovery. 
  2. Follow the rule of 3 and the abstraction principle. If the same code is used 3 or more times, it needs to be implemented as a reusable class, method or loop. Programmers sometimes refer to this as DRY v WET : "Don’t Repeat Yourself" vs "We Enjoy Typing"). Create abstract code for reusable procedures.

Friday, December 5, 2014

Get Ready Glossary for Administrators Learning to Code

If you are and administrator learning to code, you already know more than you may realize.  I've started preparing a glossary to help you with programming terms by giving you similar examples from your daily tasks as a Salesforce Administrator.

Database customization and coding, it's all connected.
  • Data Types:  When you create custom fields, you have to specify a data type: Date, Text, Currency, Number, etc.
  • Polymorphism:  When you use "+" in a formula for two text fields, it concatenates, when you use it in a formula with two number fields it adds them.  This different behavior in different scenarios is polymorphism at work.
  • Variables:  Fields that let users input values are variables.  They can be changed if needed, just look for the label you gave and edit the data.
  • Constants:  Your org ID is a great example of a constant.  It's a value that will not change in your org.
  • Objects:  Okay, this is confusing.  When you start programming, you will see that Salesforce objects are now referred to as SObjects.  This is because object oriented programming languages use the term Objects to represent data collections.  Oh, hey, that's what objects are in Salesforce too, basically.  Only oop objects can also have actions related to them, things that you can do to them or things that they can do to other objects.  Oh, hey, sObjects are the same if you think about workflows as actions that are related to specific objects and think of triggers as actions that let one sObject act on another sObject.  So maybe this isn't confusing at all.
  • Array:  In the Salesforce database, you have a record ID associated with a bunch of fields -- record name, created date, etc.  This is essentially an array of data. Apex uses the term List rather than Array, but they are the same.  Lists can be multidimensional too.  For example, you can have a list of data from fields for a single contact record, or you can have multiple records in a list and each of those records will have its own list of field values.  List Views are two dimensional lists of data.
  • Cast:  In programming, you can force a variable of a particular data type to be treated like a different data type.  Similarly, in Salesforce, you can use Formulas like Text(PicklistSelection__c) to force a field, in this case a pick list, to be treated like a different type of data, in this case Text.
  • Model-View-Controller:  This is easy for you.  Model is the data model.  When you create custom objects and fields in Salesforce, you are changing the data model, native objects and fields are also part of the data model.  View is the user interface.  When you edit page layouts, you are changing the view.  Controller is any automation.  You might add workflow rules or formulas to affect data based on rules and reasons you define.
  • Boolean data: Think of a checkboxes.  They are true or false, checked or unchecked.
  • Boolean Operators: And, Or.   You may be using these in formulas or in list view filters already.  If you look for this value AND that value, both must be true.  If you look for this value OR that value, only one of them needs to be true, but both true will work as well.
  • SOQL: SObject Query Language lets you express in a few words the kinds of information you already use defining List Views.  For a List View, you sepcify filter criteria for selecting specified fields from the given object.  You might select First and Last Name from Contact with filters looking for records where the phone number is blank, for example.  SOQL lets you express the same sort of thing when programming in Apex, using a few key words.

If you want to write code for Salesforce, Visualforce will handle the View portion, Apex will handle the Controller portion, and Salesforce will continue to handle the Model portion of your program.  You will probably find yourself using data types you are very familiar with from Salesforce fields as you set up variables and constants.  And you will find SOQL easier to understand if you think of them in the context of list views, returning lists or arrays of data you request.

For a more complete introduction to programming for the administrator, please watch this Dreamforce session on coding for non-developers: http://dreamforce.vidyard.com/watch/haqgdyryAtDoQdMsOieTTA