Tutorials Design Patterns in C#

Pattern vs Anti-Pattern — Complete Guide

Pattern vs Anti-Pattern — Complete Guide: free step-by-step lesson with examples, common mistakes, and interview tips — part of Design Patterns in C# on Toolliyo Academy.

On this page
Pattern vs Anti-Pattern — Complete Guide — ShopNest Enterprise Architecture
Article 68 of 69 · Module 8: Interview & System Design · Analytics · INTERVIEW
Target keyword: pattern vs anti-pattern c# design patterns · Read time: ~24 min · .NET: 10 · INTERVIEW · Project: ShopNest Enterprise Architecture — Analytics

Introduction

Pattern vs Anti-Pattern — Complete Guide is essential for .NET architects building ShopNest Enterprise Architecture Platform — Toolliyo's 69-article design patterns master path covering GoF creational, structural, and behavioral patterns; enterprise patterns (Repository, CQRS, Saga, Outbox); microservices; ASP.NET Core architecture; and senior interview prep. Every article includes minimum two mandatory real-world examples.

In Indian delivery projects (TCS, Infosys, Wipro), interviewers expect pattern vs anti-pattern with real banking, e-commerce, or SaaS examples — not toy animal demos. This article delivers production depth on Analytics.

After this article you will

  • Explain Pattern vs Anti-Pattern in plain English and in enterprise architecture terms
  • Implement Pattern vs Anti-Pattern in ShopNest Enterprise Architecture (Analytics)
  • Compare anti-pattern vs production-ready pattern implementation
  • Answer fresher and senior design pattern interview questions confidently
  • Connect this lesson to Article 69 and the 69-article Design Patterns roadmap

Prerequisites

Concept deep-dive

Level 1 — Analogy

Pattern vs Anti-Pattern on ShopNest Enterprise Architecture is a proven blueprint for the Pattern vs Anti-Pattern problem in growing platforms.

Level 2 — Technical

Pattern vs Anti-Pattern builds architectural judgment — when patterns help vs hurt, how TCS/Infosys lateral interviews probe trade-offs on Analytics.

Level 3 — Architecture placement

[Client / API Gateway]
       ▼
[Application Layer — Handlers, Strategies, Commands]
       ▼
[Domain Layer — Entities, Domain Events, Specifications]
       ▼
[Infrastructure — EF Core, Message Bus, Polly, Cache]
       ▼
[Pattern Registration — Program.cs DI lifetimes]
       ▼
[xUnit + Moq — pattern behavior isolated]

Common misconceptions

❌ MYTH: Every class needs a design pattern.
✅ TRUTH: Patterns solve recurring problems — use judgment; a simple service method beats forcing Abstract Factory on a one-off.

❌ MYTH: GoF patterns are outdated in modern C#.
✅ TRUTH: The concepts persist — DI, MediatR, and Polly are modern implementations of established patterns.

❌ MYTH: More patterns always means better architecture.
✅ TRUTH: Overengineering slows teams — senior developers know when NOT to apply a pattern.

Project structure

ShopNest.EnterpriseArchitecture/
├── ShopNest.Domain/           ← Entities, domain events, interfaces
├── ShopNest.Application/      ← Commands, queries, handlers (MediatR)
├── ShopNest.Infrastructure/   ← EF Core, Redis, RabbitMQ, Polly
├── ShopNest.Api/              ← ASP.NET Core Web API + Minimal APIs
├── ShopNest.Workers/          ← Hosted services, outbox processors
└── ShopNest.Gateway/          ← YARP API Gateway

Hands-on implementation — Analytics

Implement Pattern vs Anti-Pattern in C# for Analytics: write a class or method, compile, and verify with a console or unit test.

  1. Open a console or class library project.
  2. Implement the concept in a focused class or method.
  3. Add null checks and meaningful exception messages.
  4. Run dotnet build and dotnet test.
  5. Review naming and SOLID boundaries.

Anti-pattern (god class, swallowed exceptions, magic strings)

// ❌ BAD — no pattern, tight coupling, untestable
public class OrderController : ControllerBase {
    public IActionResult Place(OrderDto dto) {
        var conn = new SqlConnection("Server=.;...");
        // direct SQL, no repository, no UoW, no error handling
        return Ok();
    }
}

Production-style C# code

// ✅ CORRECT — Pattern vs Anti-Pattern on ShopNest (Analytics)
public sealed class PlaceOrderHandler(
    IOrderRepository repo,
    IUnitOfWork uow,
    IPublisher events) : IRequestHandler<PlaceOrderCommand, Result<int>>
{
    public async Task<Result<int>> Handle(PlaceOrderCommand cmd, CancellationToken ct) {
        var order = Order.Create(cmd.CustomerId, cmd.Lines);
        await repo.AddAsync(order, ct);
        await events.Publish(new OrderPlacedEvent(order.Id), ct);
        await uow.SaveChangesAsync(ct);
        return Result.Success(order.Id);
    }
}

Complete example

// Pattern vs Anti-Pattern
// Judgment: pattern cost vs benefit on ShopNest Analytics

Real-World Example 1 — Notification Delivery Service

MANDATORY: Enterprise-grade Pattern vs Anti-Pattern implementation in a production notification delivery service.

Business requirement

Email, SMS, and push notifications must be delivered reliably even when downstream providers are down or rate-limited.

Why Pattern vs Anti-Pattern is needed

Without Pattern vs Anti-Pattern, the Notification Delivery Service team at ShopNest faces tight coupling, untestable code, and painful refactors every sprint. Pattern vs Anti-Pattern decouples responsibilities so the Analytics module can evolve independently while meeting scalability and compliance requirements.

Architecture

[Client/API] → [Pattern vs Anti-Pattern Abstraction]
  → [ShopNest.Analytics Service] → [EF Core / Redis / Message Bus]
  → [Downstream: Audit, Notifications, Reporting]

Tech stack: Outbox pattern, RabbitMQ, background workers, retry with exponential backoff

Full working code

// REAL-WORLD EXAMPLE 1: Notification Delivery Service
// ShopNest Enterprise Architecture — Analytics module
// Pattern: Pattern vs Anti-Pattern

namespace ShopNest.Architecture.Analytics;

public interface IPatternvsAnti-PatternService
{
    Task ExecuteAsync(PatternvsAnti-PatternRequest request, CancellationToken ct = default);
}

public sealed class NotificationDeliveryServicePatternvsAnti-PatternService : IPatternvsAnti-PatternService
{
    private readonly ILogger _logger;

    public NotificationDeliveryServicePatternvsAnti-PatternService(ILogger logger)
        => _logger = logger;

    public async Task ExecuteAsync(PatternvsAnti-PatternRequest request, CancellationToken ct)
    {
        _logger.LogInformation("[Pattern vs Anti-Pattern] Processing {Domain} request {Id}",
            "Notification Delivery Service", request.Id);

        // Production implementation — see Program.cs for DI registration
        await Task.Delay(10, ct);
        return Result.Success(request.Id);
    }
}

// Register in Program.cs:
// builder.Services.AddScoped();

Benefits achieved

  • Loose coupling — swap implementations without changing controllers
  • Unit testable — mock IPatternService in xUnit tests
  • Scalable — horizontal scaling of Analytics workers under load
  • Maintainable — new business rules added via new classes, not if-else chains

Real-World Example 2 — Financial Trading Platform

MANDATORY: Second complete example in a different domain — Financial Trading Platform.

Business problem

Every trade action must be recorded as an immutable event for audit, replay, and regulatory reporting.

Why Pattern vs Anti-Pattern solves it

In Financial Trading Platform, Indian IT delivery teams (TCS, Infosys, Wipro lateral rounds) frequently ask how Pattern vs Anti-Pattern applies to distributed systems. This example shows production-level implementation with ASP.NET Core integration, not toy animal/car demos.

Production implementation

// REAL-WORLD EXAMPLE 2: Financial Trading Platform
// ShopNest Enterprise Architecture — Analytics module
// Pattern: Pattern vs Anti-Pattern

namespace ShopNest.Architecture.Analytics;

public interface IPatternvsAnti-PatternService
{
    Task ExecuteAsync(PatternvsAnti-PatternRequest request, CancellationToken ct = default);
}

public sealed class FinancialTradingPlatformPatternvsAnti-PatternService : IPatternvsAnti-PatternService
{
    private readonly ILogger _logger;

    public FinancialTradingPlatformPatternvsAnti-PatternService(ILogger logger)
        => _logger = logger;

    public async Task ExecuteAsync(PatternvsAnti-PatternRequest request, CancellationToken ct)
    {
        _logger.LogInformation("[Pattern vs Anti-Pattern] Processing {Domain} request {Id}",
            "Financial Trading Platform", request.Id);

        // Production implementation — see Program.cs for DI registration
        await Task.Delay(10, ct);
        return Result.Success(request.Id);
    }
}

// Register in Program.cs:
// builder.Services.AddScoped();

Scalability benefits

  • Supports multi-region deployment on Azure with independent scaling
  • Integrates with ShopNest distributed events (RabbitMQ) for async workflows
  • Redis caching reduces database load for read-heavy Financial operations
  • Polly resilience policies handle transient failures in cloud-native environments
Interview tip: Always describe Pattern vs Anti-Pattern using TWO domains — e.g. "Notification Delivery Service" AND "Financial Trading Platform" — to demonstrate real production experience.

Pattern variations & ASP.NET Core integration

Modern C# 14 uses primary constructors, records, and DI. Register Pattern vs Anti-Pattern abstractions in Program.cs with appropriate lifetimes — Singleton for stateless, Scoped for request-bound, Transient for lightweight factories.

Microservices: Apply Pattern vs Anti-Pattern within bounded contexts — each ShopNest service (Analytics) owns its implementation.

Pattern comparison & when NOT to use

Compare Pattern vs Anti-Pattern with similar patterns. Avoid overengineering — if a simple function or DI registration suffices, do not force a pattern. Senior architects value judgment over pattern count.

Unit testing the pattern

public class PatternvsAnti-PatternPatternTests
{
    [Fact]
    public async Task ExecuteAsync_ReturnsSuccess()
    {
        var mock = new Mock<IPatternvsAnti-PatternService>();
        mock.Setup(s => s.ExecuteAsync(default)).ReturnsAsync(Result.Success());
        var result = await mock.Object.ExecuteAsync(default);
        Assert.True(result.IsSuccess);
    }
}

Pattern recognition

Object creation pain → Creational. Composing subsystems → Structural. Algorithm/communication variation → Behavioral. Persistence/messaging → Enterprise. Multi-service → Cloud patterns. ASP.NET pipeline → Middleware/Options/Hosted Service.

Architectural judgment

Senior interviewers reward trade-off analysis over pattern name-dropping. Always answer: problem → options → chosen pattern → alternatives rejected → metrics you'd monitor.

Common errors & fixes

  • Singleton with mutable state shared across requests — Use Singleton only for stateless services; keep request state Scoped.
  • Factory explosion — new class per trivial variation — Use Strategy or simple DI when behavior differs slightly, not Abstract Factory.
  • Repository wrapping every EF call without domain logic — Repository adds value for testability and query composition — not as a pass-through.
  • Saga/CQRS on a CRUD app with 3 tables — Start with simple layered architecture; add patterns when complexity demands.

Best practices

  • 🟢 Name patterns by problem solved, not GoF catalog page number
  • 🟢 Register abstractions in DI — depend on interfaces, not concretions
  • 🟡 Match DI lifetime to pattern (Singleton vs Scoped)
  • 🟡 Write one xUnit test proving the pattern's core behavior
  • 🔴 Do not apply Saga/CQRS/Event Sourcing on simple CRUD
  • 🔴 Document when you chose NOT to use a pattern — interviews love this

Interview questions

Fresher level

Q1: What is the Pattern vs Anti-Pattern pattern and when would you use it?
A: Pattern vs Anti-Pattern solves a specific recurring problem on ShopNest Analytics. Explain intent, structure (participants), and one real example — then state when NOT to use it.

Q2: Pattern vs Anti-Pattern vs similar patterns — how do you choose?
A: Compare intent and consequences; e.g. Strategy vs State, Repository vs DAO, Mediator vs Observer — pick by change axis.

Q3: How do design patterns relate to SOLID?
A: Patterns implement SOLID — Strategy/OCP, Repository/DIP, SRP via focused classes. SOLID is why; patterns are how.

Mid / senior level

Q4: Repository pattern — benefits and pitfalls?
A: Benefits: testability, query composition. Pitfalls: leaky abstraction, generic repo anti-pattern, duplicating EF features.

Q5: When would you NOT use a design pattern?
A: Simple CRUD, prototypes, or single-developer utilities — YAGNI until complexity appears.

Q6: How are patterns asked in TCS/Infosys lateral interviews?
A: Scenario-based: "Design payment retry" → Retry + Circuit Breaker; "Split monolith" → Strangler + API Gateway.

Coding round

Implement Pattern vs Anti-Pattern for ShopNest Analytics: interface, concrete class, DI registration, and xUnit test with Moq.

builder.Services.AddScoped<IPatternvsAnti-PatternService, PatternvsAnti-PatternService>();

public sealed class PatternvsAnti-PatternService : IPatternvsAnti-PatternService
{
    public Task<Result> ExecuteAsync(CancellationToken ct) => Task.FromResult(Result.Success());
}

Summary & next steps

  • Article 68: Pattern vs Anti-Pattern — Complete Guide
  • Module: Module 8: Interview & System Design · Level: INTERMEDIATE · Type: INTERVIEW
  • Applied to ShopNest Enterprise Architecture — Analytics

Previous: Overengineering Problems in Enterprise Applications — Complete Guide
Next: Refactoring Legacy Code Using Design Patterns — Complete Guide

Practice: Apply today's pattern in one module — commit with feat(patterns): article-68.

FAQ

Q1: What is Pattern vs Anti-Pattern?

Pattern vs Anti-Pattern helps ShopNest Enterprise Architecture implement Analytics with maintainable, testable C# structure.

Q2: Do I need to memorize all GoF patterns?

No — understand ~15 commonly used ones (Singleton, Factory, Strategy, Observer, Decorator, Repository, CQRS) deeply.

Q3: Is this asked in Indian IT interviews?

Yes — creational/behavioral basics in campus drives; enterprise and microservice patterns in lateral and architect rounds.

Q4: Which .NET version?

Examples target .NET 10 with C# 14, ASP.NET Core DI, MediatR, and Polly.

Q5: How does this fit ShopNest?

Article 68 applies Pattern vs Anti-Pattern to Analytics. By Article 69 you architect enterprise systems with sound judgment.

Questions on this lesson 0

Sign in to ask a question or upvote helpful answers.

No questions yet — be the first to ask!

Design Patterns in C#
Course syllabus

Design Patterns in C# Tutorial

Module 1: Creational Design Patterns
Module 2: Structural Design Patterns
Module 3: Behavioral Design Patterns
Module 4: Enterprise Design Patterns
Module 5: Modern Enterprise Patterns
Module 6: Microservices & Cloud Patterns
Module 7: ASP.NET Core Architecture Patterns
Module 8: Interview & System Design
Toolliyo Assistant
Ask about tutorials, ebooks, training, pricing, mentor services, and support. I use public site content only—not admin or internal tools.

care@toolliyo.com

Need callback? Share your details