Sam*_*eer 4 design-patterns scala
我试图解决一个问题,处理从一个温度单位到另一个温度单位的转换(摄氏,开尔文,华氏温度).
在Java中,我需要创建一个接口并提供多个实现,这些实现封装了Input Type并将结果作为输出类型的单元返回.例如Kelvin到摄氏或摄氏到华氏等我已经在scala中重构了我的代码以下但仍然觉得它违反了Open封闭原则,因为如果我需要添加另一种类型我需要更改现有代码.任何建议保持代码功能以及遵守开放封闭原则请忽略转换逻辑
object TempConverter extends App {
object UnitType extends Enumeration {
type EnumType = Value
val cel, fah, kel = Value
}
def convert(x: Double, i:UnitType.Value,o:UnitType.Value) = {
strategy(i,o)(x)
}
def strategy(inputType: UnitType.Value, outputType: UnitType.Value) = {
inputType match {
case UnitType.cel => celsius(outputType)
case UnitType.kel => kelvin(outputType)
case UnitType.fah => fahrenheit(outputType)
}
}
def celsius(outputType: UnitType.Value) = {
outputType match {
case UnitType.fah => x: Double => x * 1.8 + 32
case UnitType.kel => x: Double => x * 1.8 + 32
}
}
def kelvin(outputType: UnitType.Value) = {
outputType match {
case UnitType.cel => x: Double => x - 273.5
case UnitType.fah => x: Double => x * 1.8 + 32
}
}
def fahrenheit(outputType: UnitType.Value) = {
outputType match {
case UnitType.cel => x: Double => x * 1.8 + 32
case UnitType.fah => x: Double => x * 1.8 + 32
}
}
println(convert(32.0, UnitType.cel, UnitType.fah))
}
Run Code Online (Sandbox Code Playgroud)
我会做以下事情:
toKelvin和from Kelvin方法.a为单位b只是:b.fromKelvin(a.toKelvin())事实上,在Scala中添加Enumerations的方法比Java更复杂,所以这里是一个实现特征的单例的实现:
trait TemperatureUnit {
def toKelvin(value : Double): Double
def fromKelvin(value : Double): Double
def convert(value : Double, unit : TemperatureUnit) : Double = fromKelvin(unit.toKelvin(value))
}
object Kelvin extends TemperatureUnit {
def toKelvin(value : Double) = value
def fromKelvin(value : Double) = value
}
object Celsius extends TemperatureUnit {
def toKelvin(value : Double) = value + 273.5
def fromKelvin(value : Double) = value - 273.5
}
Run Code Online (Sandbox Code Playgroud)
然后将开尔文转换为摄氏温度就是:
scala> Celsius.convert(100,Kelvin)
res0: Double = -173.5
Run Code Online (Sandbox Code Playgroud)
您可能还应该添加一个包装器类,这样您就不会在裸露Double的情况下传递(可能会在没有编译器警告的情况下意外地将其用作长度,时间戳等).
class Temperature (value: Double, unit: TemperatureUnit) {
def to(new_unit: TemperatureUnit) = new Temperature(new_unit.convert(value,unit),new_unit)
}
Run Code Online (Sandbox Code Playgroud)
然后当你写
new Temperature(10,Celsius).to(Kelvin)
Run Code Online (Sandbox Code Playgroud)
没有任何含糊之处.
| 归档时间: |
|
| 查看次数: |
394 次 |
| 最近记录: |