正确应用封装
Proper application of encapsulation
我一直在研究封装的概念,并发现了一些关于该主题的不错的线索,例如 this one and this one。但是我一直无法找到我遇到的特定问题的答案。我将在 Swift.
中使用示例
假设您有一个类型为 RoadTrip 的对象:
class RoadTrip() {
private var duration: Double
private var totalMiles: Double
private var gallonsOfFuel: Double
var averageMilesPerGallon: Double
}
现在假设应用程序要计算 averageMilesPerGallon
这是唯一的 public 属性:
func calculateAverageMilePerGallon() -> Double {
let mpg = totalMiles / gallonsOfFuel
return mpg
}
每加仑平均英里数的计算是否应该是执行和更新其 averageMilesPerGallon
的 RoadTrip 对象的私有方法,或者是否可以接受由单独实用程序中的另一种方法执行计算 class 然后使用设置值的增变器方法更新 RoadTrip 对象的 averageMilesPerGallon
属性?
编辑:这是我的单曲 class,其中包含我的应用程序的基本计算。我是根据我在 iTunes 上的斯坦福课程中学到的知识以这种方式处理它的,但我开始考虑在我的情况下我应该将大部分内容转移到我的 LiftEvent class:
infix operator ^^ { }
func ^^ (radix: Double, power: Double) -> Double {
return Double(pow(Double(radix), Double(power)))
}
class CalculatorBrain: NSObject {
var weightLifted: Double?
var repetitions: Double?
var oneRepMax: Double?
let dataManager = LiftEventDataManager()
func calculateOneRepMax(weightLifted: Double, repetitions: Int ) -> Double {
let preferredFormulaID = UserDefaultsManager.sharedInstance.preferredFormula!
let formulas = dataManager.fetchSelectableFormulas()
let formulaName = formulas[preferredFormulaID].formulaName
switch formulaName {
case "Epley":
oneRepMax = weightLifted * (1 + Double(repetitions)/30.0)
return oneRepMax!
case "Baechle":
oneRepMax = weightLifted * (36/(37 - Double(repetitions)))
return oneRepMax!
case "Brzychi":
oneRepMax = weightLifted * ( 1 + ( 0.033 * Double(repetitions)))
return oneRepMax!
case "Lander":
oneRepMax = 100 * weightLifted / (101.3 - (2.67123 * Double(repetitions)))
return oneRepMax!
case "Lombardi":
oneRepMax = weightLifted * (Double(repetitions) ^^ 0.10)
return oneRepMax!
case "Mayhew":
oneRepMax = 100 * weightLifted / (52.2 + (41.9 * (2.71828 ^^ (-0.055 * Double(repetitions)))))
return oneRepMax!
case "O'Conner":
oneRepMax = weightLifted * (1 + 0.025 * Double(repetitions))
return oneRepMax!
default:
return 0.0
}
}
private func calculatePercentOfWeight(maxWeight: Double, percent: Double) -> Double {
return maxWeight * percent
}
func calculateWeightPercentages(maxWeight: String) -> [Int: Double] {
let weightPercentages = [1.0, 0.95, 0.90, 0.85, 0.80, 0.75, 0.70, 0.65, 0.60, 0.55, 0.50, 0.45, 0.40, 0.35, 0.30, 0.25]
var percentages = [Int: Double]()
for percent in weightPercentages {
let integerPercent = Int(percent * 100)
percentages[integerPercent] = calculatePercentOfWeight(Double(maxWeight)!, percent: percent)
}
return percentages
}
func convertBetweenUnits(fromUnit: Int, toUnit: Int, value: Double) -> Double {
let units = dataManager.fetchUnits()
let from = units[fromUnit].conversionRatio as Double
let to = units[toUnit].conversionRatio as Double
let result = Double(value * to / from)
return result
}
}
我认为这是理想的 use-case 计算 属性:
class RoadTrip {
private let duration: Double
private let totalMiles: Double
private let gallonsOfFuel: Double
private var averageMilesPerGallon: Double {
return totalMiles / gallonsOfFuel
}
}
我一直在研究封装的概念,并发现了一些关于该主题的不错的线索,例如 this one and this one。但是我一直无法找到我遇到的特定问题的答案。我将在 Swift.
中使用示例假设您有一个类型为 RoadTrip 的对象:
class RoadTrip() {
private var duration: Double
private var totalMiles: Double
private var gallonsOfFuel: Double
var averageMilesPerGallon: Double
}
现在假设应用程序要计算 averageMilesPerGallon
这是唯一的 public 属性:
func calculateAverageMilePerGallon() -> Double {
let mpg = totalMiles / gallonsOfFuel
return mpg
}
每加仑平均英里数的计算是否应该是执行和更新其 averageMilesPerGallon
的 RoadTrip 对象的私有方法,或者是否可以接受由单独实用程序中的另一种方法执行计算 class 然后使用设置值的增变器方法更新 RoadTrip 对象的 averageMilesPerGallon
属性?
编辑:这是我的单曲 class,其中包含我的应用程序的基本计算。我是根据我在 iTunes 上的斯坦福课程中学到的知识以这种方式处理它的,但我开始考虑在我的情况下我应该将大部分内容转移到我的 LiftEvent class:
infix operator ^^ { }
func ^^ (radix: Double, power: Double) -> Double {
return Double(pow(Double(radix), Double(power)))
}
class CalculatorBrain: NSObject {
var weightLifted: Double?
var repetitions: Double?
var oneRepMax: Double?
let dataManager = LiftEventDataManager()
func calculateOneRepMax(weightLifted: Double, repetitions: Int ) -> Double {
let preferredFormulaID = UserDefaultsManager.sharedInstance.preferredFormula!
let formulas = dataManager.fetchSelectableFormulas()
let formulaName = formulas[preferredFormulaID].formulaName
switch formulaName {
case "Epley":
oneRepMax = weightLifted * (1 + Double(repetitions)/30.0)
return oneRepMax!
case "Baechle":
oneRepMax = weightLifted * (36/(37 - Double(repetitions)))
return oneRepMax!
case "Brzychi":
oneRepMax = weightLifted * ( 1 + ( 0.033 * Double(repetitions)))
return oneRepMax!
case "Lander":
oneRepMax = 100 * weightLifted / (101.3 - (2.67123 * Double(repetitions)))
return oneRepMax!
case "Lombardi":
oneRepMax = weightLifted * (Double(repetitions) ^^ 0.10)
return oneRepMax!
case "Mayhew":
oneRepMax = 100 * weightLifted / (52.2 + (41.9 * (2.71828 ^^ (-0.055 * Double(repetitions)))))
return oneRepMax!
case "O'Conner":
oneRepMax = weightLifted * (1 + 0.025 * Double(repetitions))
return oneRepMax!
default:
return 0.0
}
}
private func calculatePercentOfWeight(maxWeight: Double, percent: Double) -> Double {
return maxWeight * percent
}
func calculateWeightPercentages(maxWeight: String) -> [Int: Double] {
let weightPercentages = [1.0, 0.95, 0.90, 0.85, 0.80, 0.75, 0.70, 0.65, 0.60, 0.55, 0.50, 0.45, 0.40, 0.35, 0.30, 0.25]
var percentages = [Int: Double]()
for percent in weightPercentages {
let integerPercent = Int(percent * 100)
percentages[integerPercent] = calculatePercentOfWeight(Double(maxWeight)!, percent: percent)
}
return percentages
}
func convertBetweenUnits(fromUnit: Int, toUnit: Int, value: Double) -> Double {
let units = dataManager.fetchUnits()
let from = units[fromUnit].conversionRatio as Double
let to = units[toUnit].conversionRatio as Double
let result = Double(value * to / from)
return result
}
}
我认为这是理想的 use-case 计算 属性:
class RoadTrip {
private let duration: Double
private let totalMiles: Double
private let gallonsOfFuel: Double
private var averageMilesPerGallon: Double {
return totalMiles / gallonsOfFuel
}
}