我目前正试图通过阅读名为Practical Object Oriented Design in Ruby
的书来理解SOLID原理。第一个原则是单一责任,我理解这个概念的方式是,一个类/方法应该只有一个责任或改变的理由。
在下面的代码中,我有一个Calculate类,它负责(4)四种不同的操作,add
、subtract
、multiply
和divide
,对我来说,这不符合单一责任理论。
有人能这么友善,以一种符合Single Responsibility
的方式重构下面的类吗?
我知道这可能是一个非常固执己见的话题,但我真的需要更好地理解这个概念。
仅供参考-为了简单起见,我只使用Ints,我知道它不适合除法和减法。
class Calculate{
let num1:Int
let num2:Int
init(firstNum:Int, secondNum:Int){
num1 = firstNum
num2 = secondNum
}
func add()->Int{
let total = num1 + num2
return total
}
func subtract()->Int{
let total = num1 - num2
return total
}
func multiply()->Int{
let total = num1 + num2
return total
}
func divide()->Int{
let total = num1 / num2
return total
}
}
let operation = Calculate(firstNum:5 , secondNum:5)
print(operation.divide())
单一责任意味着类应该只有一个逻辑功能。
所以,如果你有计算器,它是完全可以的,它可以计算。"单一"并不意味着"单一方法"。计算器可以求和、除法等等,对吧?所以,是的,这正是Calculator类方法应该做的
例如,如果要连接两个Calculator类,则添加方法"connectToAnotherCalculator"是违反SRP的。正确的方法是创建连接器类,它应该处理计算器之间的通信。
我想建议更好的设计。想象一下,您必须添加许多其他运算:百分比、平方根,甚至正弦。你的计算器将增长数千行。测试呢?假设,我们已经测试了计算器。现在我们需要在每次手术后再次进行测试。所以,增加新的操作将花费我们更换计算器,更换所有使用它的地方和许多涵盖它的测试
但我们可以制作一个单一责任的计算器——计算(运算):1) 现在我们可以使用无处不在的计算器->计算(运算),用测试来覆盖它并使它们通过。2) 对于每一个新的操作,我们只需添加新的操作类并对其进行测试。我们可以轻松地更改任何操作,甚至不需要触摸计算器和使用它的对象。
@Denis Efimov这是我根据你的建议编写的代码。这段来自Laracasts的视频对我帮助很大,它是用PHP编写的,但很容易将其翻译成Swift。
我只显示了两个操作(Addition
和Multiplication
),但我可以很容易地添加任意数量的操作。请注意,为了简单起见,我只使用Int
s。
protocol Operation{
func equation()->Int
}
class Calculator{
func calculate(operation:Operation)->Int{
return operation.equation()
}
}
class Addition:Operation{
var addendOne:Int
var addendTwo:Int
init(addendOne:Int, addendTwo:Int){
self.addendOne = addendOne
self.addendTwo = addendTwo
}
func equation()->Int{
return self.addendOne + self.addendTwo
}
}
class Multiplication:Operation{
var multiplicand:Int
var multiplier:Int
init(multiplicand:Int, multiplier:Int){
self.multiplicand = multiplicand
self.multiplier = multiplier
}
func equation()->Int{
return self.multiplicand * self.multiplier
}
}
let addition = Addition(addendOne:5, addendTwo:5)
let multiplication = Multiplication(multiplicand:5, multiplier:5)
let calculator = Calculator()
print(calculator.calculate(addition))
print(calculator.calculate(multiplication))
你们对这个代码有什么看法,这看起来是一个更好的方法吗?这是否更符合SOLID
原则(SO
)?。
感谢