Skip to content

Chapter 6 of 6

Beyond Patterns: Principles, Anti-Patterns, and Choosing Well

Several broader design principles complement the individual patterns and the SOLID guidelines. Composition over Inheritance favors assembling objects through has-a relationships rather than inheriting behavior through is-a ones. Composition avoids tight coupling to parent classes, allows behavior to be changed at runtime, prevents deep and fragile inheritance hierarchies, and makes it easier to substitute mock objects in tests. Many of the patterns already discussed, including Strategy, Decorator, Observer, and Bridge, embody this principle by relying on composition rather than inheritance to extend behavior.

The Hollywood Principle captures the idea that high-level components should control the flow of a program and call low-level components, rather than the reverse. It is often phrased as "don't call us, we'll call you." Template Method demonstrates this by having a base class call subclass hooks, while Observer does so by having the subject call its observers, and Dependency Injection does so by having a framework call into application code. The closely related idea of Inversion of Control generalizes the same idea: control flow is inverted so that a framework calls your code instead of your code calling the framework. Common implementations include Dependency Injection, Template Method, and event-driven systems, and IoC containers such as Spring, Laravel, and the .NET DI host manage this inversion for entire applications.

Anti-patterns are common solutions that look attractive but are actually counterproductive. The God Object, sometimes called God Class, is one of the most damaging: a single class that knows too much and does too much, with thousands of lines of code, dozens of methods spanning different concerns, and many dependencies. It violates SRP by definition. The fix is to extract responsibilities into separate classes following SRP, optionally introducing a Facade to preserve a simplified entry point for clients, and refactoring incrementally with tests as a safety net. Other well-known anti-patterns include Spaghetti Code, where logic is tangled and unstructured; the Golden Hammer, in which a single familiar solution is applied to every problem; Lava Flow, in which dead code is left in place because nobody dares to remove it; and Copy-Paste Programming, where code is duplicated instead of being properly abstracted. Recognizing these patterns is the first step toward refactoring them away.

Choosing the right pattern is a matter of judgment rather than rule-following. The most useful guideline is to identify what varies in a design and encapsulate that variation, which often points directly to one or two candidate patterns. Match the problem to a pattern's intent rather than its structure, and resist the temptation to force a pattern into a place where it does not solve a real problem. The SOLID principles serve as a useful compass for narrowing down the choice. Start simple and refactor toward patterns only as complexity grows; over-engineering with patterns is itself an anti-pattern, sometimes called Pattern-itis. In the end, patterns are tools that serve clear thinking about software design, not ends in themselves.

All chapters
  1. 1Foundations of Design Patterns
  2. 2Creational Patterns
  3. 3Structural Patterns
  4. 4Behavioral Patterns
  5. 5The SOLID Principles
  6. 6Beyond Patterns: Principles, Anti-Patterns, and Choosing Well

Drill it

Reading is not remembering. These come from the Design Patterns deck:

Q

What are Design Patterns in software engineering?

Design patterns are reusable solutions to commonly occurring problems in software design. They were popularized by the Gang of Four (GoF) in their 1994 book. Th...

Q

What are the three categories of GoF Design Patterns?

The three categories are:Creational Patterns – Deal with object creation mechanisms (e.g., Singleton, Factory Method, Builder)Structural Patterns – Deal with ob...

Q

What is the Singleton pattern?

The Singleton pattern ensures a class has only one instance and provides a global point of access to it.Key traits:Private constructorStatic method to get the i...

Q

What are the drawbacks of the Singleton pattern?

Singleton drawbacks include:Introduces global state, making code harder to testViolates the Single Responsibility Principle (manages its own lifecycle)Thread sa...