13

This is more meta to Salesforce than to SFSE, but I'm curious. Do any of you have a rigorous documentation strategy that works well for you?

Throughout my time as a developer, I have never really worked with someone who had a solid, consistent template. I often struggle to come up with one myself.

It seems like a pervasive issue that we undervalue this aspect of our responsibilities. I know I have been frustrated by the lack of documentation on projects I have inherited, and I would love to avoid giving others that feeling, but I'm not sure how.

  • 1
    Are you talking about code comments? Or a larger documentation strategy that has an audience outside the developers themselves? – Nick Cook Aug 2 '16 at 15:25
  • The latter, a broad distribution. – Adrian Larson Aug 2 '16 at 15:25
  • 5
    That's an excellent question. I have written documentation, but I can't say that I have what you'd call a "rigorous strategy" or a "template" that I follow. I've always described what each trigger & helper does, what each error message and/or "error code" means, etc to provide a reference for diagnosing issues that might occur in the future. But I'm usually only working on a portion of a solution/application, not the entire code base. – crmprogdev Aug 2 '16 at 16:52
  • 1
    I find it varies a lot working as a consultant as often it is driven by client's requirements/standards on documentation and I would like to try and get a more standardised approach that I know will work with Salesforce. Really the things I would see as necessary are apart from the custom objects and functionality why particular elements of GA functionality have been used in preference to others. – Dave Humm Aug 4 '16 at 15:42
  • 1
    Something that was just presented at the last KC user group. github.com/xjsender/haoide. basically just pulls down metadata and puts it into a csv. But still would require best practices about filling out description and help fields (cause all devs do that). I like the idea, but can do the same through the metadata API and just parse that xml for what I want for tech docs. – Jesse Milburn Aug 13 '16 at 2:46
7

Some time ago, I stumbled upon ApexDoc, which brings the idea of Doc Blocks from JavaDoc to Apex...kinda. Since then, I've been making a conscious attempt to document more of my code using this format. Being the only full-time dev at my company is making that difficult at times (though perhaps I've found a good goal for my next performance review).

For the benefit of those unaware of Doc Blocks, it's simply a multi-line comment that has annotations such as @description which give a specific piece of information about that thing that you're documenting.

From my admittedly limited knowledge, this seems to have emerged as the de facto documentation standard over the years for the languages that I've used the most (C++, Java, JavaScript, and PHP).

/**
* @description Base class used for creating widgets
*/
public class Foo {
    /**
    * @description Type: String 
    *   Defaults to 'Baz'
    */
    public String bar = 'Baz';

    /**
    * @description Basic getter. Memo-izes the return result of someClass.something() if bar is null.
    * @return A String with special instructions
    */
    public String getBar(){
        if(bar == null){
          bar = someClass.something();
        }
        return bar;
    }
}

ApexDoc is a CLI, Java-based tool that can scan Apex class files for docblocks, and generates static HTML pages from them. I haven't actually run the tool myself, but think of it generating something like the Apex developer docs that Salesforce provides today. I imagine it wouldn't be hard to add as a step in an existing build process with a CI tool like Jenkins.

Even if you don't use the tool to generate the documentation in HTML format, simply using a docblock to give an executive summary of your class/method/whathaveyou should help other devs digest your code.

Beyond that, my only other documentation strategy is to add comments above snippets of code that I've spent a good deal of time on adjusting (for a bugfix, getting a failing test to pass, optimizing, etc...). If not for anyone else, then for me so I can remember (months later) why the hell I needed to structure the code the way I did.

As an example, here's a comment I made above a while loop that is used in a method to add a number of business days to a given date

// The number of business days we add by adding/subtracting x days from tempStartDate/tempEndDate
//  will always be less than or equal to x.
// Thus, we can always add/subtract a number of days equal to target - actual, and never overshoot.
// Simply lather, rinse, repeat until we arrive at our target.

while(numBusinessDays != targetBusinessDays){
    workingDate = workingDate.addDays(targetBusinessDays - numBusinessDays);
    numBusinessDays = this.businessDaysBetween(startDate, workingDate);
}
  • 1
    Yeah I'm a big non-fan of comments, but javasdocs style commenting could be useful with an automated tool. Hmm. – Adrian Larson Aug 4 '16 at 16:35
  • @AdrianLarson Wait, if you aren't a fan of comments, how are you currently documenting your code? Are you compiling it in a single external document? Is everything broken up into separate classes that are 50 lines long, causing the purpose and functionality to be obvious in combination with the class and method names? – Derek F Aug 4 '16 at 16:45
  • 1
    Yes naming is very helpful. I keep my documentation separate from my code. Usually Google Docs but I'm not finding it an easy tool to use for this purpose. I almost feel like it would be better to set up a wiki or something. – Adrian Larson Aug 4 '16 at 16:46
  • 4
    I'm also a big non fan of comments - and I find the Javastyle comments are just a big heap of meaningless boilerplate garbage in most instances. I favour naming my methods and classes well + writing comments only where the naming convention is not enough. – Caspar Harmer Aug 8 '16 at 2:45
  • @CasparHarmer are you talking about not being a fan of doc blocks, or the type of comments I gave above my while loop? I do agree that comments like // Iterate over this list of ints, and make a new sObject each time are useless. The comment above my while loop is an implementation detail though, which I'd really hesitate to put in the public documentation for the method the while loop is contained in. Consumers of my method don't need to know this implementation detail, but people updating the implementation need to understand how it works (lest they break a build). – Derek F Aug 10 '16 at 19:12
  • 1
    Actually, I like the while loop comment - I don't like the Java style doc blocks. They are generally out of date, incorrect, incomplete and unhelpful. SOMETIMES they provide a useful piece of information - generally if something unusual is happening. Because of their unreliability, I still need to read the code - rendering them almost useless. – Caspar Harmer Aug 10 '16 at 20:34
  • 1
    At the risk of sounding elitist, they generally precede poorly written outsourced code. Kind of a red flag if you will. – Caspar Harmer Aug 10 '16 at 20:35
  • 2
    @CasparHarmer To be fair, most of those sound like things that can easily happen no matter which documentation tool/convention you use (docblocks, google docs, wiki, git commit messages, smoke signals, etc...) The documentation is only as good as the person writing it. – Derek F Aug 10 '16 at 22:55
5

Four thoughts here

  1. Use patterns in the code so that there is a consistent approach to structure. For example, the Separation of Concerns pattern which at its core means you have a Selector class, Domain class, and (optional) Service class for each(most) SObject. VF, batch, REST, invocable, etc then leverage the Service class method(s). This helps minimize documentation requirements at least as far as how the code is all put together into a cohesive application. Common utility methods, test factories, and exploitation of custom metadata types for configuration also help.
  2. Where service layer methods are passed more than just a set of ids, use contract-driven development with inner class object(s) representing the fields that must be passed from caller to service (or potentially as a service result). The inner class serves as documentation.
  3. As @DerekF suggested - use internal comments to document why not-obvious-at-first-glance code is the way it is. If multiple use cases to be handled, enumerate via comments the use cases and tie the code back to the use cases with comment annotation.
  4. For overarching documentation, I've exploited whatever the org tends to use for engineering top level documentation. A few years ago, that was wikis, at last org, we used Jive. You want others to be able to find it using the normal tools they are used to using.

I had to smile wryly when I read in OP I know I have been frustrated by the lack of documentation on projects I have inherited -- I'm sure that is only the least of the frustrations you've inherited, including my personal bête noire - code that is not at all indented.

5

This answer is largely in response to various comments made to various answers.

Adrian, I find it interesting that you're a "big non-fan of comments" and yet asked this question. Naming schemes for code, or code patterns in general for that matter, that are intuitive to "you" may not be intuitive me or the next person who inherits your or anyone else's code. It's important to remember that we all come from different backgrounds and life experiences. Some of us are left handed while some of us are right handed. We all view the world from different perspectives and are at different skill levels when it comes to coding.

What each of us views as "logical" or "intuitive" is usually the result of inductive reasoning. They're conclusions we've drawn based on our unique life experiences. They're often what "feels right" or "comfortable" for "us". They represent a "preference". It's similar to why some prefer Windows over a Mac or Linux; Android vs iOS vs (gasp) Blackberry or Windows Mobile. We all have our preferences when it comes to things that "feel intuitive" to us. Until someone explains or teaches a methodology to us, we may not see the logic or reasoning behind it without studying and practicing it. Without having gone through their life experiences, we may never completely understand it or find that it works for us.

I'd personally dislike inheriting code that didn't contain any comments at all. I'd also dislike inheriting code that made me refer to an external document when I wanted to learn something about it while I was looking at it. Code that didn't contain much of the same information about it how worked at appropriate points without having to read the docs would really annoy me.

I'd want any documentation to be available to me for display side-by-side and referenced from within the code while I'm in Eclipse or my editor of choice. When I think of documentation, I think more along the lines of

  • Being able to see the "big picture" of how all the code works together (an ERD or Flowchart for starters).
  • I also think in terms of a security model. Is the code operating internally or externally?
  • Is it with or without sharing and if so, why?
  • Is it operating internal to the org or external, in say a community or sites?
  • In other words: where are the security boundaries?

Like @cropredy, I want to see the separation of concerns.

  • Where are the different service layers that handle selectors and common services without duplicating the same code repeatedly throughout the application with only minor variations?
  • Where are the common utility classes that I expect to see?
  • What does each one do and how is it called? (I'll want to use them in future code)
  • As much as anything, I want to know about custom metadata and custom settings too! Where are they, how are they set, what do they control, what can I do with them and what must I not attempt to do with them?
  • In an app of any size, I expect to see error handlers with error reporting methods of some kind.
  • I want to know what each custom error really means, not just the line the error occurred on or the stack trace.
  • The trap was put there for a reason. What were they expecting to need to trap? Don't make me try to figure that out for myself later when you've already done that.

Those are a few of my thoughts on the discussion that's ensued. If someone is an architect, I expect them to have put thought into these decisions and much much more which they can share in their documentation.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .