{
  "slug": "Mastering-State-Patterns-in-Golang--Overcoming-Conditional-Statement-Limitations-ffc32b9b71ee",
  "title": "Mastering State Patterns in Golang: Overcoming Conditional Statement Limitations",
  "subtitle": "State is a behavioral design pattern that allows an object to change its behavior when its internal state changes. The State Pattern is a…",
  "excerpt": "State is a behavioral design pattern that allows an object to change its behavior when its internal state changes. The State Pattern is a…",
  "date": "2025-07-28",
  "tags": [
    "Go"
  ],
  "readingTime": "12 min",
  "url": "https://medium.com/@mobinshaterian/mastering-state-patterns-in-golang-overcoming-conditional-statement-limitations-ffc32b9b71ee",
  "hero": "https://cdn-images-1.medium.com/max/800/1*kv7uu-1rplVZcFSpegQdlQ.jpeg",
  "content": [
    {
      "type": "paragraph",
      "html": "<strong>State</strong> is a behavioral design pattern that allows an object to change its behavior when its internal state changes. The <strong>State Pattern</strong> is a behavioral design pattern that enables an object to change its behavior in response to changes in its internal state. It’s beneficial when an object must behave differently depending on its current state, but without resorting to large conditional statements (like <code>if-else</code> or <code>switch</code> chains).<br>I’d like to extend heartfelt thanks to <a href=\"https://medium.com/u/417f3a1534e1\" target=\"_blank\" rel=\"noreferrer noopener\">Mohammad Reza Kargar</a> for not only grasping the essence of the State design pattern in Golang but also skillfully implementing it to address complex conditional behaviors."
    },
    {
      "type": "paragraph",
      "html": "The State pattern is closely related to the concept of a <em>Finite-State Machine</em>."
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*z9hOhXohCIzkz79rzvAQaA.png",
      "alt": "https://refactoring.guru/design-patterns/state",
      "caption": "https://refactoring.guru/design-patterns/state",
      "width": 359,
      "height": 279
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Why Use a State Machine?"
    },
    {
      "type": "paragraph",
      "html": "State machines help enforce predictable transitions between states. They are useful in:"
    },
    {
      "type": "list",
      "ordered": false,
      "items": [
        "Order processing systems",
        "Workflow engines",
        "Vending machines",
        "Booking applications"
      ]
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*kv7uu-1rplVZcFSpegQdlQ.jpeg",
      "alt": "Mastering State Patterns in Golang: Overcoming Conditional Statement Limitations",
      "caption": "",
      "width": 1120,
      "height": 1120
    },
    {
      "type": "heading",
      "level": 2,
      "text": "🥤 Example: Vending Machine"
    },
    {
      "type": "paragraph",
      "html": "Imagine a simple vending machine that sells only <strong>one kind of snack</strong> (e.g., a bag of chips). The machine can be in one of <strong>four states</strong>:"
    },
    {
      "type": "heading",
      "level": 3,
      "text": "✅ 1. hasItem"
    },
    {
      "type": "list",
      "ordered": false,
      "items": [
        "The machine has chips in stock.",
        "You can request to buy an item."
      ]
    },
    {
      "type": "paragraph",
      "html": "<strong>Example:</strong><br>&nbsp;You walk up to the machine and see that it has chips inside. You can press a button to make a purchase."
    },
    {
      "type": "heading",
      "level": 3,
      "text": "❌ 2. noItem"
    },
    {
      "type": "list",
      "ordered": false,
      "items": [
        "The machine is <strong>empty</strong>.",
        "It won’t let you buy anything."
      ]
    },
    {
      "type": "paragraph",
      "html": "<strong>Example:</strong><br>&nbsp;You press the button, but it shows “Out of stock.” No chips are available."
    },
    {
      "type": "heading",
      "level": 3,
      "text": "🔘 3. itemRequested"
    },
    {
      "type": "list",
      "ordered": false,
      "items": [
        "You have requested to purchase an item, but you <strong>have not</strong> yet paid.",
        "The machine is waiting for your money."
      ]
    },
    {
      "type": "paragraph",
      "html": "<strong>Example:</strong><br>&nbsp;You press the button for chips. The machine now shows “Please insert $1.”"
    },
    {
      "type": "heading",
      "level": 3,
      "text": "💰 4. hasMoney"
    },
    {
      "type": "list",
      "ordered": false,
      "items": [
        "You’ve <strong>inserted the money</strong>, and the machine is ready to give you the item."
      ]
    },
    {
      "type": "paragraph",
      "html": "<strong>Example:</strong><br>&nbsp;You put in $1 after requesting chips. The machine gives you the chips and returns to the correct state depending on whether it still has more items."
    },
    {
      "type": "paragraph",
      "html": "The main idea is that, at any given moment, there’s a finite number of states that a program can be in. Within any unique state, the program behaves differently, and it can be switched from one state to another instantaneously. However, depending on the current state, the program may or may not switch to certain other states. These switching rules, called transitions, are also finite and predetermined."
    },
    {
      "type": "paragraph",
      "html": "You can also apply this approach to objects. Imagine that we have a <code>Document</code> class. A document can be in one of three states: <code>Draft</code>, <code>Moderation</code> and <code>Published</code>. The <code>publish</code> The method of the document works a little bit differently in each state:"
    },
    {
      "type": "list",
      "ordered": false,
      "items": [
        "In <code>Draft</code>It moves the document to moderation.",
        "In <code>Moderation</code>It makes the document public, but only if the current user is an administrator.",
        "In <code>Published</code>It doesn’t do anything at all."
      ]
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*voejp3RlleP3xD62oezndA.png",
      "alt": "https://refactoring.guru/design-patterns/state",
      "caption": "https://refactoring.guru/design-patterns/state",
      "width": 594,
      "height": 506
    },
    {
      "type": "heading",
      "level": 2,
      "text": "State Machine Using Conditionals"
    },
    {
      "type": "list",
      "ordered": false,
      "items": [
        "A <strong>state machine</strong> is a way of organizing code where something (like a document) can be in <strong>different states</strong> (like “Draft”, “Published”, or “Archived”).",
        "Using <strong>conditionals</strong> means you write a lot of <code>if</code> or <code>switch</code> statements to decide what to do based on the current state."
      ]
    },
    {
      "type": "paragraph",
      "html": "<strong>Why Conditionals Can Be a Problem</strong>"
    },
    {
      "type": "list",
      "ordered": false,
      "items": [
        "As you add <strong>more states</strong> and more behaviors that depend on the state, you end up writing <strong>a lot of </strong><code><strong>if</strong></code><strong> or </strong><code><strong>switch</strong></code><strong> statements</strong> in many different places.",
        "This can make your code <strong>hard to read, hard to change, and easy to break</strong>."
      ]
    },
    {
      "type": "heading",
      "level": 2,
      "text": "🧱 Example:"
    },
    {
      "type": "paragraph",
      "html": "Imagine you’re coding a <code>Document</code> class in a writing app."
    },
    {
      "type": "paragraph",
      "html": "<strong>Problem</strong>: As you add more states (like “review”, “scheduled”) and actions (<code>Edit()</code>, <code>Delete()</code>, etc.), every method becomes a <strong>long mess of if-else logic</strong>."
    },
    {
      "type": "code",
      "lang": "go",
      "code": "type Document struct {\n    State string // could be \"draft\", \"published\", \"archived\"\n}\nfunc (d *Document) Publish() {\n    if d.State == \"draft\" {\n        fmt.Println(\"Document is now published.\") d.State = \"published\"\n    }\n    else if d.State == \"published\" {\n        fmt.Println(\"Document is already published.\")\n    }\n    else if d.State == \"archived\" {\n        fmt.Println(\"Cannot publish an archived document.\")\n    }\n}"
    },
    {
      "type": "heading",
      "level": 2,
      "text": "🧠 What Is the State Pattern?"
    },
    {
      "type": "paragraph",
      "html": "Imagine a vending machine. It behaves <strong>differently depending on what state it’s in</strong>:"
    },
    {
      "type": "list",
      "ordered": false,
      "items": [
        "If it’s empty, → You can’t buy anything.",
        "If it has items → You can request an item.",
        "If you’ve selected an item → It waits for money.",
        "If you insert enough money, → It dispenses the item."
      ]
    },
    {
      "type": "paragraph",
      "html": "Instead of writing a bunch of <code>if</code> and <code>switch</code> statements, the <strong>State pattern</strong> gives each of these conditions its object, and the machine delegates its behavior to the current state."
    },
    {
      "type": "paragraph",
      "html": "🏗️ Code Breakdown"
    },
    {
      "type": "paragraph",
      "html": "1. <strong>State Interface (</strong><code><strong>state.go</strong></code><strong>)</strong>"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "type State interface {\n    addItem(int) error\n    requestItem() error\n    insertMoney(money int) error\n    dispenseItem() error\n}"
    },
    {
      "type": "paragraph",
      "html": "2. <strong>VendingMachine Struct (</strong><code><strong>vendingMachine.go</strong></code><strong>)</strong>"
    },
    {
      "type": "paragraph",
      "html": "This is the actual vending machine. It holds:"
    },
    {
      "type": "list",
      "ordered": false,
      "items": [
        "<code>currentState</code>: the current state object (e.g., waiting for money)",
        "States: <code>hasItem</code>, <code>itemRequested</code>, <code>hasMoney</code>, <code>noItem</code>",
        "<code>itemCount</code> and <code>itemPrice</code>"
      ]
    },
    {
      "type": "paragraph",
      "html": "It delegates behavior to its current state like this:"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "func (v *VendingMachine) requestItem() error {\n    return v.currentState.requestItem()\n}"
    },
    {
      "type": "paragraph",
      "html": "3. <strong>Concrete State Implementations</strong>"
    },
    {
      "type": "paragraph",
      "html": "✅ <code>HasItemState</code> – The machine has stock and is waiting for you"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "func (i *HasItemState) requestItem() error {\n    i.vendingMachine.setState(i.vendingMachine.itemRequested)\n}"
    },
    {
      "type": "paragraph",
      "html": "💵 <code>ItemRequestedState</code> – Item selected, waiting for money"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "func (i *ItemRequestedState) insertMoney(money int) error {\n    if money < price {\n        return error\n    }\n    i.vendingMachine.setState(i.vendingMachine.hasMoney)\n}"
    },
    {
      "type": "paragraph",
      "html": "🍬 <code>HasMoneyState</code> – Ready to dispense"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "func (i *HasMoneyState) dispenseItem() error {\n    vendingMachine.itemCount -= 1\n    vendingMachine.setState(...)\n}"
    },
    {
      "type": "paragraph",
      "html": "❌ <code>NoItemState</code> – The machine is empty"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "func (i *NoItemState) requestItem() error {\n    return fmt.Errorf(\"Item out of stock\")\n}"
    },
    {
      "type": "paragraph",
      "html": "4. <strong>Client Code (</strong><code><strong>main.go</strong></code><strong>)</strong>"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "vendingMachine := newVendingMachine(1,\n10)vendingMachine.requestItem()vendingMachine.insertMoney(10)vendingMachine.dispenseItem()"
    },
    {
      "type": "paragraph",
      "html": "✅ Sample Run Output"
    },
    {
      "type": "code",
      "lang": "text",
      "code": "Item requestdMoney entered is okDispensing ItemAdding 2 itemsItem requestdMoney entered is\nokDispensing Item"
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Implement the machine state"
    },
    {
      "type": "paragraph",
      "html": "Below is a compact, self‑contained Go example that applies the <strong>State pattern</strong> to an order/payment workflow with the two operations you specified — <code>approve()</code> and <code>refund()</code>—and the five states you listed:"
    },
    {
      "type": "list",
      "ordered": false,
      "items": [
        "<strong>unknown</strong> (brand‑new order)",
        "<strong>checkout</strong> (details entered, awaiting approval to start)",
        "<strong>In progress</strong> (payment/fulfilment running)",
        "<strong>succeed</strong> (completed successfully)",
        "<strong>canceled</strong> (refunded / void)"
      ]
    },
    {
      "type": "paragraph",
      "html": "The <code>Order</code> (the <em>context</em>) delegates every call to its <code>currentState</code>, and each concrete state decides<br>&nbsp;• whether the action is allowed,<br>&nbsp;• what side effects to perform, and<br>&nbsp;• Which next state to switch to?"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "package main\nimport (\n\"fmt\"\n\"log\")/* ---------- State interface ---------- */type State interface {\n    approve() error refund() error\n}\n/* ---------- Context ---------- */type Order struct {\n    // singleton state objects unknown\n    State checkout State inProgress State succeed\n    State canceled State currentState State id string\n}\nfunc newOrder(id string) *Order {\n    o := &Order{\n        id: id\n    }\n    // create concrete states, each holds a back‑pointer to the context o.unknown = &unknownState{\n        o\n    }\n    o.checkout = &checkoutState{\n        o\n    }\n    o.inProgress = &inProgressState{\n        o\n    }\n    o.succeed = &succeedState{\n        o\n    }\n    o.canceled = &canceledState{\n        o\n    }\n    o.setState(o.unknown) // initial state\n    return o\n}\n/* -- context helpers that delegate to state -- */func (o *Order) approve() error {\n    return o.currentState.approve()\n}\nfunc (o *Order) refund() error {\n    return o.currentState.refund()\n}\nfunc (o *Order) setState(s State) {\n    o.currentState = s fmt.Printf(\"🟢  Order %s switched to %T\\n\", o.id, s)\n}\n/* ---------- Concrete states ---------- *//* 1.unknown\n-------------------------------------------------------------- */\ntype unknownState struct{\n    order *Order\n}\nfunc (s *unknownState) approve() error {\n    fmt.Println(\"details confirmed, moving to checkout\") s.order.setState(s.order.checkout) return\n    nil\n}\nfunc (s *unknownState) refund() error {\n    return fmt.Errorf(\"cannot refund: order not created yet\")\n}\n/* 2.checkout ------------------------------------------------------------- */type checkoutState\nstruct{\n    order *Order\n}\nfunc (s *checkoutState) approve() error {\n    fmt.Println(\"payment started\") s.order.setState(s.order.inProgress) return nil\n}\nfunc (s *checkoutState) refund() error {\n    s.order.setState(s.order.canceled) return nil\n}\n/* 3.inProgress ----------------------------------------------------------- */type inProgressState\nstruct{\n    order *Order\n}\nfunc (s *inProgressState) approve() error {\n    fmt.Println(\"order fulfilled\") s.order.setState(s.order.succeed) return nil\n}\nfunc (s *inProgressState) refund() error {\n    fmt.Println(\"cancelling in‑progress order\") s.order.setState(s.order.canceled) return nil\n}\n/* 4.succeed -------------------------------------------------------------- */type succeedState\nstruct{\n    order *Order\n}\nfunc (s *succeedState) approve() error {\n    return fmt.Errorf(\"order already succeeded\")\n}\nfunc (s *succeedState) refund() error {\n    fmt.Println(\"refund processed\") s.order.setState(s.order.canceled) return nil\n}\n/* 5.canceled ------------------------------------------------------------- */type canceledState\nstruct{\n    order *Order\n}\nfunc (s *canceledState) approve() error {\n    return fmt.Errorf(\"cannot approve: order is canceled\")\n}\nfunc (s *canceledState) refund() error {\n    return fmt.Errorf(\"order already canceled / refunded\")\n}\n/* ---------- Demo ---------- */func main() {\n    o := newOrder(\"ORD‑42\") // happy path if err := o.approve();\n    err != nil {\n        log.Fatal(err)\n    }\n    // unknown -> checkout if err := o.approve();\n    err != nil {\n        log.Fatal(err)\n    }\n    // checkout -> inProgress if err := o.approve();\n    err != nil {\n        log.Fatal(err)\n    }\n    // inProgress -> succeed // now refund it if err := o.refund();\n    err != nil {\n        log.Fatal(err)\n    }\n    // succeed -> canceled // try an invalid transition if err := o.approve();\n    err != nil {\n        fmt.Println(\"expected error:\", err)\n    }\n}"
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*EDhye7zZF561ccrQhfDnOQ.jpeg",
      "alt": "Mastering State Patterns in Golang: Overcoming Conditional Statement Limitations",
      "caption": "",
      "width": 1024,
      "height": 1024
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Building a State Machine in Go"
    },
    {
      "type": "paragraph",
      "html": "State machines are a powerful design pattern for modeling complex workflows and systems with well-defined states and transitions. In this article, we’ll implement a <strong>Finite State Machine (FSM)</strong> in Go using a clean and scalable design."
    },
    {
      "type": "heading",
      "level": 2,
      "text": "✅ FSM Design in Go"
    },
    {
      "type": "paragraph",
      "html": "We’ll create:"
    },
    {
      "type": "list",
      "ordered": false,
      "items": [
        "<strong>States</strong>: Defined as constants.",
        "<strong>Actions</strong>: Events that trigger transitions.",
        "<strong>Transition Table</strong>: Maps <code>From State + Action</code> to <code>To State</code>.",
        "<strong>Execution Logic</strong>: Optionally execute business logic during transitions."
      ]
    },
    {
      "type": "heading",
      "level": 2,
      "text": "1. Define States and Actions"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "type State stringtype Action stringconst (    StateIdle      State = \"idle\"    StateProcessing State\n= \"processing\"    StateSuccess    State = \"success\"    StateFailed     State = \"failed\"\nActionStart   Action = \"start\"    ActionSucceed Action = \"succeed\"    ActionFail    Action = \"fail\")"
    },
    {
      "type": "heading",
      "level": 2,
      "text": "2. Define Transition Struct"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "type Transition struct {\n    From State\n    Act Action\n    To\n    State\n    Func func() error // Optional business logic\n}"
    },
    {
      "type": "heading",
      "level": 2,
      "text": "3. FSM Core Logic"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "type FSM struct {\n    State State\n    Transitions []Transition\n}\nfunc (f *FSM) Can(action Action) bool {\n    for _, t := range f.Transitions {\n        if t.From == f.State && t.Act == action {\n            return true\n        }\n    }\n    return false\n}\nfunc (f *FSM) Apply(action Action) error {\n    for _, t := range f.Transitions {\n        if t.From == f.State && t.Act == action {\n            if t.Func != nil {\n                if err := t.Func();\n                err != nil {\n                    return err\n                }\n            }\n            f.State = t.To return nil\n        }\n    }\n    return fmt.Errorf(\"invalid transition from %s with action %s\", f.State, action)\n}"
    },
    {
      "type": "heading",
      "level": 2,
      "text": "4. Define Transitions Table"
    },
    {
      "type": "code",
      "lang": "go",
      "code": "func main() {\n    fsm := &FSM{\n        State: StateIdle, Transitions: []Transition{\n            {\n                From: StateIdle, Act: ActionStart, To: StateProcessing, Func: func() error {\n                    fmt.Println(\"Started processing\") return nil\n                }\n            }, {\n                From: StateProcessing, Act: ActionSucceed, To: StateSuccess, Func: func() error {\n                    fmt.Println(\"Processing succeeded\") return nil\n                }\n            }, {\n                From: StateProcessing, Act: ActionFail, To: StateFailed, Func: func() error {\n                    fmt.Println(\"Processing failed\") return nil\n                }\n            },\n        },\n    }\n    fmt.Println(\"Current State:\", fsm.State)\n    fsm.Apply(ActionStart)\n    fmt.Println(\"Current State:\", fsm.State)\n    fsm.Apply(ActionSucceed)\n    fmt.Println(\"Current State:\", fsm.State)\n}"
    },
    {
      "type": "heading",
      "level": 2,
      "text": "✅ Features of This Design"
    },
    {
      "type": "list",
      "ordered": false,
      "items": [
        "<strong>Type Safety</strong>: Strong typing for states and actions.",
        "<strong>Pluggable Logic</strong>: Each transition can run custom business logic.",
        "<strong>Declarative</strong>: Easy to read and maintain."
      ]
    },
    {
      "type": "heading",
      "level": 2,
      "text": "✅ Possible Enhancements"
    },
    {
      "type": "list",
      "ordered": false,
      "items": [
        "Add <strong>guards</strong> (conditional checks before transitions)",
        "Support <strong>multiple actions per transition</strong>",
        "Persist the FSM state to a database",
        "Use <strong>service injection</strong> for business logic"
      ]
    },
    {
      "type": "heading",
      "level": 2,
      "text": "How does the State pattern in Go overcome the limitations of conditional statements?"
    },
    {
      "type": "paragraph",
      "html": "The State design pattern in Go effectively overcomes the limitations of extensive conditional statements by <strong>encapsulating state-specific behavior into separate objects</strong> and allowing the main object to <strong>delegate actions to its current state object.</strong>"
    },
    {
      "type": "paragraph",
      "html": "Here’s a breakdown of how it addresses these limitations:"
    },
    {
      "type": "paragraph",
      "html": "<strong>Limitations of Conditional Statements</strong>"
    },
    {
      "type": "paragraph",
      "html": "• <strong>Messy and Hard to Manage Code:</strong> When an object needs to behave differently based on its internal state, a common approach is to use numerous <code>if-else</code> or <code>switch</code> statements within its methods"
    },
    {
      "type": "paragraph",
      "html": "• <strong>Increased Complexity:</strong> As more states and behaviors are added, these conditional chains become <strong>long, difficult to read, and hard to change.</strong> For instance, a <code>Document</code> A class with states like \"Draft,\" \"Published,\" and \"Archived\" would require <code>if-else</code> logic in every method (e.g., <code>Publish()</code>, <code>Edit()</code>, <code>Delete()</code>) to determine what action is valid for the current state."
    },
    {
      "type": "paragraph",
      "html": "• <strong>Violation of Open/Closed Principle:</strong> Modifying or adding a new state often requires changes across multiple methods, making the code <strong>easy to break</strong> and difficult to extend without altering existing, tested code."
    },
    {
      "type": "paragraph",
      "html": "• <strong>Duplication of Logic:</strong> Similar conditional logic might be scattered throughout the codebase."
    },
    {
      "type": "paragraph",
      "html": "<strong>How the State Pattern Overcomes These Limitations</strong>"
    },
    {
      "type": "paragraph",
      "html": "The State pattern addresses these issues by:"
    },
    {
      "type": "paragraph",
      "html": "1. <strong>Defining a State Interface:</strong> It starts by defining an interface (e.g., <code>State</code> in Go) that declares all possible behaviors that can vary by state. For a vending machine, this might include methods like <code>addItem</code>, <code>requestItem</code>, <code>insertMoney</code>, and <code>dispenseItem</code>. For an order system, it could be <code>approve()</code> and <code>refund().</code>"
    },
    {
      "type": "paragraph",
      "html": "2. <strong>Encapsulating State-Specific Behavior:</strong> Instead of one large object with many conditionals, each specific state (e.g., HasItemState, NoItemState, ItemRequestedState, HasMoneyState for a vending machine; or unknownState, checkoutState, inProgressState, succeedState, canceledState for an order) becomes its separate class or struct that implements the State interface. Within each concrete state object, only the logic relevant to that specific state is implemented for the interface methods."
    },
    {
      "type": "paragraph",
      "html": "3. <strong>Delegation of Behavior:</strong> The main object (known as the “context,” such as <code>VendingMachine</code> or <code>Order</code>) <strong>maintains a reference to its current state object.</strong> When an action is called on the context object (e.g., <code>vendingMachine.requestItem()</code>, <code>order.approve()</code>), <strong>it delegates that call to its currentState object</strong>. The <code>currentState</code> then handles the action according to its specific implementation."
    },
    {
      "type": "paragraph",
      "html": "◦ <strong>Example (Vending Machine):</strong> If the vending machine is in <code>HasItemState</code> and <code>requestItem()</code> is called, that state object handles the request and transitions the machine to <code>ItemRequestedState</code>. If it’s in <code>NoItemState</code> and <code>requestItem()</code> is called, the <code>NoItemState</code> object returns an \"Item out of stock\" error."
    },
    {
      "type": "paragraph",
      "html": "◦ <strong>Example (Order System):</strong> An <code>Order</code> object delegates <code>approve()</code> or <code>refund()</code> calls to its <code>currentState</code>. For example, an <code>unknownState</code> can <code>approve()</code> to move to <code>checkout</code>, but a <code>canceledState</code> will return an error if <code>approve()</code> is called."
    },
    {
      "type": "paragraph",
      "html": "4. <strong>Predictable State Transitions:</strong> Each concrete state object is also responsible for determining what the <strong>next state</strong> should be after an action, enforcing predictable transitions. This is explicitly managed within the state implementations, such as <code>s.order.setState(s.order.checkout).</code>"
    },
    {
      "type": "paragraph",
      "html": "5. <strong>Improved Readability and Maintainability:</strong> By isolating the behavior for each state into its own class, the code becomes much cleaner. <strong>There are no large if-else or switch statements</strong> in the main object’s methods. Adding new states or modifying existing state behavior only requires creating a new concrete state class or modifying an existing one, rather than changing multiple conditional blocks across the entire system."
    },
    {
      "type": "paragraph",
      "html": "6. <strong>Scalability:</strong> This design makes the system <strong>highly scalable</strong>. If new states or actions are required, you simply create new concrete state implementations without altering existing code, adhering to the Open/Closed Principle."
    },
    {
      "type": "paragraph",
      "html": "In essence, the State pattern transforms complex conditional logic into an object-oriented structure where <strong>each “if” condition becomes a separate object</strong>, making the system more modular, understandable, and easier to evolve. It is closely related to the concept of a <strong>Finite-State Machine (FSM)</strong>, which inherently defines states, actions, and transitions"
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Conclution"
    },
    {
      "type": "paragraph",
      "html": "Both the State design pattern and FSM implementations in Go provide powerful ways to manage complex state-dependent logic, offering significant advantages over verbose conditional statements. The State pattern emphasizes an object-oriented approach where behavior is delegated to state objects, while the transition table FSM offers a more declarative and tabular way to define state changes, especially beneficial for complex workflows. Choosing between them depends on the specific project needs and architectural preferences. Regardless of the chosen approach, state machines help enforce predictable transitions and lead to more maintainable and robust code."
    },
    {
      "type": "heading",
      "level": 2,
      "text": "A message from our Founder"
    },
    {
      "type": "paragraph",
      "html": "<strong>Hey, </strong><a href=\"https://linkedin.com/in/sunilsandhu\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>Sunil</strong></a><strong> here.</strong> I wanted to take a moment to thank you for reading until the end and for being a part of this community."
    },
    {
      "type": "paragraph",
      "html": "Did you know that our team run these publications as a volunteer effort to over 200k supporters? <strong>We do not get paid by Medium</strong>!"
    },
    {
      "type": "paragraph",
      "html": "If you want to show some love, please take a moment to <strong>follow me on </strong><a href=\"https://linkedin.com/in/sunilsandhu\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>LinkedIn</strong></a><strong>, </strong><a href=\"https://tiktok.com/@messyfounder\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>TikTok</strong></a><strong> and </strong><a href=\"https://instagram.com/sunilsandhu\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>Instagram</strong></a>. And before you go, don’t forget to <strong>clap</strong> and <strong>follow</strong> the writer️!"
    }
  ]
}
