COSC 310: Design Patterns and Anti-Patterns

SOLID Principles Overview

  • Single Responsibility Principle (SRP)

    • A class should have only one reason to change, meaning it should have only one job.

    • Ensures high cohesion and low coupling.

  • Open/Closed Principle (OCP)

    • Software entities (classes, modules, functions) should be open for extension but closed for modification.

  • Liskov Substitution Principle (LSP)

    • Objects of a superclass should be replaceable with objects of a subclass without affecting the correctness of the program.

  • Interface Segregation Principle (ISP)

    • No client should be forced to depend on methods it does not use.

  • Dependency Inversion Principle (DIP)

    • High-level modules should not depend on low-level modules but should depend on abstractions (e.g. interfaces).

Open/Closed Principle in Practice

  • Example: Violations in code with multiple animal classes doing their specific sounds directly.

  • To conform to OCP, use interfaces and polymorphism (e.g., AnimalInterface with method makeSound() to define behaviors of various animals).

Dependency Inversion Principle Example

  • UserProfile Class

    • Should rely on an interface rather than a concrete class.

    • Example: Does not depend on CacheStore directly but on CacheStoreInterface.

Objectives of Learning Design Patterns

  • Understand design patterns to solve recurring software design problems.

  • Familiarity with creational, structural, and behavioral design pattern categories.

  • Know the key elements of a pattern: name, problem, solution, and consequences.

  • Be aware of common anti-patterns such as BBoM, god object, golden hammer, etc.

  • Recognize and adapt patterns to improve software quality.

Understanding Design Patterns

  • Definition: Design patterns describe general repeatable solutions to commonly occurring problems in software design.

  • Pattern usage promotes reusability and efficiency.

    • Avoid re-inventing the wheel by leveraging established solutions.

Anti-Patterns Defined

  • An anti-pattern is a commonly used solution that appears effective initially but has negative consequences.

  • Anti-patterns can occur at various levels and lead to code quality issues, maintenance problems, etc.

  • Key Elements:

    1. It appears to be effective but harms more than helps.

    2. A documented better solution exists.

Common Anti-Patterns
  • BBoM (Big Ball of Mud): Unstructured, chaotic code that is hard to maintain.

  • God Object: An object that does too much and violates SRP, leading to tight coupling and poor cohesion.

  • Golden Hammer: Over-reliance on a specific approach or technology, ignoring better solutions.

Examples of Common Anti-Patterns

  • BBoM: Refers to unplanned growth, lack of structure, and excessive code repetition.

  • God Class: A class that centralizes too much functionality, making it hard to manage and test.

  • Golden Hammer: Using a familiar tool or method regardless of its suitability for a specific task.

Design Pattern Categories

  1. Creational Patterns: Deal with object creation mechanisms. Examples: Singleton, Factory Method.

  2. Structural Patterns: Deal with object composition. Examples: Adapter, Facade.

  3. Behavioral Patterns: Deal with communication between objects. Examples: Observer, Command.

Singleton Pattern
  • Ensures a class has only one instance, providing a global point of access.

  • Beneficial when coordination across the system is needed.

  • Problems: Tight coupling, difficulty in testing and multi-threading considerations.

Factory Method Pattern
  • Allows object creation without specifying the class.

  • Useful for flexible systems needing different object types.

  • Encourages decoupling of object creation from specific classes.

Abstract Factory Pattern
  • Produces families of related objects without specifying their concrete classes.

  • Separates code that creates product variants from the actual products.

Adapter and Facade Patterns

  • Adapter Pattern: Allows incompatible interfaces to collaborate.

  • Facade Pattern: Simplifies the interface for complex systems, providing a straightforward API.

Behavioral Patterns Detailed

Observer Pattern
  • Establishes a one-to-many dependency between objects. Updates observers when the subject changes.

  • Effective for maintaining loose coupling and flexibility in systems.

Conclusion on Design Patterns and Anti-Patterns

  • Design patterns are solutions that improve flexibility and quality in software development.

  • Anti-patterns can degrade software quality and maintainability.

  • Understanding and applying the right design patterns is crucial for software success.