Monster file single-handedly implements large blocks of functionality within a system and performs multiple, non-cohesive functionalities. It violates the basic approach of structured programming which is: Break a big problem into smaller problems and then resolve these problems. The result obtained inevitably solves the big problem. The monster file typically has high LOC, high LCOM, high CC, and a higher count of functions.
Impact
- The Monster file tends to become bulky and complex.
- Refactoring becomes a fairly complicated task. Refactoring of such a file affects a significant part of the system, as other members of the system depend heavily on Monster File.
- The tendency to hold too much non-cohesive functionality also means this file becomes critical; making even a small change to it has a system-wide impact in terms of testing efforts.
- Time and maintenance cost increases.
Characteristics
- The file is large and complex (high LOC and many long and complex functions).
- Functions implement non-cohesive functionalities.
Example(s)
- The file is large and complex (high LOC and too many long and complex functions).
Functions implement non-cohesive functionalities.
BankAccount.js { let acInfo = []; // Cohesive methods public void openAccount(); public void closeAccount(); // Non-cohesive method (should ideally exist in Customer class) public void createCustomer();
File excessively accesses data of other files and also tends to implement logic that belongs to those files.
//File BankAccount accesses attributes of AccountInfo file // File also implements logic that should belong to AccountInfo file. public boolean isAccountValid{ if( (acInfo.isActive) && (acInfo.balance > acInfo.minimumBalance ) { return true; } return false; }
Solution: Move the logic into a method in the AccountInfo file and invoke that function.
public boolean isAccountValid() { return acInfo.isAccountValid(); }
Guidelines
- Follow the ‘one file one task’ rule. Distribute the system intelligence across several files and let one file handle only one task. Collectively they will solve the intended problem.
- Functionalities that have common, overlapping aspects but are also dissimilar in other aspects can be implemented as sibling files and the common functionality can be moved into a third file.
- If distinct groups of data-operations exist in one file, try extracting them into separate files.
- Make sure that file functions are not too long and do not use more than necessary data from other files.
- The monster file is often a result of incrementally adding functionality to an existing file over time. This should be avoided. Try refactoring the file occasionally. Split the file instead of adding new functionality.