The title of the Anti pattern is The Blob, the sub-title is” Doing everything all at one is a best practice”
The elaboration is read as: A class in an object-oriented system that monopolizes the processing while other classes primarily just encapsulate data. this results in software that is more complex and harder to troubleshoot and maintain.
This link provide some further reading on the anti-pattern (including interesting photo). For your convenience, I copied some here:
The Blob is an anti-pattern that describes a class which resembles the monster from the 1958 film The Blob, which absorbs anything it touches and grows larger and larger over time. Such classes are similar to God Objects and over time lose any focus they might once have had. Blob classes violate well-known OOP principles such as the Single Responsibility Principle and the Open/Closed Principle, and tend to be more expensive to maintain and lead to Big Ball of Mud systems.Rather than allow a class to expand like The Blob, refactor using Extract Class and create smaller classes that each have a single responsibility.
Quotes
For each transaction, there are 5-10 steps user need to go through to complete the transaction. Steps for different transaction category and different transaction are different and configured in a database table.
However, in the design I saw only one Window Form named as Transaction Detail Form, which is used to handle all different transactions in various steps.
Similarly in the business layer, I saw a huge class call Transaction Business Object, it has over 8 thousands line of code, close to 500 members. the highest member level of cyclomatics Complexity is over 170 (it was over 1000 when I took it over)
This is a clear case of “The Blob”, Transaction Detail Form and Transaction Business Object are two biggest Blobs among the rest.
Sure enough, it is easy to break, hard to maintain and very difficult to troubleshoot.
In object oriented design, the rules you want to follow are: 1) No repeating logic 2) no redundant functionality. In this case when a Business Object is instantiated to handle one specific step of one specific transaction, the object is much powerful than the task it is given. when you change something in the class for one specific transaction, unintentionally, the code change affect other transactions.
Wen you are in the design phase, pay attention to the rule of “one thing and one thing only”, when class handles to many functionalities, you want to break it to smaller classes. When you design class model, you want to give each class a specified scope and role in the system.
When you are given a code base like the one I had, you want to be careful bot to break existing functionality while you take effort to fix the Blob issue. What you want to do is to design a new set of object inheritance hierarchy and make the original Blob class be the base class and let the rest of code base use these sub-classes where the blob class was used originally. I am sure you want to give each sub-class a clear defined scope and role. At this point of time, all sub classes are empty. all we are doing is to create place holders for various sub classes. because there is no business logic changes, the change is less risky, even if we forgot to change some reference, it is fine, as the functionality is still in the original blob class. a good test to see if you have completed this step is making the originally blob class an abstract class. if you are able to do that without build error. you are good.
Once you are done with that, you can start to move business logic specific to certain transaction or specific to certain step to its rightful home in the newly defined object hierarchy. as you slowly making progress in this migration process, you will see the blob class start to shrink, and these empty sub-classes start to have something meaningful.
However, this is the technical aspect of the issue, to achieve what I described here you must not underestimate the non technical aspect of the issue. The leadership’s recognition of the issue and commitment to resolve the issue are critical. Like basketball game, it is a team sport, and all listen to the coach. if coach does not believe the shooter is tired or not performing well, he stays on the game. If you, as a team member, making too much noise, you might get yourself out of the game. Similarly, if the leadership does not believe this is the problem, the problem will stay. The worse thing is that the longer the problem stays the worse the problem will be and the bigger negative impact on productivity. this is what I call "too busy to do something to save time."
Quotes
"Multitasking is the art of distracting yourself from two things you you’d rather note be doing them simultaneously.”
- Anonymous
Not long ago, I came across a windows application. The application handles 3 different categories, more than 170 different transactions for a state government agency. There are distinguished business rules, processes for transactions in each category and specifically in each transaction. For each transaction, there are 5-10 steps user need to go through to complete the transaction. Steps for different transaction category and different transaction are different and configured in a database table.
However, in the design I saw only one Window Form named as Transaction Detail Form, which is used to handle all different transactions in various steps.
Similarly in the business layer, I saw a huge class call Transaction Business Object, it has over 8 thousands line of code, close to 500 members. the highest member level of cyclomatics Complexity is over 170 (it was over 1000 when I took it over)
This is a clear case of “The Blob”, Transaction Detail Form and Transaction Business Object are two biggest Blobs among the rest.
Sure enough, it is easy to break, hard to maintain and very difficult to troubleshoot.
In object oriented design, the rules you want to follow are: 1) No repeating logic 2) no redundant functionality. In this case when a Business Object is instantiated to handle one specific step of one specific transaction, the object is much powerful than the task it is given. when you change something in the class for one specific transaction, unintentionally, the code change affect other transactions.
Wen you are in the design phase, pay attention to the rule of “one thing and one thing only”, when class handles to many functionalities, you want to break it to smaller classes. When you design class model, you want to give each class a specified scope and role in the system.
When you are given a code base like the one I had, you want to be careful bot to break existing functionality while you take effort to fix the Blob issue. What you want to do is to design a new set of object inheritance hierarchy and make the original Blob class be the base class and let the rest of code base use these sub-classes where the blob class was used originally. I am sure you want to give each sub-class a clear defined scope and role. At this point of time, all sub classes are empty. all we are doing is to create place holders for various sub classes. because there is no business logic changes, the change is less risky, even if we forgot to change some reference, it is fine, as the functionality is still in the original blob class. a good test to see if you have completed this step is making the originally blob class an abstract class. if you are able to do that without build error. you are good.
Once you are done with that, you can start to move business logic specific to certain transaction or specific to certain step to its rightful home in the newly defined object hierarchy. as you slowly making progress in this migration process, you will see the blob class start to shrink, and these empty sub-classes start to have something meaningful.
However, this is the technical aspect of the issue, to achieve what I described here you must not underestimate the non technical aspect of the issue. The leadership’s recognition of the issue and commitment to resolve the issue are critical. Like basketball game, it is a team sport, and all listen to the coach. if coach does not believe the shooter is tired or not performing well, he stays on the game. If you, as a team member, making too much noise, you might get yourself out of the game. Similarly, if the leadership does not believe this is the problem, the problem will stay. The worse thing is that the longer the problem stays the worse the problem will be and the bigger negative impact on productivity. this is what I call "too busy to do something to save time."
Peter - Very well said the issue. I like most of your direction and comments very much. Thanks for everything.
ReplyDeleteSenthil K