Skip to main content
added 214 characters in body
Source Link
user204677
user204677

I was that kind of outspoken young guy insisting on using profilers, writing tests, etc, preparing lengthy presentations which often had some colleagues rolling their eyes. In retrospect I was also rather dogmatic since I saw the existing codebase as the worst thing imaginable and in the foulest ways that Michael Feathers himself probably might not have anticipated. He talked about monster methods spanning a couple hundred lines of code. Let's talk about countless C functions that span over 20,000 lines of code with sporadic goto statements, over 400 variables all declared at the top of the function and uninitialized, and colleagues that get pissed off if you initialize them to try to make the runtime behavior more deterministic while swimming through uninitialized variable bugs because they're afraid of the computational cost of initializing a plain old data type (ignoring the fact that optimizing compilers will generally optimize away redundant initialization). There was a repeatedly echoed policy to not fix what isn't broken but, when examining the nature of the codebase, the fact that each new version of the software often introduced more bugs than it fixed, and the lack of testing, often begged the question of how to effectively tell what wasn't broken.

I was that kind of outspoken young guy insisting on using profilers, writing tests, etc, preparing lengthy presentations which often had some colleagues rolling their eyes. In retrospect I was also rather dogmatic since I saw the existing codebase as the worst thing imaginable and in the foulest ways that Michael Feathers himself probably might not have anticipated. He talked about monster methods spanning a couple hundred lines of code. Let's talk about countless C functions that span over 20,000 lines of code with sporadic goto statements, over 400 variables all declared at the top of the function and uninitialized, and colleagues that get pissed off if you initialize them to try to make the runtime behavior more deterministic while swimming through uninitialized variable bugs because they're afraid of the computational cost of initializing a plain old data type (ignoring the fact that optimizing compilers will generally optimize away redundant initialization).

I was that kind of outspoken young guy insisting on using profilers, writing tests, etc, preparing lengthy presentations which often had some colleagues rolling their eyes. In retrospect I was also rather dogmatic since I saw the existing codebase as the worst thing imaginable and in the foulest ways that Michael Feathers himself probably might not have anticipated. He talked about monster methods spanning a couple hundred lines of code. Let's talk about countless C functions that span over 20,000 lines of code with sporadic goto statements, over 400 variables all declared at the top of the function and uninitialized, and colleagues that get pissed off if you initialize them to try to make the runtime behavior more deterministic while swimming through uninitialized variable bugs because they're afraid of the computational cost of initializing a plain old data type (ignoring the fact that optimizing compilers will generally optimize away redundant initialization). There was a repeatedly echoed policy to not fix what isn't broken but, when examining the nature of the codebase, the fact that each new version of the software often introduced more bugs than it fixed, and the lack of testing, often begged the question of how to effectively tell what wasn't broken.

added 299 characters in body
Source Link
user204677
user204677

Anyway, for a start, monoliths or God objects start to undermine coupling and cohesion in a similar way as having a bunch of global variables. When your program is tripping over state management and finding it cannot effectively maintain invariants, then the difficulty of correcting those issues is proportional to the scope/visibility of the state involved. Just as a global variable might be accessed by hundreds of functions, so too might a class member if the class has hundreds of methods which have access to this persistent state. If the state violates a conceptual invariant and causes bugs, then your list of suspects is proportional to the number of functions that can modify the state, class methods or not. Explaining things this way might convince your colleagues to take it easy on the God objects and start hoisting functions out of a class that do not need access to the class's internals as a compromise. As an extreme example, if the entirety of your codebase's functionality was offered by a single God class, then it would be no more capable of effectively maintaining invariants over its private state than the worst C codebase using nothing but global variables for everything. From a practical debugging standpoint, the first priority to making things sane is typically to simplify state management and be able to confidently maintain invariants. That precedes even principles like SOLID if you have a horrific legacy codebase that's repeatedly encountering invalid states to first get its state management under control.

Anyway, for a start, monoliths or God objects start to undermine coupling and cohesion in a similar way as having a bunch of global variables. When your program is tripping over state management and finding it cannot effectively maintain invariants, then the difficulty of correcting those issues is proportional to the scope/visibility of the state involved. Just as a global variable might be accessed by hundreds of functions, so too might a class member if the class has hundreds of methods which have access to this persistent state. If the state violates a conceptual invariant and causes bugs, then your list of suspects is proportional to the number of functions that can modify the state, class methods or not. Explaining things this way might convince your colleagues to take it easy on the God objects and start hoisting functions out of a class that do not need access to the class's internals as a compromise. As an extreme example, if the entirety of your codebase's functionality was offered by a single God class, then it would be no more capable of effectively maintaining invariants over its private state than the worst C codebase using nothing but global variables for everything.

Anyway, for a start, monoliths or God objects start to undermine coupling and cohesion in a similar way as having a bunch of global variables. When your program is tripping over state management and finding it cannot effectively maintain invariants, then the difficulty of correcting those issues is proportional to the scope/visibility of the state involved. Just as a global variable might be accessed by hundreds of functions, so too might a class member if the class has hundreds of methods which have access to this persistent state. If the state violates a conceptual invariant and causes bugs, then your list of suspects is proportional to the number of functions that can modify the state, class methods or not. Explaining things this way might convince your colleagues to take it easy on the God objects and start hoisting functions out of a class that do not need access to the class's internals as a compromise. As an extreme example, if the entirety of your codebase's functionality was offered by a single God class, then it would be no more capable of effectively maintaining invariants over its private state than the worst C codebase using nothing but global variables for everything. From a practical debugging standpoint, the first priority to making things sane is typically to simplify state management and be able to confidently maintain invariants. That precedes even principles like SOLID if you have a horrific legacy codebase that's repeatedly encountering invalid states to first get its state management under control.

edited body
Source Link
user204677
user204677

Anyway, for a start, monoliths or God objects start to undermine coupling and cohesion in a similar way as having a bunch of global variables. When your program is tripping over state management and finding it cannot effectively maintain invariants, then the difficulty of correcting those issues is proportional to the scope/visibility of the state involved. Just as a global variable might be accessed by hundreds of functions, so too might a class member if the class has hundreds of methods which have access to this persistent state. If the state violates a conceptual invariant and causes bugs, then your list of suspects is proportional to the number of functions that can modify the state, class methods or not. Explaining things this way might convince your colleagues to take it easy on the God objects and start hoisting functions out of a class that do not need access to the class's internals as a compromise. As an extreme example, if the entirety of your codebase's functionality was offered by a simple godsingle God class, then it would be no more capable of effectively maintaining invariants over its private state than the worst C codebase using nothing but global variables for everything.

Anyway, for a start, monoliths or God objects start to undermine coupling and cohesion in a similar way as having a bunch of global variables. When your program is tripping over state management and finding it cannot effectively maintain invariants, then the difficulty of correcting those issues is proportional to the scope/visibility of the state involved. Just as a global variable might be accessed by hundreds of functions, so too might a class member if the class has hundreds of methods which have access to this persistent state. If the state violates a conceptual invariant and causes bugs, then your list of suspects is proportional to the number of functions that can modify the state, class methods or not. Explaining things this way might convince your colleagues to take it easy on the God objects and start hoisting functions out of a class that do not need access to the class's internals as a compromise. As an extreme example, if the entirety of your codebase's functionality was offered by a simple god class, then it would be no more capable of effectively maintaining invariants over its private state than the worst C codebase using nothing but global variables for everything.

Anyway, for a start, monoliths or God objects start to undermine coupling and cohesion in a similar way as having a bunch of global variables. When your program is tripping over state management and finding it cannot effectively maintain invariants, then the difficulty of correcting those issues is proportional to the scope/visibility of the state involved. Just as a global variable might be accessed by hundreds of functions, so too might a class member if the class has hundreds of methods which have access to this persistent state. If the state violates a conceptual invariant and causes bugs, then your list of suspects is proportional to the number of functions that can modify the state, class methods or not. Explaining things this way might convince your colleagues to take it easy on the God objects and start hoisting functions out of a class that do not need access to the class's internals as a compromise. As an extreme example, if the entirety of your codebase's functionality was offered by a single God class, then it would be no more capable of effectively maintaining invariants over its private state than the worst C codebase using nothing but global variables for everything.

added 274 characters in body
Source Link
user204677
user204677
Loading
added 243 characters in body
Source Link
user204677
user204677
Loading
Minor corrections.
Source Link
user204677
user204677
Loading
Source Link
user204677
user204677
Loading