The image above is from the article DEALING WITH TECHNICAL DEBT, which I recommend you read, right after reading this one 🙂
The common method of creating plugins in the CRM projects I have worked on, is putting all/most of the code directly in the plugin class, this creates code which is
- Complex code
- Hard to read
- No code reuse
- Difficult to debug
- Writing unit tests is hard so most CRM developers don’t bother
This method of developing plugins creates technical debt to the CRM project instantly and pushes the code towards legacy status and creates spaghetti code
The motivation for writing this blog post is a most CRM projects don’t have enough classes\abstractions in them and the code written is not adhering to good object orientated design principles.
The lack of design and structure in CRM plugins I believe is one of major reasons there is little code reuse in projects and between projects.
I have experienced CRM projects where multiple developers have independently written the same code, not only creating duplicate code (and more code to maintain) but each developer had to spend time writing the code.
CRM developers seem to have an aversion to creating classes and finding abstractions in their code. A common occurrence in CRM code is the creation of the Plugin Monster method
The plugin monster method is a CRM plugin which has all of the logic, which can be many lines of code.
Creating CRM plugins without using classes creates a project with lots of technical debt. The amount of technical debt is increased with the creation of every new plugin.
Creating plugins with classes or using OO principles will lead to CRM project code reaching a legacy level almost before the project is released to the customer.
This type of coding doesn’t adhere to the S.O.L.I.D principles. This article gives a quick summary of the S.O.L.I.D principles
Most developers (hopefully) have heard of S.O.L.I.D. principles and the principles of Object Orientated Design. The best place to start is with Uncle Bob’s Principles of OOD
Below is the Uncle Bob’s list of the S.O.L.I.D. principles with links to his articles on the subject. The first five principles are focused on class design
|SRP||The Single Responsibility Principle||A class should have one, and only one, reason to change.|
|OCP||The Open Closed Principle||You should be able to extend a classes behavior, without modifying it.|
|LSP||The Liskov Substitution Principle||Derived classes must be substitutable for their base classes.|
|ISP||The Interface Segregation Principle||Make fine grained interfaces that are client specific.|
|DIP||The Dependency Inversion Principle||Depend on abstractions, not on concretions.|
Many developers have heard of the SOLID principles, fewer developers understand the principles and even fewer put them into practice when creating their plugin/custom workflow code.
You might think CRM development doesn’t need to implement OO principles because plugins are small focused pieces of code. This view is has resulted in plugin code consiting of poorly written, complex code and explains the lack of reusable code generated by CRM projects.
Code being re-used in CRM projects is seen as often as big foot – Hosk
Common attributes of CRM projects (in my experience)
- The number of classes is minimal in CRM projects
- Classes and methods doing more than one thing
- Most projects have no unit testing and the code would be hard to test due to complexity
- The S.O.L.I.D principles rarely implemented
- Almost no code reuse, even in the same project between plugins
Projects with the characteristics above have little/no code reuse and contain an abundance of technical debt which makes supporting them difficult. All interaction with the code will take longer and longer.
Code Interaction is
Why does poor plugin code get created
I have seen many many many plugins written where all the code is included in the plugin. This blog is about poor class design but putting all the code in a plugin is not even designing a class.
Putting the code in the plugin and creating one big method is poor coding and results in
confusing complex code which is hard to understand
Very hard to unit test a plugin
zero code reuse
Complex plugin code with poorly designed code leads to these problems
- debugging is difficult and takes longer
- bug fixing is difficult and takes longer
- No unit tests means refactoring is difficult and often avoided
The bottom line is the project which becomes a legacy project and developers try to interact, change and extend the code as little as possible.
Explanations for poor plugin code
Below I will discuss the reasons why I believe poor code gets created most of the poor code could be avoided with code reviews.
Some plugin code is written by junior developers who didn’t apply the principles for designing and structuring classes and methods. The blame should not be placed on the junior developer, the reason why this code is still in the project is because their is lack of code reviews in CRM development. A code review would have picked up the poor code and the code would have been rewritten with some guiding advice on the areas to improve.
Poorly skilled developers
There are some developers who don’t enjoy being a developer and they have no passion for developer or pride in what they create.
If you don’t enjoy doing something you are not likely to devote much time improving your skills (despite it being their main source income)
They are different from junior developers because often these developers are quite experienced (in terms of years of development experience).
Developers who have not heard/read about OO Principles
Some developers believe if you write code and it does what is required then that’s all that matters.
Many developers believe designing the code to OO principles, creating classes and methods are not needed and don’t.
This will create the code which delivers the functionality but any further interaction with the code is difficult.
The quality of CRM Developers contractors is about 60 percent good, 40 percent bad. I don’t blame the individual contractors because they work to the agreed and existing levels. If unit tests are not part of the development process then they don’t get written.
I believe all code should be code reviewed but it’s definitely important to review contractors code because you don’t know the quality of their code. The knowledge a developers code will be reviewed will increase the quality and tidyness before any changes have been found in the code review.
Poor code survives due to the lack of code reviews and lack of Unit tests/code reviews (which often tasks removed when projects deadlines are tight). Read my blog post Why rushed projects/code doesn’t save time and reduces quality
The benefit of well designed classes offers long terms benefits when interacting with the code. The long term benefits won’t benefit the contractor who is usually not working on the project after the release.
No Unit Tests
No unit tests leads to the attitude of “if it ain’t broke don’t fix it”. This is understandable when it’s difficult to test if code changes have broken anything.
When unit tests are written developers can change the code and test their code changes haven’t broken anything.
- Why CRM Developers should unit test their code
- Unit tests are a vital part of emerging code design
- Information to Get started with Unit Testing with Microsoft Fakes and Microsoft Dynamics CRM 2013
It easier to create poorly written code in one or two big methods than it is to create small classes/functions. Most CRM developers get the code working and then if there is time, tidy up the code.
It’s quicker to create code in one big method, the developer has nothing to think about apart from creating the code.
This method of writing code creates technical debt and fragile code. The debt of the code will start to eat away developers time whenever they need to understand the code, maintain or extend.
Understanding bad code is is like trying to find things in a messy teenagers bedroom, stuff everywhere and in an order only known to the owner of the room.
Changing bad code is like playing Jenga, changing one bit of code could bring down the whole tower
If all the plugins in a project are poorly written there can be some pressure on the developer to create the plugin in the same way and some CRM developers can question the adding of lots of new classes!
It doesn’t make sense to create code which is badly structured, it’s hard to understand and it can’t be tested. Simple plugins can create code with one or two longs methods with multiple nested if statements and end up confusing.
The fact no code can be reused seems plain crazy, particularly when you consider a lot ofthe code is written using core CRM entities which exist in most CRM projects,
Look at your own plugin code
look at the code you have written recently, how well structured is the code, how reusable is it is
Look in your current CRM projects, how many classes are there
- How many classes?
- How long are your methods?
- Could the code be split up into smaller classes
- What is the average size of the classes and methods
- Are the classes well named? (badly named classes/methods hides code doing many thing not a single thing.
- Are the CRM queries in separate classes or mixed with other code?
- How reusable is the code?
How Fragile is your code?
A great way to test the fragility of your code is to ask yourself a question
- What happens if the business logic is changed
- What happens if the a new type is added
- What happens if I have to change this plugin
If your code is fragile changing one part of the code could break other parts of the code. If your plugin code is contained in one or two large methods then the code dependency is high, changing one or two lines could break the whole method.
Fragile code is where a change to one part of the code breaks seemingly unrelated parts of the code.
Is your code designed to minimise the effects of change, e.g. low coupling with independent/modular code.
Look at your plugin code, imagine its going to change and answer these questions
- Is the code easy to change?
- Could I add another type/business logic?
- Can I test the code will work after making the change?
- What is dependent on this code?
It’s an interesting exercise predicting the effects of change on your code and it will provide a warning for areas of code. You need to factor in the likehood of changes in that area of code. It’s interesting to do this after the code has been written but very useful to do when you are designing and creating the code the first time. Which is where the OO design principle came from
Encapsulate What Varies
Here are a couple of interesting articles on the Encapsulate what varies
Find What Is Varying and Encapsulate It
Steve Row – Encapsulate What Varies
finally this article on Object Orientated Principles is great
I shall leave you with these thoughts
Code should be high quality and low in quantity.
No copying and pasting, no duplication.
less code, less places for bugs to hide
Reblogged this on Dynamics CRM and commented:
I couln’t agree more with you Ben!
This is marvelous, I totally agree on following SOLID practices. What about the file size Ben? Having smaller classes will lead to have multiple classes, do you think the size of the overall plugin would matter? Thanks!
Do you have any exemplo of solid plugin for dynamics in github?