76
Self-documenting Code (lackofimagination.org)
(page 2) 20 comments
sorted by: hot top controversial new old
[-] graycube@lemmy.world 7 points 1 day ago

I would have liked some comments explaining the rules we are trying to enforce or a link to the product requirements for it. Changing the rules requirements is the most likely reason this code will ever be looked at again. The easier you can make it for someone to change them the better. Another reason to need to touch the code is if the user model changes. I suppose we might also want a different password hash or to store the password separately even a different outcome if the validation fails. Or maybe have different ruled for different user types. When building a function like this I think less about "ideals" and more about why someone might need to change what I just did and how can I make it easier for them.

load more comments (2 replies)
[-] dohpaz42@lemmy.world 4 points 1 day ago
async function createUser(user) {
    validateUserInput(user) || throwError(err.userValidationFailed);
    isPasswordValid(user.password) || throwError(err.invalidPassword);
    !(await userService.getUserByEmail(user.email)) || throwError(err.userExists);

    user.password = await hashPassword(user.password);
    return userService.create(user);
}

Or

async function createUser(user) {
    return await (new UserService(user))
        .validate()
        .create();
}

// elsewhere…
const UserService = class {
    #user;

    constructor(user) {
        this.user = user;
    }

    async validate() {
        InputValidator.valid(this.user);

       PasswordValidator.valid(this.user.password);

        !(await UserUniqueValidator.valid(this.user.email);

        return this;
    }

    async create() {
        this.user.password = await hashPassword(this.user.password);

        return userService.create(this.user);
    }
}

I would argue that the validate routines be their own classes; ie UserInputValidator, UserPasswordValidator, etc. They should conform to a common interface with a valid() method that throws when invalid. (I’m on mobile and typed enough already).

“Self-documenting” does not mean “write less code”. In fact, it means the opposite; it means be more verbose. The trick is to find that happy balance where you write just enough code to make it clear what’s going on (that does not mean you write long identifier names (e.g., getUserByEmail(email) vs. getUser(email) or better fetchUser(email)).

Be consistent:

  1. get* and set* should be reserved for working on an instance of an object
  2. is* or has* for Boolean returns
  3. Methods/functions are verbs because they are actionable; e.g., fetchUser(), validate(), create()
  4. Do not repeat identifiers: e.g., UserService.createUser()
  5. Properties/variables are not verbs; they are state: e.g., valid vs isValid
  6. Especially for JavaScript, everything is const unless you absolutely have to reassign its direct value; I.e., objects and arrays should be const unless you use the assignment operator after initialization
  7. All class methods should be private until it’s needed to be public. It’s easier to make an API public, but near impossible to make it private without compromising backward compatibility.
  8. Don’t be afraid to use if {} statements. Short-circuiting is cutesy and all, but it makes code more complex to read.
  9. Delineate unrelated code with new lines. What I mean is that jamming all your code together into one block makes it difficult to follow (like run-on sentences or massive walls of text). Use new lines and/or {} to create small groups of related code. You’re not penalized for the white space because it gets compiled away anyway.

There is so much more, but this should be a good primer.

[-] FizzyOrange@programming.dev -1 points 1 day ago

Oof found the Java developer. No thanks.

load more comments (6 replies)
[-] humblebun@sh.itjust.works 1 points 1 day ago

Code should be generated from documentation imo

[-] verstra@programming.dev 4 points 1 day ago

Documentation should be generated from code imo

[-] Zagorath@aussie.zone 5 points 1 day ago

If the doco we're talking about is specifically an API reference, then the documentation should be written first. Generate code stubs (can be as little as an interface, or include some basic actual code such as validating required properties are included, if you can get that code working purely with a generated template). Then write your actual functional implementation implementing those stubs.

That way you can regenerate when you change the doco without overriding your implementation, but you are still forced to think about the user (as in the programmer implementing your API) experience first and foremost, rather than the often more haphazard result you can get if you write code first.

For example, if writing a web API, write documentation in something like OpenAPI and generate stubs using Swagger.

[-] humblebun@sh.itjust.works 4 points 1 day ago

Same for drivers. Generate headers from documentation and distribute it you fucking morons

[-] Zagorath@aussie.zone 3 points 1 day ago

Yup absolutely. I mentioned web APIs because that's what I've got the most experience with, but .h files, class library public interfaces, and any other time users who are not the implementor of the functionality might want to call it, the code they'll be interacting with should be tailored to be good to interact with.

[-] key@lemmy.keychat.org 5 points 1 day ago

Code should be generated from documentation generated from code

[-] svetlyak40wt@fosstodon.org 2 points 1 day ago

@key @verstra documentation should be generated from neuro-waves, generated from a brainstorm.

[-] humblebun@sh.itjust.works 3 points 1 day ago
[-] Deckweiss@lemmy.world 5 points 1 day ago

Just run both in a loop until it reaches a state of equilibrium.

[-] humblebun@sh.itjust.works 2 points 1 day ago

Or use LLM to generate the doc from all sources you have. Foolproof 100%

[-] nous@programming.dev 1 points 1 day ago

Better yet, use LLM to generate the docs - then use it again to generate the code form the docs. WCPGW

load more comments (1 replies)
load more comments (1 replies)
load more comments
view more: ‹ prev next ›
this post was submitted on 21 Oct 2024
76 points (85.2% liked)

Programming

17241 readers
263 users here now

Welcome to the main community in programming.dev! Feel free to post anything relating to programming here!

Cross posting is strongly encouraged in the instance. If you feel your post or another person's post makes sense in another community cross post into it.

Hope you enjoy the instance!

Rules

Rules

  • Follow the programming.dev instance rules
  • Keep content related to programming in some way
  • If you're posting long videos try to add in some form of tldr for those who don't want to watch videos

Wormhole

Follow the wormhole through a path of communities !webdev@programming.dev



founded 1 year ago
MODERATORS