frankie frankie - 3 months ago 9
Swift Question

Using class or struct with getter and setter to have properties computed with relations

I would like to replace my ugly with something smarter, using structs, or any simple looking solution.

There are lot of methods in my class that could be composed and I don't like it.

For imagination, I have created a class that has some methods in it.

An example is about relation among members count, who and a budget that is distributed):

class Budget {

var distribution : (Int, Double) = (0, 0.0) // (number of members, sum per member) as tuple

func getBudget(distribution: (Int, Double)) -> Double {
let members = distribution.0
let perMember = distribution.1
return Double(members) * perMember
}

func ratioBySumPerMember(sum: Double) -> Double {
let budget = getBudget(distribution: distribution)
return sum / budget
}

func sumPerMemberByBudget(budget: Double) -> Double {
let members = distribution.0
return budget/Double(members)
}

func sumPerMemberByRatio(ratio: Double) -> Double {
let budget = getBudget(distribution: distribution)
return ratio * budget
}

func ratioByMembersCount(members: Int) -> Double{
return Double(members)/100.0
}

func getBudgetBySumPerMember(sum: Double) -> Double {
distribution.1 = sum
let budget = getBudget(distribution: distribution)
return budget
}

/// ... etc
}


I would like to establish any property/struct, that is dedicated to serve like some smart calculating formula.

It should be able to get result from input values, as well as to get input values, by putting a result into it. Will anybody have an idea?
The shorter, the better. If possible...

Answer

It is nice example of a situation, when it's good time for using computed properties.

It doesn't store values, it is just calculating result. It sets other properties (not directly) as well. So let's indirectly set properties. With variables you can work like they were common stored properties.

struct Distribution {
    var members = 0, perMember = 0.0
}
struct Plan {
    var distribution = Distribution()
    var ratio: Double {
        get {
            return Double(distribution.perMember) / budget
        }
    }
    var budget: Double {
        get {
            return Double(distribution.members) * distribution.perMember
        }
        set {
            let perMember = newValue * ratio
            distribution = Distribution(members: Int(newValue / perMember), perMember: perMember)
        }
    }
}

I attach some output by using structs and updating variables:

var plan = Plan(distribution: Distribution(members: 4, perMember: 1000.0))
print("\(plan.ratio * 100.0)% ") // 25.0%
print(plan.budget) // 4000.0
plan.distribution = Distribution(members: 5, perMember: 900.0)
print("\(plan.ratio * 100.0)% ") // 20.0%
print(plan.budget) // 4500.0
plan.budget = 8000.0
print(plan.distribution.perMember) // 1600.0
Comments