Mert Özen Further With Every Line

Blog

Mert Özen's blog posts on software development, backend, frontend, and DevOps.

Series
26 posts found #design-patterns
Anti-Patterns: God Object, Service Locator, Singleton Abuse, Anemic Domain Model and Patternitis
Software Design PART 24

Anti-Patterns: God Object, Service Locator, Singleton Abuse, Anemic Domain Model and Patternitis

An anti-pattern is a solution that looks reasonable at first but produces the same trouble again and again, and recognizing one means knowing the refactoring that moves it to a better structure. The dependency Service Locator hides from ValidateOnBuild, a God Object measured with CA1506, singleton tests that break depending on order, an anemic model whose rule gets bypassed, Golden Hammer, Lava Flow, Poltergeist and patternitis.

7 Nov 2026 14 min 6
Visitor Pattern: Double Dispatch, ExpressionVisitor and a Comparison with Pattern Matching
Software Design PART 23

Visitor Pattern: Double Dispatch, ExpressionVisitor and a Comparison with Pattern Matching

Visitor doubles C#'s one-dimensional virtual dispatch through Accept and Visit calls, letting you add new operations to a stable type hierarchy without touching the elements; the price is that a new type breaks every visitor. The static-type trap of overload resolution, the expression problem, ExpressionVisitor and Roslyn's CSharpSyntaxWalker, and a comparison with switch expressions that have no exhaustiveness check.

7 Nov 2026 12 min 3
Template Method Pattern: Algorithm Skeletons, Hooks and the Delegate-Based Alternative
Software Design PART 22

Template Method Pattern: Algorithm Skeletons, Hooks and the Delegate-Based Alternative

Template Method fixes an algorithm's skeleton in a non-overridable base class method and leaves the varying steps to abstract methods or empty hooks. The hook silently skipped by a forgotten override (CS0114), Stream.CopyTo and BackgroundService.ExecuteAsync whose behavior changed in .NET 10, the virtual-call-in-constructor trap (CA2214), and building the same flow with delegates through composition.

7 Nov 2026 13 min 7
Strategy Pattern in Depth: Keyed Services, IEnumerable<IStrategy> and Func for Runtime Selection
Software Design PART 21

Strategy Pattern in Depth: Keyed Services, IEnumerable<IStrategy> and Func for Runtime Selection

Writing a strategy is easy; choosing the right one at runtime is the hard part: keyed services select by a single key, IEnumerable<IStrategy> with CanHandle looks at several properties of the object, and Dictionary<string, Func<>> selects with the least ceremony when formulas have no dependencies. How registration order silently changes prices, why keyed registrations don't show up in GetServices, and IComparer and StringComparer as strategies in the BCL.

7 Nov 2026 12 min 4
Observer Pattern in Depth: event, IObservable<T>, IChangeToken and Domain Events
Software Design PART 19

Observer Pattern in Depth: event, IObservable<T>, IChangeToken and Domain Events

Observer means that the objects depending on an object are notified when its state changes; in C# you meet it as event, in the BCL as IObservable<T>/IObserver<T>, and in ASP.NET Core as IChangeToken and IOptionsMonitor. Starting from a phantom confirmation email sent by an event raised before the save, we study the OnNext/OnError/OnCompleted contract, Rx.NET operators, single-use change tokens and domain events dispatched in isolation after the save, all with real output.

7 Nov 2026 11 min 7
Memento Pattern: Taking Snapshots, Restoring and Keeping Encapsulation
Software Design PART 18

Memento Pattern: Taking Snapshots, Restoring and Keeping Encapsulation

Memento lets you take an object's internal state out without breaking encapsulation and restore it later; in C# the cleanest way is a private nested record plus a narrow interface shown to the caretaker. With real output we look at the shallow-copy trap of the with expression, a capacity-limited undo in the checkout wizard, Utf8JsonReader's JsonReaderState, undo with Command, versioning snapshots written to JSON, and the memory difference immutable state makes.

7 Nov 2026 12 min 6
Mediator Pattern: Centralizing Object Conversations and "Do I Really Need MediatR?"
Software Design PART 17

Mediator Pattern: Centralizing Object Conversations and "Do I Really Need MediatR?"

Mediator gathers the interaction rules of components that call each other directly into one object; MediatR is less this pattern than an in-process dispatcher that finds a handler by request type. We fix the bug produced by checkout components that know each other with a CheckoutForm mediator, study Blazor's EditContext as a real example, then write the same order placement with MediatR 14.3, a plain service class and our own 30-line dispatcher and compare them.

7 Nov 2026 13 min 3
Iterator and Interpreter: Two Patterns Built into C# — yield return and Expression Trees
Software Design PART 16

Iterator and Interpreter: Two Patterns Built into C# — yield return and Expression Trees

Iterator lets you walk a collection's elements in order without exposing its internals, and in C# it is built into the language as IEnumerable, IEnumerator and yield return; Interpreter represents a small language's grammar as an AST and evaluates it. With real output we read a paged catalog API with yield and IAsyncEnumerable, write a small promotion rule language and compile it to an expression tree, look at the interpreter inside Regex and draw the security boundary for dynamic expressions.

7 Nov 2026 14 min 10
Command Pattern: Turning Requests into Objects, Undo/Redo and Queuing
Software Design PART 15

Command Pattern: Turning Requests into Objects, Undo/Redo and Queuing

Command packages a request as an object, so an invoker can run it, undo it, queue it and log it without knowing what it does. An undo/redo stack and a MacroCommand in Bookstore's catalog editor, System.Windows.Input.ICommand in the BCL, serializing commands with System.Text.Json and running them in the background through a Channel, how a GoF command differs from a CQRS command, MediatR 13's license and a library-free dispatcher.

7 Nov 2026 14 min 7
Chain of Responsibility: ASP.NET Core Middleware, DelegatingHandler and Validation Chains
Software Design PART 14

Chain of Responsibility: ASP.NET Core Middleware, DelegatingHandler and Validation Chains

Chain of Responsibility passes a request along a chain of handlers until one handles it, breaking the coupling between sender and receiver; ASP.NET Core middleware and DelegatingHandler are short-circuiting forms of the pattern. A discount approval chain in Bookstore, the hidden business rule carried by IEnumerable registration order in DI, a validation chain that stops at the first error versus a pipeline that collects everything, and the trap of a request falling off the end of the chain.

7 Nov 2026 14 min 6
Proxy Pattern: Lazy Loading, Remote Proxies and Intercepting with DispatchProxy
Software Design PART 13

Proxy Pattern: Lazy Loading, Remote Proxies and Intercepting with DispatchProxy

A proxy implements the same interface as the real object and controls access to it: it defers creation (virtual), checks permissions (protection), represents a remote service (remote) or does extra work on access (smart reference). EF Core's Castle.Proxies.AuthorProxy and the N+1 it hides, a virtual proxy with Lazy<T>, typed HttpClients as remote proxies, DispatchProxy's async and TargetInvocationException pitfalls, and how it differs from Decorator.

7 Nov 2026 15 min 4
Flyweight Pattern: Saving Memory with Shared State — string.Intern and ArrayPool
Software Design PART 12

Flyweight Pattern: Saving Memory with Shared State — string.Intern and ArrayPool

Flyweight stores the repeating, immutable part of many objects (intrinsic state) once through a factory and shares it, keeping the line-specific part (extrinsic state) outside. A BookInfoFactory that cuts a million-line report from 377 MB to 30 MB, the side effects of string.Intern, the Task and array instances .NET already shares, why ArrayPool is an object pool rather than a flyweight, and BenchmarkDotNet measurements.

7 Nov 2026 14 min 4
Blog Map