所以我是一个Scala noob,来自生锈的Java背景和主要的PHP + JavaScript。 我发现自己感到沮丧,因为我想在Scala中实现设计模式,但我不知道如何导致大量阅读,而且从不进行任何编程。
无论如何所以我正在忙着制作一个基本程序来学习细节,我正在制作一个配置文件阅读器。我需要做的是将不同的格式映射到扩展,诀窍是不同的扩展名(例如yaml
和yml
)映射到相同的格式。
在java中,我会使用Enums
并控制构造函数中的映射。挺直的。
scala ......不是那么多。首先,我发现ADT(意思是代数数据类型而非抽象数据类型)是使用Enumeration的更好的选择(原因对我来说仍然不清楚),并且它对Java库更有效(具有讽刺意味的是,我没有想法为什么。)
接下来我发现ADT的各种格式,作为一个初学者同时掌握所有概念是艰苦的。我已经设法找出companion Objects
类似于javascript,因为它是一个单独的实例化,几乎像一个单例,并允许您在静态上下文中访问已定义的函数。
我写过我认为是个好主意但是代码看起来很麻烦,冗长,我无法弄清楚一些用例,而且从我所有的JS插件中看起来我有点像namespacing nut在逻辑分离方面表现良好,但在scala中表现不够简洁。
class ConfigManager {
object Formats{
case class Format(f: String){
val format = f.toUpperCase()
}
case object Yaml extends Format("YAML")
case object Xml extends Format("XML")
case object Json extends Format("JSON")
}
object Extensions {
case class Extension(e: String) {
val extension = e.toUpperCase()
}
case object Yaml extends Extension("YAML")
case object Yml extends Extension("YML")
case object Xml extends Extension("XML")
case object Json extends Extension("JSON")
}
object Config {
private sealed trait ConfigFormats {
def f: Formats.Format
def e : Extensions.Extension
}
case class ConfigFormat(f: Formats.Format, e: Extensions.Extension)
extends ConfigFormats (f, e)
case object Yaml1 extends ConfigFormat(Formats.Yaml, Extensions.Yaml)
case object Yaml2 extends ConfigFormat(Formats.Yaml, Extensions.Yml)
case object Xml extends ConfigFormat(Formats.Xml, Extensions.Xml)
case object Json extends ConfigFormat(Formats.Json, Extensions.Json)
}
//this looks nice, and useful, is concise and does what I want
def readConfig(c: Config.ConfigFormat){
c.f match {
case Formats.Yaml => readConfigYaml()
case Formats.Json => readConfigJson()
case Formats.Xml => readConfigXml()
case _ => throw new Exception("Invalid Config format")
}
}
//and this is where I lose the plot
def setFormat(extension: String){
val configFormat = new Extensions.Extension(discoveredFormat) match {
case Config.????? => ????
}
}
}
所以显而易见的问题是我的实施有多糟糕,我应该做些什么,为什么? (我最关心的是“为什么”)
答案 0 :(得分:1)
Scala枚举很好,您可以像这样定义Formats
和Extensions
:
object Formats extends Enumeration {
type Eny = Value
val YAML, XML, JSON = Value
}
object Extensions extends Enumeration {
type Eny = Value
val YAML, YML, XML, JSON = Value
}
如果您想要地图,只需使用地图:
val configFormats: Map[Extensions.Value, Formats.Value] = Map(
Extensions.YAML -> Formats.YAML,
Extensions.YML -> Formats.YAML,
Extensions.XML -> Formats.XML,
Extensions.JSON -> Formats.JSON)
然后我不确定你的方法应该做什么,但看起来你的setFormat
可以这样开始:
def setFormat(extension: String): Unit = {
val format: Formats.Value = configFormats(Extensions withName extension)
...
}
你看,就像Java :)如果你更好地描述你想做什么,我们可能会给你一个更“习惯的方式”。