Thursday, June 2, 2016

Goals in software development

This is from a document I scratched down (in my mildly legible handwriting) about 5 years ago but I find that it is still worth reflecting on at times. The writing is starting to fade a bit so I decided it was time to add it to the blog. I made a few updates to mention newer ideas/technology, etc. This isn't really a complete how-to or anything - just a snapshot of what I was thinking about over a couple days a few years back. There is probably nothing surprising here even - it is to a large degree just the distillation of a number of best/good practices that I have experienced first hand and/or found documented by others. I'll probably fill in some details over time.

Just a brief description of my software development goals - these are "abilities" to strive for. This is beyond the "must meet functional requirements".
  1. Reliability
  2. Test-ability
  3. Maintainability
  4. Manageability
  5. Monitor-ability
  6. Secure-ability 
Promoting Reliability:
  • Development
    • Use source control. It amazed me that my employer had no source control when I started. Without source control it is tedious and error prone to manage anything but minimal changes with a single developer and it only gets worse with more developers.  There is minimal cost to use source control - free products exist so the main cost is in learning to use the tools and maybe some maintenance/upgrade aspects depending on the tool. With the use of SCM tools you can track the changes going into a product - which I believe is a factor in software reliability. 
    • Unit tests / regression tests.  
      • Use something like JUnit or a few alternatives. Use a mocking framework like Mockito to stub out your code to create reasonable sized test cases.
      • Depending on some factors; having developers run a basic set of unit tests as part of the source control pre-checkin process might be worthwhile. I have wondered if some sort of Eclipse / Subversion integration could be created for this. At that moment, it is something I do manually when it seems warranted. Catching silly issues before getting into source control does tend to reduce some slowdowns I experienced otherwise.
      • Automate unit/regression testing.  Use something like Jenkins to regularly perform builds. For a very small team this might be a manual process but for larger teams it should probably be done based upon source control changes occurring.
    • Use and/or write reusable libraries. I find a need to use utility type functionality in multiple applications so why not write it once, test it well and use it again. This does have a cost though - extra testing, documentation, etc.  If a utility needs a small tweak to support something new then extra testing / analysis / work is required to prevent unintended breakage of existing client code. There is some risk in using common 3rd party libraries - security issues cause a large consumption of Ibuprofen. How big the issue is can depend a lot on your organizations ability to turn-around new releases quickly with updated libraries.
    • Write some test plans and do some functional testing. If you have the resources then use some functional test automation tools as well. 
  • Architecture
    • support redundancy and failover
      • software or hardware load balancer
      • Any caching mechanism should not be a single point of failure
      • In general, reduce single point of failure situations
Promoting Test-ability:
  • Use Inversion of Control (IOC).  This promotes "configurability" and simplifies setting up tests. I use Spring for this. 
  • Create a testable architecture. There are a few books which talk about that in some detail.  
    • NOTE TO SELF: Add references.
Promoting Maintainability:
  • Use a consistent architecture
  • Don't repeat yourself (the DRY principle) 
  • Documentation
    • code
    • process/procedure
Promoting Manageability:
  • Task automation
    • Deployment tasks 
      • web/app server up/down
      • log rotating
      • archive files if desired (i.e. WAR, etc) for fast recovery if needed
      • Update filesystem permissions (to/from read-write)
  • Consistent environments
    • Don't manually update environment setups - automate it
      • Various tools (Chef, Puppet, CFEngine) should work or you can script things
Promoting Monitor-ability:
  • Implement hooks to expose metrics.  I would do this via JMX now. 
    • JVisualVM is part of the Sun/Oracle JDK and works pretty well at monitoring individual servers.
  • Reduce the number of places to review for system status.
    • Consolidate logs from multiple servers into one location.  
    • Integrate metrics into any monitoring tool you use (maybe Nagios, etc). 
    • Implement a dashboard of some sort
  • Implement self-checks.
    • application data and/or configuration consistency
    • DB/App server privilege checks
    • Static resource validations
  • Log parsing tools would be useful. Automate the trolling of logs.
    • Helps answer "when do you know you had/have a problem?"
Promoting Secure-ability:
  • This is a more recent addition. The idea being to prevent tampering whenever/wherever possible and promote the ability to determine if something was tampered with or accessed inappropriately.
  • Other "abilities" tend to support this but it is worth keeping as a separate item due to importance in this day and age.
  • I'd like to add more detail here but not sure the risk is worth it.

 Hope someone else may find something useful here.
Scott

Titus 2:7English Standard Version (ESV)

Show yourself in all respects to be a model of good works, and in your teaching show integrity, dignity,

No comments:

Post a Comment