25-Comp-B11 Advanced Software Design · December 2014
Question 18 of 26: Anti-Patterns
Nivaar worked solution (AI-drafted; not reviewed by a licensed engineer)
Notes on this paper
98-Comp-B11 Advanced Software Design — National Exams, December 2014. 3 hours, closed book, no calculator permitted. The paper is organized into five parts, and candidates were instructed to answer any three (3) questions in Part I, any four (4) in Part II, any four (4) in Part III, any two (2) in Part IV, and any two (2) in Part V — only the first questions answered, in each part, as they appear in the answer book are marked. All questions carry equal weight, so the 15 questions actually marked (3+4+4+2+2 of 26) each count for 100/15 ≈ 6.7% of the paper. All 26 questions are answered below for completeness.
Reference texts: Sommerville, Software Engineering (10th ed., Pearson) — software processes, requirements engineering, agile methods, design principles; Pressman, Software Engineering: A Practitioner's Approach (9th ed.) — supplementary process and quality coverage; Gamma, Helm, Johnson & Vlissides (GoF), Design Patterns: Elements of Reusable Object-Oriented Software — structural/behavioural pattern catalogue (Proxy, Bridge, Strategy, Observer, Template Method, Composite, etc.); Sebesta, Concepts of Programming Languages (12th ed.) — polymorphism, dynamic binding, inheritance and language-level object semantics (also underpins the Java/C++ discussion in Part V); Brown, Malveau, McCormick & Mowbray, AntiPatterns: Refactoring Software, Architectures, and Projects in Crisis — anti-pattern catalogue (Question 18). Bertrand Meyer's Object-Oriented Software Construction is cited by name where the paper's own vocabulary (design by contract, open–closed principle) originates there; Barbara Liskov's 1987 substitutability paper is likewise cited by name for Question 11.
Definition. An anti-pattern is the negative mirror of a design pattern (Question 13): a commonly-occurring, documented, NAMED solution to a recurring design problem that appears attractive or expedient in the moment — usually because it is the path of least resistance under time pressure — but that is demonstrably counterproductive, generating more technical debt, complexity, or maintenance cost than it saves. Like a genuine pattern, an anti-pattern is repeatedly observed across many independent projects (which is why it has a name at all); unlike a genuine pattern, cataloguing it is meant to help engineers RECOGNIZE and AVOID it, together with a documented refactored solution.
God Object (a.k.a. God Class / Blob). A single class accumulates a large fraction of the system's responsibilities, state, and behaviour, while most other classes become thin data holders that this one class manipulates directly. It arises because adding "just one more" responsibility to an already-central class is always locally easier than designing a proper new collaborator with its own well-defined interface (Question 12's design-goal trade-offs, resolved by always favouring short-term convenience). It is an anti-pattern because it directly violates single-responsibility and information-hiding (Question 19): the class becomes a single point of coupling for nearly every change, is difficult to unit-test in isolation (Question 19's testability argument — there is no small, focused unit left to test), and its sheer size makes it hard for any one engineer to hold its behaviour in their head, sharply raising defect rates.
Spaghetti Code. Code with no discernible control-flow structure or architecture — deeply nested conditionals, extensive reliance on shared global state, and ad hoc control transfers grown incrementally, patch by patch, with no refactoring pass to consolidate the accumulating branches. It arises for the same reason as God Object: adding another special-case branch to already-tangled code is locally the fastest way to ship one more feature, and nothing forces a stop to assess the design as a whole (exactly the architectural-erosion danger of undisciplined agile development flagged in Question 5). It is an anti-pattern because each additional patch increases the code's accidental complexity and coupling roughly combinatorially with the number of prior patches, so comprehension and defect risk grow much faster than the feature count actually delivered — eventually making even a small, well-understood change disproportionately expensive and risky to make safely.
Both qualify as anti-patterns under the same test: each is a widely-recognized, RECURRING response to a recurring problem (excess responsibility needs a home; a fixed algorithm needs one more special case) that looks like the cheapest solution in the moment, yet the documented, catalogued alternative (decompose God Object along single-responsibility lines; refactor Spaghetti Code toward Template Method/Strategy-style structured control flow, per Question 15/17) is known to cost less over the system's actual lifetime.