The rate of change for software quality and expectations has dramatically increased and will continue to do so. Today's techniques and architectures are next month's has beens and pains to deal with. The way good software is written looks nothing like it did just a decade ago. The expectations software customers have has matured to what could be considered a snobbish high.
Over the past 2 decades I have been able to observe good and bad best practices of multiple organizations. There are certain characteristics I have observed that work and many more than don't. In fact I think it is fair to say the majority of software project fail, often attributed to the bad characteristics. Not that a poorly written application can't succeed, Facebook is a glaring example. Sometimes human gravity just outweighs well written and architected software and you can get away with junk for longer than you should.
I wrote the majority of this article several years ago, after leaving one of the worst development shops I had participated. I think it was written to help me vent some frustration. Recently I have had several independent discussions with developers about best practices, especially in enterprise software development. Another conversation about just being overwhelmed as an individual developer was the real tipping point to go ahead and clean this article and publish it today. The good news is there are developers out there that want to have good practices, workflows and architectures. However I think the majority either make bad decisions or more often than not simply do not care enough to try to improve.
I agree many developers are overpowered by today's rapid technology movements. The rate of change is often referred to as a fire hose. The volume and velocity of new libraries, frameworks, techniques, platforms and specifications simply overwhelms even the best technologists. This is making it hard for IT decision makers to make decisions with confidence. This leads me to perceive a high level of paralysis in the enterprise as technology is passing most companies by.
The modern enterprise runs on custom built software. Sure they spend vast amounts of money on SharePoint's, PeopleSoft's, SQL Server's and the like. But they spend more time and money customizing those software packages to fit their perceived needs as well as hundreds of thousands of custom line of business applications that somewhere along the line started the same way, File + New + Project.
With over 20 years at this point and I am starting to see things through much more mature eyes. I see software trends, languages and styles come and go faster than women's fashion trends.
20 years ago the web was barely known, Ami Pro and Lotus 123 were popular office tools. Developers were using Borland C++, BASIC and even plain C to create applications. Mosaic was the cool browser. We thought we had a good life, and we did. Then we went and kept making it better and better and better.
We learned to create better and better techniques to build software. This often means the techniques, languages, infrastructure, etc simply becomes outdated and must be replaced. The software and techniques of the past are now relicts of the past, destined for a computer science history book or museum, the chain restaurant equivalent of where antique signs and farm tools reside today. Remember when Ruby was cool? Or when Subversion was an awesome source control system?
Those old languages, designs, tools, etc were all replaced by better versions that themselves will eventually be replaced. I used to think the applications I wrote would last for years to come. Not anymore I accept a six month shelf life before it becomes stale and will most likely be replaced with a new technique here, technology there or just outlived its usefulness to the customer. Its not personal, it is just the way it is and should be.
Instead of embracing these changes to make their business more profitable I often see enterprise development shops falling behind for what ever reason. Today I want to isolate just 5 things I commonly see in the enterprise that is causing them to hemorrhage time and money to the point of paralysis. These by no means are an exhaustive list, I can think of several dozen more factors, but I need to limit the scope of this article.
Using Outdated Processes
Software development is a process and is subject to change. As I was finishing college and beginning my professional career I was focused on manufacturing, chemistry and ways to make processes more efficient. This involved measuring aspects involved in the actual manufacturing process. It could be heat, speed, humidity, energy consumption or just how often does the machine operator needs a bathroom break. The common thread to all this was to identify the week points in a process and make them stronger so the company could be more profitable.
Sometimes this means throwing out expensive equipment that could not keep up with expectations and replacing it with even more expensive equipment. The end result was a much more profitable and competitive company. The final products were usually higher quality, the amount of rejects lowered and customers were more satisfied.
There was always a need to measure the expected return on investment or how fast can I turn a profit on my capital investment. In the software business this can be an interesting choice? How much does it really cost to develop custom line of business software? How long will that software be usable? Can the software be updated as the business needs change?
As I visit and review various enterprises I see a common issue with outdated software development processes. The #1 offender is the employment of waterfall instead of agile processes. Waterfall is where the development team goes off with a very long set of requirements the stakeholders have supplied. The list is often more of a wish list based on what they have today.
The process often lacks vision of what can be done or where the business will be when the application is ready to deploy. The development team runs off for 6-12 months and builds 'software' that meets the stakeholder's request. The end result is almost 100% of the time not what the stakeholder thought they asked for and certainly does not help them do many, new important parts of their day to day business that may not have even existed when the development cycle began.
I saw this first hand with my first project assignment at my first job after graduate school. My task was to build a custom report module for a plant manager. I built the solution in a couple of weeks and the manager (the stakeholder) loved it. The problem was the IT deployment and code review process. You see no one told me anything about this so I just wrote a solution, it worked, the stakeholder loved it, so I naively thought "ship it". Well I learned real quick what a code review and managed deployment process was. Needless to say six months later when the solution was deployed the manager had long forgotten the project and found another way to get his report. Shadow IT for the win. For a young Chris it was a big eye opener.
Agile on the other hand will take the long requirement list and break them down into really small groups based on priority. Typically a development cycle is 2 weeks, not months of any sort. At the end of the 2 weeks the software is delivered to the client for real use (this is important). There can be a QA review before deployment, but if proper unit testing has been employed it should not be a long process.
Once the application has been deployed the next 2 week sprint is started and new requirements are collected and allocated to upcoming sprints. The end result is a continuous cycle where the business keeps getting small digestible improvements and have an often smaller, more agile development team dedicated to their needs. The end result is good tools with happier stakeholders.
Unfortunately the agile, sprint based approach is almost never used in the enterprise. More often than not there is what I call Waterfagile employed. This is a Frankenstein hybrid of waterfall and agile. The developers work on 2-26 or 52 week (that's right 52 weeks) sprints to deliver a finished product after a year or two. The development team has daily morning stand ups, but often these are scheduled and sparsely attended or just plain canceled most days. The technical folks tell the business they are agile, but in reality they are nothing of the sort. Mostly they mean they have a daily status meeting, which they confuse with being agile.
This defeats the purpose of what agile development is all about and it does not solve the problems it is supposed to solve. So often the enterprise software project fails or at best creates great tension between the business and the developers. Software is a living breathing entity, especially when it is highly customized for a particular business process. Agile methods provide the best way to continuously give the business something they need, engage them in the development process. Failures are quickly remedied and successes create good will capital.
A mess, that's the word I think best describes the state of enterprise source control. This is probably one of the most important things an enterprise development team needs to manage. It has to be reliable of course, with good backup. But it has to be easy to use and allow the team to actually work in harmony together. Merging and branching should just be obvious. I am not so sure the current crop of source control systems is quite there yet, they are close. They all have pros and cons. I have to say I like Git's model more and more, I just hate the typical UI. TFS is expensive and very bulky, but has so many features enterprises really need when it comes to a complete project management system. But project management is not really source control, so don't get the two things confused.
Before I begin this section let me state I am not very disciplined with unit testing, but the more I work with teams for various clients I see the need for good unit testing practices. The larger the team the more important a good battery of automated tests become. No one can know what everyone is doing and therefor cannot know if the small little change they make will break something someone else or even themselves wrote last month.
Tests are a good way to make sure the little things are working as expected. Even software that is perceived as small has any small, important details that need to function properly for the software to just work. As you progress through the application development process you often forget the details you handled last month or last year. Unit tests ensure these details continue to work without hearing from the end user with an angry e-mail or scowl in a meeting.
A unit test is a function that exercises a small piece of code in a specific manor. This does not mean it exorcises many methods at once, that is an integration test. An integration test is designed to test the outcome of several smaller units that work together to produce a finished product. An example would be testing a service end point to see if it returns the requested record(s) from the database. Unit tests, on the other hand, would individually test each of the methods in the overall pipeline to ensure they are working correctly.
More often than not the enterprise creates a small set of integration tests and call it unit testing. This is problematic because if something is broken it is more difficult to trace the error and fix it. I also believe it removes personal ownership or mental responsibility about the code quality employed by the individual developer.
Sure proper unit testing takes time, up front. It is a different way of developing software, which requires a mental shift by many enterprise developers. It requires more initial investment writing code. It can also be difficult determining exactly how to test a function because so many dependencies must be stubbed and mocked. However, once the practice becomes a normal way of life those hindrances are reduced, to code quality is increased and the maintenance costs radically reduced.
Let me finish this section with a recent example. My team was dropped in like paratroopers to fix some chronic issues. The code was an giant unorganized mess with no guidance as to how things worked. There was no documentation, a lack of helpful developers that even understood their application and of course no unit tests. We had to simply walk the code to find the issues and fix them. We had no confidence we were not breaking code we were not working with. A good battery of unit tests not only would have given us confidence we were not breaking the application in ways we could not anticipate we would have had some solid guidance to how the application was supposed to work. The time for us to ramp up to work on the application efficiently would have been radically reduced, costing the company much less and of course making the business folks happier.
Tight Coupling And Code Reuse
Debt, debt, debt, it just kills any good project. In the average enterprise application I have encountered it is just riddled with debt, usually from tight coupling and not following the DRY principle.
How many times have I reviewed the button click event handler with 100-2500 lines of code? Too many to count to be honest. There should about 2-5 lines of code in any button click event handler FWIW. The handler should call a method that actually performs any client-side logic. This makes it easier to test and replace as the application changes. The core business logic should be in the business logic, behind a service API layer. The client should only be responsible for client things, like basic validation. I point this scenario out because it is very common and easily fixable.
Don't Repeat Yourself, or DRY is also something I see ignored. Basically if you use some code more than once you really should refactor it to a method of its own. This makes testing easier and code maintenance easier. You can find errors and address them and you have much less code to maintain.
This is a tough one, but something we need to be honest about. Many enterprise developers, managers and architects I encounter are simply not qualified for modern application development. This factor alone results in poor applications littering corporations world wide, wasting billions of dollars every year.
Many times there is a developer quota to fill or the term 'butts in seats'. This is a sign the management layer probably does not really know how to plan and manage the project. Often the subscribe to the 9 women can make a baby in 1 month syndrome. There have been several times I was placed on a team of 10 or more when the project really just needed a single good developer. Most of the time was spent in planning meetings, merging code and other non-productive tasks. How do I know, I have built a lot of software in and out of the enterprise by myself and many of those applications were larger and more complicated than the 10 person team's product.
The butts in seats mentality leads to teams hiring anyone that has the correct set of acronyms (TLAs) on their resume. Its tough to hire qualified enterprise developers because there is really no good way to evaluate their skills because much of their code is behind a firewall and not owned by the developer. That is one reason why I blog, have a GitHub page, speak, author books, etc. Good or bad I want to share what I can do and why I believe.
Not everyone can do what I am doing, we are all different. I like what a friend of mine tries to do, maintain a small set of code in a portfolio he can hand to a hiring manager or recruiter to review. I like the idea because not only will it demonstrate your capabilities and interests it also forces you to keep up and dabble with emerging trends, languages, etc. That can only make you better as a developer. I mean you get 10 free Azure websites you can post the working code, hosted in S3 or Azure blob storage or even a public cloud drive if nothing else. There are lots of options. Hiring managers need to look for these sorts of things.
In the end enterprises need to adjust the way they build and manage software development projects. Let old techniques fade away and replace them with better ones. It is a continuous improvement process. It requires everyone involved in the enterprise development stack to not only keep up with trends but experiment with future ones. The final products as well as on going maintenance will be better and easier, thus reducing overhead and making stakeholder happy!
But developers and IT professionals are not to blame for this problem. Many enterprises do not know how to hire. They are lost and often outsource the hiring process to head hunters. They look for keywords and filter to supply possible candidates.
At the same time enterprises are not sure how to define developer roles. For example I still see too many positions for full stack developers. That worked 5 years ago, but not anymore. You need to have more specialized roles. A front-end position, one or more business layer developers and at least a data specialist. The more complex the application the more roles and positions a project can fill.
Times have changed, but we have struggled to keep up. We struggle with modern software development because we keep trying to apply legacy techniques to the process. This means architectures and work flows are out of date.
Unfortunately this means we make messes. We can do better. Breaking habits is hard, it requires a leap of faith. Sometimes we find out we are wrong and need to change to something else. These bad choices can be damaging to the business, but also to a person's career. So we make safe choices, the choices to stick with what worked yesterday.
Successful high tech and startup companies on the other hand have become big experiments. The company puts a product out there, collects data on how it is used, how customers perceive the product or service and constantly tweak the offering or even pivot to meet the market demands. My point is these businesses are not afraid to fail fast and adjust to market demands. You can read more about these concepts in Lean Startups.
At the same time our technology stack has evolved and become more complicated. This has made it hard for developers, IT professionals and managers to keep up. Some of this we put on ourselves constantly trying to invent fast food frameworks with promises of silver bullets. Unfortunately they have the reverse affect as developers scramble each year to learn the fast food framework du jour. This waste important developer time and money and create fat, slow software no one likes using. Sadly this process is repeated every twelve months.
This year React is the hot newness. Last year Angular was the rage the year before jQuery still had legs. Meanwhile Ember and Backbone are still around. These are just some of the front-end fast food frameworks I deal with everyday. The back-end is just as polluted. ASP.NET WebForms, MVC and now vNext. Then there is nodejs, PHP, Ruby, Python, F#, Java (different flavors there) and many other platforms, languages and frameworks. It is almost and endless list of options.
What never seems to change? Our desire to geek things up. We are always reaching for the next cool thing. We have to of course. How else are we going to see the reality of Minority Report or some other futuristic science fiction movie or novel?
Enterprises spend billions each year creating software, tailored to their specific needs. Often the processes are not efficient and do not bring out the best in the engineers. We need to have a little more courage and take chances. At the same time we need to simplify our processes and not rely on large, one size fits all frameworks and get more intimate with out platforms and languages. At the same time we need to develop like a lean startup and adopt a true agile process.