Model enum / struct

Hi,

I have 3 entities, Category, Action, Event. (Used for analytics)

Event object is formed using Category and Action

Caller would pass the Category and Action to a function f1

What I have done so far:

Models and function

enum Category : String {
    case cat1
    case cat2
}

enum Action : String {
    case act1
    case act2
}

func f1(category: Category, action: Action) {
    
    let event = category.rawValue + "_" + action.rawValue

    //log event
    print(event)
}

f1(category: .cat1, action: .act1)

What I would like to achieve:

Build Category, Action and Event in such a way it is easier to use while invoking.

Example: f1(event: .cat1.act2)

Question:

  • How should I model my entities to achieve this ?
  • If it is not possible to achieve it, are there any suggestions to improve my models ?

Version:

Swift: Apple Swift version 4.2.1

Not quite what I aimed to do, but settled for the below:

enum Action : String {
    case act1
    case act2
}

enum Event {
    
    case cat1(Action)
    case cat2(Action)
    
    var rawValue: String {
        
        let string : String
        
        switch self {
            
        case .cat1(let action):
            string = "Cat1 \(action.rawValue)"
            
        case .cat2(let action):
            string = "Cat2 \(action.rawValue)"
        }
        
        return string
    }
}

func log(event: Event) {
    
    print(event.rawValue)
}


let e1 = Event.cat1(.act1)
let e2 = Event.cat1(.act2)
let e3 = Event.cat2(.act1)

log(event: e1)
log(event: e2)
log(event: e3)

Yeah, this is probably similar to how I would structure it. Ultimately it seems the merger of the two was conceptually a higher element, Event, which then contains an internal action.

One of the good things about associated values is it lets you create better abstractions by finding the "wider grouping". I tend to encourage junior devs to think "what is the general thing I'm working with, define that, and then define its internal components". It tends to work better to define the overall abstraction first, and then associate details with it, than to try and compose a set of discrete elements that may not even need to exist, eg your Category type.

That isn't to say that composition is wrong by any means, merely that by trying to define the problem correctly, you work out what composition helps you, and what is overkill.

1 Like

Thanks @Rod_Brown it was a nice explanation.