# Simplifying Conditional Expressions

> Techniques that flatten, name, merge and replace conditionals so branching logic reads as a list of plain decisions.

- kind: category
- category: refactoring
- canonical: https://aipatterns.dev/refactoring/techniques/simplifying-conditional-expressions
- inspired-by: https://refactoring.guru/refactoring/techniques/simplifying-conditional-expressions

## What these techniques solve

Conditionals grow by accretion. Each bug fix adds a clause, each feature adds a branch, and the result is nested `if` blocks with duplicated tails, control flags and null checks scattered across callers. These techniques make each decision explicit, remove repetition between branches, and move type-based branching into the types themselves.

**A reader should see the normal path first and each exception as one named, early decision.**

## Members

- [Decompose Conditional](https://aipatterns.dev/refactoring/techniques/decompose-conditional.md): extract the condition and each branch body into well-named methods.
- [Consolidate Conditional Expression](https://aipatterns.dev/refactoring/techniques/consolidate-conditional-expression.md): merge several checks that lead to the same result into one named condition.
- [Consolidate Duplicate Conditional Fragments](https://aipatterns.dev/refactoring/techniques/consolidate-duplicate-conditional-fragments.md): move code that runs in every branch outside the conditional.
- [Remove Control Flag](https://aipatterns.dev/refactoring/techniques/remove-control-flag.md): replace a boolean that steers a loop with `break`, `continue` or `return`.
- [Replace Nested Conditional with Guard Clauses](https://aipatterns.dev/refactoring/techniques/replace-nested-conditional-with-guard-clauses.md): handle special cases with early returns so the main path isn't nested.
- [Replace Conditional with Polymorphism](https://aipatterns.dev/refactoring/techniques/replace-conditional-with-polymorphism.md): move each branch of a type-based conditional into a method on the matching subclass or strategy.
- [Introduce Null Object](https://aipatterns.dev/refactoring/techniques/introduce-null-object.md): return an object with safe default behavior instead of `null`, so callers stop checking.
- [Introduce Assertion](https://aipatterns.dev/refactoring/techniques/introduce-assertion.md): make an assumption the code already relies on explicit with an assertion.

## How to choose within this category

- **The condition itself is hard to read:** [Decompose Conditional](https://aipatterns.dev/refactoring/techniques/decompose-conditional.md). Several conditions with the same outcome: [Consolidate Conditional Expression](https://aipatterns.dev/refactoring/techniques/consolidate-conditional-expression.md) first, then name the result.
- **Branches end or start with the same lines:** [Consolidate Duplicate Conditional Fragments](https://aipatterns.dev/refactoring/techniques/consolidate-duplicate-conditional-fragments.md).
- **Deep nesting where outer branches only check for special cases:** [Replace Nested Conditional with Guard Clauses](https://aipatterns.dev/refactoring/techniques/replace-nested-conditional-with-guard-clauses.md).
- **A `done` or `found` flag controls a loop:** [Remove Control Flag](https://aipatterns.dev/refactoring/techniques/remove-control-flag.md). Often a standard library call (`find`, `some`, `any`) removes the loop entirely.
- **The same `switch` on a type appears in several places:** [Replace Conditional with Polymorphism](https://aipatterns.dev/refactoring/techniques/replace-conditional-with-polymorphism.md). For a single `switch` over a closed union, exhaustive pattern matching (TypeScript `never` checks, Rust `match`, Java sealed `switch`) is often clearer than a class per case.
- **`if (x == null)` checks repeat for the same default behavior:** [Introduce Null Object](https://aipatterns.dev/refactoring/techniques/introduce-null-object.md). Where optional chaining (`?.`), `??`, or `Optional` already reads well, prefer those.
- **Code silently assumes something is true:** [Introduce Assertion](https://aipatterns.dev/refactoring/techniques/introduce-assertion.md). Don't use assertions to validate user input; that is error handling, not an invariant.
