The problems with complex code and complex CRM Customizations

Any fool can write code that a computer can understand. Good programmers write code that humans can understand.  Martin Fowler

Complex code is hard to understand code because classes and methods do so many different things it’s impossible to understand how it works without stepping through the code to understand exactly what is going on. – Hosk

When writing code you need to keep in mind – Will I be able to  understand this code 6 months later when I have forgotten the business logic – Hosk

This started out as a small blog post, which seems to have kept growing and growing, so be prepared for a long read.  I have a few CRM developer articles which you can find in the section Hosk’s CRM Developer Articles.  It has an article on code readability and why experience is important in CRM development which I recommend you to read.

Before reading the article below I would like you to remember coding is an art, which is one of the reasons it takes a time to learn.  Seeing coding as an art helps to explain why there is no right or wrong way to write code and good code/bad code is open to interpretation.  So the thoughts below are my thoughts on coding and the processes and standards I use, yours might be different but I would love to hear them so please leave a comment.

Complex code

Most developers have been in the situation where you get assigned to a new project and one your first tasks is to resolve a bug. project.

The first step usually when bug fixing is recreating the bug, so I will assume you have done that so now it’s time to look at the code to try to fix the bug.

When debugging some code this is roughly the process I go through
  • scan the code
  • getting a rough idea of the structure of the code
  • work out the flow
  • understand the data sources
  • Work out what parts of the code are changing the data.
When you come face to face with some nasty complex code, you will see unusually named classes, methods and variables.  There will be some massive methods which seem to do all sorts of things.

“WHAT IS THIS CODE DOING?”

The only way is to debug it line by line

The code is so complex and confusing the most efficient way to understand it is to debug the code, stepping through it line by line, hoping to get some understanding what’s happening and trying to find the elusive cause of the bug.

The code is one big pile of spaghetti code which you are afraid to change, if you are good (and have time) you will do some code refactoring but most likely you will cautiously poke a change towards the code with a long stick, cross fingers it fixes it before slowly backing away hoping to never see the code again.

Why complex code created

 The opposite of simple code is complex code but I would say a lot of code isn’t complex its just poorly written and structured, the main causes of poorly written code (which is often needlessly complex) is inexperienced developers or developers under time pressure.
There is another great quote, which I have paraphrased below from this post – On Credentialism In Software Development
Junior developers create complex code for simple problems
Senior developers create simple code for complex problems
A rushed developer creates code to refactor later

Common reasons for complex code

  • Written by a junior developer who is learning
  • Quick bug fixes
  • Time constraints
  • Refactor Later
  • No Peer Reviews

Inexperienced/Junior Developer

The reason most complex/bad code is written is because a junior developer hasn’t learned to write simple code yet.  Taking a complex solution and simplying it sounds easy but is extremely difficult in practice.

Time constraints

When developers rush they create code and more code but they do not create better quality code.  Rushed code creates what is called technical debt, which will give you problems later (e.g. when you have to debug or enhance the code).  A note for project managers, pushing developers to extremely tight schedules creates more code

Quick Bug Fixes

When developers add quick bug fixes or bug fixes in general it’s easy to wedge in some code and increase the complexity by veering away from creating simple code.

Refactor Later

Developers know they should write better code/simpler code but they write some code which works and fixes the bug/provides the functionality needed and they promise to “Refactor later”.  You already know how this story ends, the developer is too busy, something urgent pops up and the code is never refactored.

No Peer Reviews

The most effective way to reduce the amount of complex code or bad code is to have a senior developer check the code with a peer review (could also be known as a code review).  The developer won’t let their standards drop and will produce better code when they know it is going to be inspected by another developer.

Peer reviews will also find some bugs in the code and are a great way to guide junior developers into converting complex code into simple code with pointers from the senior developer.

The smells of complex code

Poor code gives off a nasty smell, you maybe able to recognise some of the smells in this wiki article – Code Smell
To understand simple code, I will explain what complex code is and why it makes it difficult.
Here are some of the main culprits of complex code
  • Large methods – Monster methods
  • confusingly named classes, methods and variables
  • methods which do lots of things
  • not consistent
  • tight coupling
  • dependent code
  • poorly structured code

Large Monster methods

I’m sure all developers have come across a project where there is one monster method that runs for lines and lines and lines.  They are often full of bug fixes and usually one developers knows the method (the poor soul has had to debug it many times) and often all the bugs flow their way.

People are scared of the monster methods and rightly so because no one can understand it and no one wants to change it.

Plugins are a common breeding ground for monster methods.  I have seen numerous plugins where all the code is directly inside one big method in a plugin.

Developers should not be afraid of changing code

Badly named classes, methods and variables

You know the complexity of code has gone up a notch when you start to see confusingly named methods and variables.  The reason why code gets oddly named is because it’s difficult to name a method which does more than one thing.
Poorly named code makes it difficult to understand the code.

Methods doing more than one thing

Good methods should do one thing well, this makes them easy to understand, easy to debug and fix and easier to reuse.
Complex methods will do lots of different things which makes understanding the method difficult and changing and extending the method scary.

Not consistent

Complex code/poor code will be inconsistent, this can usually occur when a developer has copied the code from various different sources or you have a number of developers working on a project where there is no standards being applied.

The difficulty inconsistently structured code brings is it makes the code hard to understand because there is no common structure, the code has a different flow.

Code and customizations are difficult to understand and not being consistent makes the job even harder.

Tightly coupled/dependant code

Tightly coupled code is code which can’t be reused because it is dependent on other code in the project.  The cause is often because the methods are doing more than one thing and  are really a number of methods (if they were refactored) squashed into one.

Dependant code often can’t be reused even within the same project.

Poorly structured code

Code should be structured and organised in a logical manner.  A simple form of structuring is splitting the business logic and queries into separate methods.

Code structuring makes the code easier to understand and splits into smaller logical areas, this will help in code reuse and bug fixing (because you are isolating the bug)

CRM Customization smells

I have discussed general code smells and complex code, in this section I will focus on CRM complexity.  Below are some of the complex code/customizations I have seen in CRM.

Giant workflows

The CRM GUI for workflows can make it difficult to work with workflows but when you have a giant workflow it can be almost impossible.  There is a limit of four nested if statements in CRM (it’s true for CRM 2011, I’m dangerously assuming it’s still the case in CRM2013/CRM2015 but I could be wrong) and when you have a workflow which is hitting this limit, it’s a sign the workflow is too complex

Read more about four nested if statement limitation

Big workflows are very difficult to maintain and making changes can be very challenging, if you have workflows which are very big you should consider breaking these down into child workflows.

Lots of different customizations overlapping

CRM customizations allow you to provide functionality in lots of different ways.

  • Plugins
  • Custom Plugins
  • Javascript
  • Business rules
  • Workflows
  • WCF webservices
  • Console apps

Some customizations are better suited to certain problems and best practices/experience will guide you as to which customization you should use.

I have seen problems where developers have used business rules and Javascript together because business rules don’t trigger Javascript on change events.  By using the different customizations together you are adding to the complexity of the solution and making it difficult for developers to understand the flow.

You can get similar problems when workflows and plugins are used in conjunction with workflows running after the plugin (because plugin is synchronous and workflow is asynchronous) and the workflow overwrites the plugin set value.

I’m not saying using plugins and workflow is wrong and should never be used but care should be taken when they overlap it can create a solution which is difficult to understand and debugging can be puzzling.

When deciding what customizations to use, some consideration of what customizations already exist should be taken into account.  The simpler the solution the easier it will be to maintain and extend the solution later.  When I mention  solutions I am referring to all the customizations as a whole.

Javascript files with duplicated methods

The most common method of structuring Javascript code is having one Javascript file for each entity, CRM pushes people into this model by making you choose a file to upload for the form.  This isn’t incorrect because there will be Javascript methods only suitable for each form because they will be manipulating fields on the form.

This can cause people to copy methods from one entity Javascript file to another entity Javascript file.

What happens later if a bug is found in one of these duplicated methods, usually it gets fixed on one form.  Then you have duplicated code, some of which is fixed and some which isn’t.

No common Javascript files

Following on from the point above, if there are common Javascript functions then put them in a common Javascript file rather than copying the same function many times.

All the code in the plugin

My personal view is you should have no code in a plugin, it should all be moved out to separate classes.

The first reason is you have created a big monster method, which is hard to understand, debug and enhance.

Testing code in a plugin is difficult because you need to mock all the plugin code, if you remove the code from the plugin, you can test the code by just passing in a OrganisationService (e.g. a connection to CRM).

You cannot reuse any code inside a plugin

Copy and paste code (plugins and Javascript)

Complex code means people cannot reuse the code, so they often end up copying parts of tightly coupled code from one area in CRM to another.  This can often lead to messy/poor code but can also allow bugs to slip in with code which isn’t relevant or needed.

The problems with complex code and customizations

 

The code is hard to read

When writing code you need to keep in mind

When writing code you need to keep in mind -Will I be able to  understand this code 6 months later when I have forgotten the business logic.

 

Complex code is hard to understand often because it’s not structured and modularized.  Understanding code which is logically structured into separate classes and small focused methods is easy because the code does what you expect.

Complex code has large methods which do many things, the classes and method names are confusing because it’s difficult to apply a name to a class/method which does many different actions.

Well structured code is like a tidy room, with everything tidied away into draws, bookshelves and wardrobes.  Easy to understand and use.  Things are easy to find.  If you add a new item to the tidy room, you can place it with the other similar items

Complex code is like a messy student room, everything is on the floor.  It’s hard to understand the where everything is or should be.  Objects are to find because you are not sure where to look.  If you add a new object to the messy room, where do you put it and will mess up the organisation of the room.

Slightly improved code is where the messy student buys a big wardrobe and a chest of drawers and chucks groups of things.  You know you need to look in the chest of drawers but if the socks are not in their own drawer it’s going to take you time to find them among the other clothes.

The code is hard to debug

Complex code is hard to debug because it’s because it isn’t structured logically (because it’s in big methods) and the code isn’t easy to understand.  Often the only way to understand what the code is doing is slowly stepping through it.

The code is hard to enhance

When  I mention enhance I am referring to adding new functionality to existing code.  Complex code is usually tightly coupled and changing a big monster method is tricky because you can only test the whole method, rather than a small focused method.

Complex code creates complex bugs

Complex code can create some very tricky bugs which are not obvious to diagnose.

No Reuse

Complex code is tightly coupled and big methods are very difficult to reuse.  It means developers have to write more code, which means more testing.

More code will increase the chance of more bugs.

A lack of reuse in code will result in developers copying parts of code which can result in copy and paste bugs.

Duplicate code will result in bugs where some of the duplicated code is bug fixed and other parts get forgotten about.

Encourages more of the same

Junior developers and developers in general will copy working code.  The good developers will refactor the code, the poor developer will just leave it as it is.

Copying complex code will create more complex code.

If developers see other people creating complex/bad code then they will too.  It’s letting standards drop and everyone will pay for it later down the line when bug fixing takes twice as long

Junior developers will copy it

Developers should set high standards and great code for Junior developers to learn from.

If everyone is creating simple well-structured code, the junior developers will follow their lead.

Summary

Creating complex code/quick code really causes problems for a project later.  Finding and fixing bugs takes a lot longer because the code is harder to understand and fixing the bug is difficult because the code is in large methods and not well structured.

The difficulty in fixing large methods is they do many things and you have to make sure the method still does all those actions and changes.

If you compare this to fixing a small focused method, you only need to make sure it still does the one action.

Complex code creates problems for the project later on where it will become harder to maintain the code whilst fixing bugs and enhancing.  Complex code will mean people take longer to get up to speed on a project, whilst they learn how this individual project is setup and works.

I’m sure lots of developers have worked on legacy projects with complex code and it’s not an enjoyable experience, so make sure you are not creating projects like that.