- May 15th, 2021, 4:24 pm
#384365
This actually got lengthier than I thought. Let me know if any of them sound interesting for more unpack:
Keep your data tables as open and loosely connected as possible. Avoid unnecessarily hard-binding data, even if it looks tidier in some cases, because you never know when your client will admit that what looked like two very tightly correlated pieces of data is really three or four or that they need you to insert a couple layers of abstraction into that relationship. Best to just keep each category isolated with a guid and slot it in as a guid value on another table.
On that same note keep everything as open, expandable, and 'breathable' as possible in the way you structure the code (avoid too much interdependency) because unlike building a house you never know when your client is going to say they want to add a tower over here, a patio over here, a third and fourth story over here, a full Walmart or Costco over there, or even expand this side to jam a few more rooms into the interior. People are chaotic, apathetic, they'll give disorganized and apathetic requirements that you'll have to wade through, organize, question, etc. and even then you'll only be heading off some of the problems to come - they don't know how any of it works or how how much work it is, they just know they're paying you.
Don't be afraid to apply async and promises liberally, even using observables as puppet wires for other functions so long as you know how to keep them from hooking each other by mistake. Maybe the the additional advice there is do your best to avoid using timeouts to wait for API's or any other long processes, it's dangerous to do that as you're really setting up a race condition and you never know just what kind of antique someone might be using or how bad their VPN tunnel might be, far and away better to actually know - precisely - what event you're waiting before in order to move on to the next line of code and then hook that piece (for me most often a particular promise in series). Async is also important on the server side if you want to avoid those annoying thread pool starvation scenarios where an API call most of the time takes 1.5 second but occasionally it takes 25.
Don't worry about splitting everything into microfunctions or only the or four lines of code per functions (it's fine for utility and export functions maybe), so long as you have good error trapping and feedback and you know how to structure your code to have good failovers with try/catch/finally blocks then you're better off having readable code that sorts out by subject heading and if that particular class starts getting to be something like 4000-6000 lines feel free to start delegating some of the work to another class, particularly if there's some piece of logic that you can see yourself using over somewhere else.
If it's harder work to bundle your API calls for the sake of speed who cares - do it, it'll save a lot of wait time and it's something that'll grind on the patience of the client if they have anything like 5-7 second load times for an app when you can load your resources in 1.5 or 2 seconds by bundling the API call.
Enum's are great for avoiding keystroke errors in your code. If you have some hard-coded values that you're using in the program, especially default values for objects that you're creating, having enums to get them from something like a switch/case helps avoid typographical errors and also makes it much easier to maintain them from one place.
Change detection strategies like onpush, especially with complex UI's, are well worth learning to implement because it helps avoid a lot of the grind, has similar benefits to things like ngZone.
If you're using a typescript framework, like Angular, avoid using the forms and validation they give you - they're pretty bad and you're really better off making your own validation patterns. It might seem like it takes a bit longer to build these things from scratch you also don't have to beat your head into a wall over the way someone else built a validation suite and when you have one or two more requirements on a field than the given validation offers you're not caught in a bind.
You could maybe extend some of the principals in that last paragraph to 'avoid third party black boxes whenever possible - unless you don't mind having someone else in control of your ability to do your job'. Or at least if you're going to use a black box keep it to something very simple like a codec.
The attention you pay to making your code fail if anything veers off course and the more self-checks you build into your system to assure that it fails if it doesn't pass your audits at the end of larger processes (especially with something like a finance or accounting app) the fewer sleepless nights you have. Building your own analytic tools to watch for different types of potential error (like SQL views for example) also helps. Nothing's worse than having something not only fail without error but also not fail in a way that can come across your radar quite quickly.
If you're dealing with contingent data, like a finance app, it might be better to have it constantly rebuilding itself to both catch and mend bugs.
Other than that - keep your code as clean as you can, not to look 'all prim and proper' for someone else but for your own sanity - ie. you'll be the one who has to read it and fix it later most likely and sometimes the logic of what you're looking at could still take an hour or two to refamiliarize yourself with depending on just how much complexity your client had you bake into it - that's bad enough, don't make matters worse by having loads of commented out content, stuff you know is vestigial from prior changes that doesn't do anything, etc.
Humbly watching Youtube in Universe 25. - Me