Most of my IT career has been as a consultant and a manger of consultants. Over the years I have established some patterns to follow that I find helpful in making projects and technology easier in the long run. I sometimes share these in mentoring sessions and have heard often enough “you should write that down” where I started to.
I am still writing these concepts down, and while they originate from a consulting perspective they translate to every day practices beyond consulting.
Peer Reviews Help Everyone
Always request reviews of your work (code, documents, designs, plans, etc.) and make time to review others work when asked. Reviewing and being reviewed improves the quality of our work and our capabilities as consultants.
Reuse Applies to Everything
Developers learn to create and apply reusable objects in their code to improve efficiency in development and maintenance. This also applies to designs, project plans, matrices, etc. Look for templates and examples before creating your own and ask others in your organization if they exist if you cannot find them. While it will almost always be necessary to modify it for a specific project, starting from something that already exists will save time and provide inputs that you may not have come up with on your own.
Monitoring is Mandatory
Murphy’s Law is your friend. Use it plan what will be monitored, how it will be monitored, when automated alerts will be generated and bot the process and frequency of reviewing monitoring history and metrics. It is great to have common tools across the enterprise and important to be specific for each component how the tools are utilized. The systems are not static so the monitoring process cannot be if it is successful.
Always design first. Even if it is an agile project with an aggressive timeline, a clear understanding of what your solution will look like and the steps to get there will make the path easier to get to. Designing first is the opportunity to think through what you will be doing and recognize potential issues in advance. Often when design issues show up late they are dealt with as code flaws rather than design flaws, taking longer to correct and often leaving the design issue in the “fixed” result.
Your design can be as simple as stubbing out all of your classes before developing them. This way, issues that were missed during the design phase are more likely to be discovered earlier, before they become harder to fix.
Test-Driven Development is another approach to catch issues early on.
Insist on Design Review
Have a technical lead or peer review your design. The additional perspective is always helpful, either by validating that your approach is sound or questioning choices and reviewing options found by a fresh set of eyes.
Retrofitting DevOps practices is often difficult. For greenfield projects, prepare a detailed recommendation on the benefits of DevOps for the application and the steps necessary to implement and maintain. For enhancement projects, review the technology landscape for potential and recommend accordingly.
Environment variables should be maintained in the environment. Placing these variables in components where they must be updated between environments reduces the value of such variables and increases the chance of errors when migrating deployments between environments.
Source Control Check-in Minimum Daily
Daily check-in of code is not optional. There may be a rare circumstance where this is not the case, and such exceptions must be approved by the technical lead on the project on a daily basis.
An increment of work should seldom take longer than a day. All code that does not break the build should be checked in prior to leaving work for the day.
Code should be checked in each and every time it successfully builds and passes basic functional testing.
You should know the status of your own in-progress code at all times. If you don’t, then you cannot probably manage source control and the application is at risk for both difficult defects and issues during integration testing.
No property files in EARs or WARs
Placing property files in a deployment package defeats the purpose of being able to update configuration values without a deployment.
Also be sure that your code supports immediate updates through property files using mechanisms such as a cache that checks for last update or a re-load mechanism that can be fired by the property file change.
Use Naming Conventions
When creating new projects and packages, either follow existing naming conventions/patterns or raise the need for a change and refactor all of them.
Always Use Relative Paths
Should not require a mention as we all know it, but seems folks forget it frequently so this is a reminder.
Projects must have a readme that explains how to use the project.
Scripts should have usage notes at the top of the script. Preferably, the script should also do parameter validation and print out usage notes on validation failure.
All Connections Need Timeout Set
If all calls can be managed to a singlet timeout value, set it using an application-server level configuration. If not, manage it on a per connection basis with a single property file external of the deployment archive (usually the EAR or WAR) containing the timeouts to allow for updates to timeouts without compilation.
Determine and Describe Dependency Issues Precisely
When debugging an issue always thoroughly check everything that could be wrong with your own code and configurations before looking at factors your code is dependent on. Never assume the issue is with a dependency; find the dependency and describe it in detail. Not doing so leads to longer times to resolution with people focusing on why it isn’t their problem. In the rare circumstance where the dependency issue cannot be clearly identified, include a complete and concise description of what you have checked in your own work before asking others to check theirs.
Generate Bean Getters and Setters at Creation
If there is some special case for a field to not have a getter and/or setter, document it in the code with a clear, concise comment describing why.
Also, usually this should be the only code in a bean. Beans are storage containers and should not have processing or logic. In rare circumstances there are exceptions. Discuss the exception with the project lead before making it, and comment the methods clearly and concisely using JavaDoc comments.
Clean Your Code as You Go
It is easy to slip into the “I will clean it up later” mindset because you honestly intend to. More often than not, it does not happen because of shifting priorities. At the minimum, you should do your clean ups as you do your check-ins. You will also find it easier to work with your code if it is neatly formatted and well organized as it makes questionable designs stand out more.
Scripts Must Be Non-Destructive
Scripts should always check for perquisites and be written in such a way that if they are run repeatedly the actions will result in a fully functioning system.
When adding files or folders, check for existence and back up existing before changing. Multiple versions of backups should be kept. My general rule of thumb is 3 versions. Older versions should be removed as part of the script to prevent disk space issues.
A rollback approach should always be tested before running the script.
Apply Critical Thinking
If you are given a direction and the application of that direction does not appear to adequately solve the requirement, investigate other options. As a contractor it is expected to simply follow direction from the customer regardless of the outcome. As a consultant, it is your job to inform your leader or the client when something does not make sense and to provide a solution as part of the information. Anyone can report an issue; a consultant always includes a solution or an approach towards a solution along with the report.
It is the nature of many developers to check outside their own work first for the root cause of a n issue. Even when this is the case, simply stating that the issue is elsewhere does not result in resolving the issue in a timely manner. Always provide detailed proof of where the issue is occurring outside of your own work in a manner that is irrefutable by the person(s) that will need to address the issue. If there is any doubt about the cause of the issue, you will be made to provide this proof anyways, so have it as part of your explanation the first time.
Periodically review tuning and best practice references related to the technologies, tools and products related to the project you are working on to catch potential issues before the occur.
Data for Development
Always include time for making necessary, realistic data available for development. Include approaches for resetting and refreshing data. The time spent up front will be half as much or less than the time spent afterwards creating it as needed.
Plan Your Monitoring Before Go-Live
This concepts sounds obvious and yet it so often does not happen even in mature organizations. Everyone will be much happier spending some time to think about scenarios where things could go wrong and determining thresholds for alerts on any area where a variance can impact functionality or availability. You might not even know you were happy, but I assure you that you will not be happy when the pot boils over when no one was watching or even thought the flame would affect anything.
Defect summaries should be formatted as TYPE: Component – Functional Error Summary
Plan Performance Testing with Platform Architecture
If there is to be performance testing both the test tool platform and the test environment need to be robust enough to support it. This will require either a server farm capable of exercising the application at a realistic load or ensuring that the application performance test interfaces can be accessed by an external cloud-based platform. In the latter case, plan security testing to be done before the performance testing.
Automated Testing is Worth the Time
Many projects do not use automated testing because of the time involved in creating the tests. This is based on optimistic estimates of expected number of defects and iterations to resolve. Ironically, not having automated testing for regression testing increases the number of iterations to resolve defects and increases the total effort of testing.
Documentation and Communication
Identify Customer-Required Documents at the Start of the Project
Customers often do not look for documentation gaps until near the time when they expect them to be completed. Ask for their specific documentation requirements up front. They may later want to expand that list, and acquiring the list at the beginning and publishing the list for customer review early in the project will allow for better prioritization when the project is nearing the end.
Start Documentation Early
Many initially successful projects can later be viewed as poorly delivered when proper documentation for enhancements and maintenance is incomplete or non-existent. Begin your documentation as early as possible with a full outline and then fill it in the details as time permits. This helps to reduce the project wrap-up stress in starting documentation from scratch at the 11th hours.
Use Technical Deliverable Templates
Templates help to standardize documents for easier reference and provide reminders of sections to include and approaches for presenting specific topics.
Start from a Blank Template
While it is tempting to start from an existing document, this can result in bad data being left in and verifications of details between designs being properly verified. One example is a project that had scheduled jobs that ended up overlapping because the team kept creating new documents from the existing documents and leaving the schedule table unverified.
Avoid Unspecified Nouns
Unspecified nouns are words such as this, that, they, and it. The use of unspecified nouns can be confusing if there is more than one possible interpretation. While you, as the communicator, may only see one meaning for what is referred to by the unspecified noun, a reader or listener may not.
[NEED A GOOD EXAMPLE HERE]
While it may seem excessive and repetitive to do so, repeat the name of the thing you are talking about rather than assuming that everyone will know what this is meant by that.
Validate Guide Documents
The value of a guide is that people should be able to use the guide to complete the tasks it describes without assistance. First validate it yourself by following your document exactly as you have written it. Then have someone that will be a consumer of the document go through and follow the guide, having them make notes with Track Changes turned on. Bonus points for getting someone that has little understanding of the supporting technologies to do the validation.
A Picture Should Be Worth a Thousand Words
Screen shots should be used when they enhance understanding, allowing fewer words to describe the full details. They are not a replacement for all descriptions. At a minimum they should have a caption.
When values need to be entered in a screen shot, always include the values as text so that readers can copy/paste the values. Command line entries should use a style indicating they are commands rather than a screen shot showing the command, again to facilitate copy/paste and also because:
Is not clearer than:
Type this here
Update the Document Reference Links as You Work
Throughout the project you will need to find information online relevant to the solution. In addition to maintaining your own reference bookmarks, whenever you find a URL particularly useful to the solution add it to the Reference Links section of the project documentation. If you do not own the document, send the links to the team member that does for inclusion.
Share Your Knowledge Regularly
Hopefully your employer and/or client have a Knowledge Management system. At a minimum, the following milestones should be a reminder to contribute to this shared knowledge base:
- Completion of a project
- Completion of a key deliverable
- Solving a difficult issue
If you find it difficult to remember to make KM contributions following these events, set a regular reminder (weekly if not daily) to think about your activities and accomplishments and if there is something that is worth sharing, then do so.
Record All Web Conferences
It is a good habit to record the web conferences you host and request other hosts to record and post the recordings for participants. This allows you to focus more on the meeting rather than taking notes. It also provides a reliable source of reference when different attendees later have varying recollections of statements and decisions made in meetings.
Prepare to Participate in Project Retrospectives
The project retrospective is a chance to commit the lessons learned to memory. The issues with retrospectives come in bookend-form: It takes a long time to get the creativity and honesty flowing at the start of the retrospective and the captured lessons are rarely referenced by anyone not in the meeting. For the latter, you can blog about the lessons you’ve learned and for the former you can come prepared (you’d be surprised how often you are the only one).
To be prepared, it is best to keep running notes throughout the project (I use Evernote) or at least to put together some thoughts at least a day in advance of the meeting. If you are the only person that does this you can single-handedly knock over that first bookend (just like that couple that would always be the first to dance in school).
I strongly suggest that you have as many positive items available as possible so that you are ready to start it off on a good note. If you have several, space them out if others do not
Another approach that I have found to be successful may seem counter-intuitive: Make your first “area for improvement” shared something that you were responsible for. This is especially important if you are the first to provide it because by honestly recognizing and sharing your own contribution to things that went wrong it will ease the concern others have of being picked on. The group will be more relaxed and open up sooner, making the meeting highly productive.
© Scott S. Nelson