I love software development, and over the years have had the opportunity to contribute applications for many different use cases. Whether the code is used for university submissions, internal company functions, external client contracts and even whizzy demonstrations, I've been able to flex my creative muscles and solve various challenges along the way. My solutions have made use of of a myriad of different tools, including clever algorithms, relational and NoSQL databases, 3D rendering libraries, tracking markers, Virtual Reality and APIs, so believe me there have been a LOT of problems to solve (including ones that I idiotically created myself like an idiot)! As you can possibly imagine, I've clocked up countless lines of code over the years, which whilst have made many systems perform many functions, can become HORRIBLE to manage. I fully believe that less is more, and over these years, I've learned that a bloated codebase is far more trouble than it's worth.\n\nA Hedge that's Never Trimmed\n\nLike anything that is left to grow unchecked over time, software has an awful tenancy to spill over and become difficult manage. If applications grow without regular periods of clean-up, refactoring, pruning and even spring cleaning (i.e. removed) then they will become huge, HULKING monstrosities that NO ONE understands nor wants to understand. They become those important beasts relegated to a corner that cause people to shudder when they have to interact. Software code, like most things in life need to be constantly managed with TLC from the first character typed until it is eventually retired from use.\n\nLarge forest with tall, daunting trees\n\nI try to live by a basic concept, where I try to make things as simple as possibly be and no simpler than that. This is perfectly encapsulated by one of my favourite quotes, which expresses the concept of brevity whilst using admirable brevity:\n\nIf I had more time, I'd have written a shorter letter (Various)\n\nThis idea fortunately extends to software, where the gift of time permits succinct code to do the work previously carried out by behemoths! I have found that more complicated that you make an application, the more opportunities the software has to FAIL and fail at the absolutely worst time imaginable. If you have a big demo in front of important people, THAT is when previously unseen issues will crop up, leaving you loudly protesting "this has never happened before I swear". Will they believe you? If course they won't!\n\nRegular Attention and Care\n\nWe should be ensuring at all times that our additions are 100% necessary, as they should be managed for as long as they are used. Don't just slap in a feature and forget about it, as this can cause all kinds of issues down the line, including broken or incomplete behaviour (which will likely be relied upon by future functionality) and even security risks as ignored interfaces can provide lovely entrances for attackers to exploit! Every one of your lines should count, and you are only as strong as your weakest link.\n\nWhilst expanding functionality is the sexy and fun part of software development, instead of allowing our codebase to grow into an unmanageable and unrelenting giant, it is crucial that we take care of our existing code regularly. This means inspecting many similar functions and rewriting them to use a shared structure, meaning that future updates span fewer packages. We should reduce the complexity of our existing algorithms to ensure that less can go wrong, and we should be constantly refactoring to shared blocks and packages to ensure our libraries are as easy to manage as possible. Also, over time and with experience we become better software developers, and will likely be able to write the same functionality more efficiently. Your codebase should benefit from this. As an aside, if you don't look back at code that you've written a while ago and wonder why you did it that way, you aren't honing your skills. If you are, remember it is a GOOD thing!\n\nAs a golden rule, always try to leave your applications in a better state than you found them.\n\nA matrix of software code\n\nFinally, we should make a concerted effort to remove all unnecessary lines of code at EVERY opportunity. Leaving in old and/or orphaned code again comes with risks, and can make understanding how an application works a literal NIGHTMARE. Trust me, spending time understanding a large block of code (warts and all), only to discover that it has been superseded and is unreferenced can make even the most relaxed pacifist put their first through a wall!\n\nI've seen people become emotionally attached to their modules, leaving them in almost as a love letter to the development process. THIS IS CODE! Cold harsh instructions for a computer to execute, not a sonnet for you to read passionately to your lover sailing along the rivers of Venice on a gondola! I've seen people comment out old code and leave it there as a pseudo version control method, even when we used Subversion (if you are young, think of Subversion as an older, inferior Git, no pun intended). This is horrible, pads out files and makes readability a test of patience, so please don't do this if you actually want friends! If you desire that your code lives forever even after it is removed, write a useful, informative commit message that really POPS.\n\nMy Improvement\n\nJust recently I had my own big refactor involving a file upload routine. Originally, files were PUT on a central server, where the server would create a v4 UUID filename (with extension) and return this name back to the client. This pattern was used to prevent attackers selecting malicious filenames and exploiting path traversal to compromise my system.\n\nOWASP Path Traversal\n\nThis pattern worked fine in use cases where content was prepared and submitted all in one session, with attachment filenames being returned as responses updated in the main submission as each supplementary file PUT request succeeded. This however became far more complicated when the use case was changed to incorporate local saves created via offline use uploaded in future sessions. Now there was a requirement to track whether or not files had been uploaded, and because filenames were provided by the server, there would be a local filename which needed to synchronised once the server generated the actual filename. You couldn't save a locally generated filename for an attachment in the main submission as the reference would fail when rendered server-side! Nightmare!\n\nIt took me a bit of time to write the functionality to deal with all of this, and BY JOVE I made it work as best I could, and with asynchronous methods! The local filename was correctly allocated, the filename synchronisation synchronised correctly and the submission was correctly updated as files completed. In an ideal (development) environment where everything is local and controlled, it all clicked (almost) every time! I was proud! However sometimes things went out-of-sync, and the client-generated, local filename would be sent to the server due to a file upload timeout or failure. EPIC FAIL!\n\nHands behind head unhappy with duff code!\n\nThis didn't always mean that the file didn't upload, it sometimes meant that the file was successfully saved but the response got lost along the way. On resubmission, a duplicate file with a different server-generated fine would be created, effectively eating up storage space. You could try and check that the file was saved, but how would you know what filename to look for? The server-generated returned is the first time the client application would be given the filename! Do you send a name along with it as a hint perhaps? This would add even more complication. As you can see, much could go wrong with this method of naming and this was in an IDEAL development environment! If rolled out into production, I could imagine VERY real issues manifesting (especially on spotty networks) and understandably some VERY angry users! \n\nAfter spending some time wrestling with this configuration, a simpler approach was considered to make the system work more reliably. Here, the filename would be set client-side to a v4 UUID which would be provided in the URL of the PUT request and validated server-side to protect against the aforementioned path traversal attack. It would mean that any file retries (e.g. after a network failure) would use the same filename effectively overwriting any previous saves. However, all the long and hard work completed on the (now useless) synchronisation code would have been unnecessary, and the lines tossed into the code trash can. The debate was a battle to the death between effective functionality, and ones own ego and tendency to hoard "my previous" lines of code.\n\nAn effective, working upload won this round, and the previous synchronisation code has now been confined to Git commit history to be studied by software archaeologists and in equal measures laughed at by the future equivalent of todays millennials. "You wrote THAT?! What's wrong with YOU?!". I actually wouldn't have a response to this, hahaha! Too right!\n\nCat laughing at the silly software code written\n\nIn this case, me improving as a developer over time and being able to integrate a simpler solution to a problem was made available to the project. We should strive to make this a normal occurrence.\n\nQuality Assurance\n\nSoftware development involves managing an existing lines of code as much as writing new functionality to prevent the unabated growth of a codebase into something unmanageable. It is important that we exercise this duty, and say goodbye to lines that have outstayed their welcome to avoid poor future functionality, along with security risks. We must ensure that the applications that we build benefit from our ever improving knowledge, as this allows them to run as efficiently as possible. Code hoarding for whatever reason is the antithesis of practical software management and in the long run can hinder progress, as well make software development really tiresome. Try to avoid it when you can!\n\nTake care and all the best. Si.