<div dir="ltr"><div>Hello,</div><div><br></div><div>If this subject was debated before, please, let me know.</div><div>I googled something related to it, but I couldn&#39;t find answers on why:</div><div><ul><li>Enums only allow literals raw values;</li><li>It is acceptable using switch, even if it gets big;</li><ul><li>The problem with switch is that it makes it easy to add more and more conditions.</li></ul></ul></div><div>Although the compiler issues a warning when a switch statement covers all cases, if we use default and later add another case, it will automatically fall under default. I believe it is a point of failure.</div><div>Besides that, methods that use switch can get complex (high cyclomatic complexity), which can be hard to test.</div><div><br></div><div>A simple situation (below) can lead to different implementation for each case. Which actually means that we should be using the strategy design pattern.</div><div><br></div><div>enum MathematicalOperator {</div><div>    case add, subtract, multiply, divide</div><div><br></div><div>    func perform(between a: Int, and b: Int) -&gt; Int {</div><div>        switch self {</div><div>        case .add:      return doAdd(a: a, b: b)</div><div>        case .subtract: return doSubtract(a: a, b: b)</div><div>        case .multiply: return doMultiply(a: a, b: b)</div><div>        case .divide:   return doDivide(a: a, b: b)</div><div>        }</div><div>    }</div><div><br></div><div>    private func doAdd(a: Int, b: Int) -&gt; Int {</div><div>        return a + b</div><div>    }</div><div><br></div><div>    private func doSubtract(a: Int, b: Int) -&gt; Int {</div><div>        return a - b</div><div>    }</div><div><br></div><div>    private func doMultiply(a: Int, b: Int) -&gt; Int {</div><div>        return a * b</div><div>    }</div><div><br></div><div>    private func doDivide(a: Int, b: Int) -&gt; Int {</div><div>        return a / b</div><div>    }</div><div>}</div><div><br></div><div>The problem with this approach is that is can be harder to test each case individually. I know that this example is simple, but it can get complex once we start adding more cases.</div><div><br></div><div>So, to use strategy, I would implement it like the code below, if it would compile.</div><div><br></div><div>protocol Operator {</div><div>    func perform(between a: Int, and b: Int) -&gt; Int</div><div>}</div><div><br></div><div>struct Addition: Operator {</div><div>    func perform(between a: Int, and b: Int) -&gt; Int {</div><div>        return a + b</div><div>    }</div><div>}</div><div><br></div><div>struct Subtraction: Operator {</div><div>    func perform(between a: Int, and b: Int) -&gt; Int {</div><div>        return a - b</div><div>    }</div><div>}</div><div><br></div><div>struct Multiplication: Operator {</div><div>    func perform(between a: Int, and b: Int) -&gt; Int {</div><div>        return a * b</div><div>    }</div><div>}</div><div><br></div><div>struct Division: Operator {</div><div>    func perform(between a: Int, and b: Int) -&gt; Int {</div><div>        return a / b</div><div>    }</div><div>}</div><div><br></div><div>enum MathematicalOperator: Operator {</div><div>    case add = Addition()</div><div>    case subtract = Subtraction()</div><div>    case multiply = Multiplication()</div><div>    case divide = Division()</div><div><br></div><div>    func perform(between a: Int, and b: Int) -&gt; Int {</div><div>        return rawValue.perform(between: a, and: b)</div><div>    }</div><div>}</div><div><br></div><div>So now I can test each strategy separately, and I can avoid the switch statement entirely. Also, if I add a new case, I would have to provide a new strategy, and the protocol would make me implement all methods.</div><div><br></div><div>I think that the roadblock for this implementation would be related to memory, I imagine that&#39;s why Swift only allows literals on enums.</div><div>Also, this implementation does not care about the Equatable protocol because its raw value is used only to access the right strategy.</div><div><br></div><div>The workaround would be using a struct and not an enum.</div><div><br></div><div>This is the first time I&#39;m sending a message, sorry if I broke any guideline.</div><div>- Rafael Guerreiro</div></div>