在Java中,我做了很多数据集成工作。一直出现的一件事是在多个系统之间映射数据。所以我一直在做这样的事情
public enum DataField{
Field1("xmlField", "dbField", "system1Field";
private String xml;
private String db;
private String sys;
private DataField(String xml, String db, String sys){
this.xml = xml;
this.db = db;
this.sys = sys;
}
public getXml(){
return this.xml;
}
public static DataField valueOfXml(String xml){
for (DataField d : this.values()){
if (d.xml.equals(xml)){ return d;}
}
}
bla, bla bla
}
这允许我做的是将字段名称DataField放入所有消息中,并能够映射在多个系统中该字段的名称。因此,在我的XML中,它可能firstname
在我的数据库中被调用,first_name
但是在我的外部接口系统中,它可能被调用first
。这种模式将所有这些很好地融合在一起,并以紧密,类型安全的方式使这些类型的系统中的消息传递非常容易。
现在,我不记得为什么Scala更改了枚举实现,但我记得阅读它时才有意义。但是问题是,我将在Scala中使用什么来代替这种设计模式?我讨厌失去它,因为它对于一天中编写的许多系统非常有用且至关重要。
谢谢
我设法弥补了您的这种情况:
sealed class DataField(val xml: String, val db: String, val sys: String)
object DataField {
case object Field1 extends DataField("xmlField1", "dbField1", "system1Field")
case object Field2 extends DataField("xmlField2", "dbField2", "system2Field")
case object Field3 extends DataField("xmlField3", "dbField3", "system3Field")
val values = List(Field1, Field2, Field3)
def valueOfXml(xml: String) =
values.find(_.xml == xml).get
}
令人讨厌的是,我们必须手动创建values
列表。但是,在这种情况下,我们可以进行一些宏修改以减少样板:
import scala.language.experimental.macros
import scala.reflect.macros.Context
object Macros {
def caseObjectsFor[T]: List[T] = macro caseObjectsFor_impl[T]
def caseObjectsFor_impl[T: c.WeakTypeTag](c: Context): c.Expr[List[T]] = {
import c.universe._
val baseClassSymbol = weakTypeOf[T].typeSymbol.asClass
val caseObjectSymbols = baseClassSymbol.knownDirectSubclasses.toList.collect {
case s if s.isModuleClass && s.asClass.isCaseClass => s.asClass.module
}
val listObjectSym = typeOf[List.type].termSymbol
c.Expr[List[T]](Apply(Ident(listObjectSym), caseObjectSymbols.map(s => Ident(s))))
}
}
然后我们可以这样做:
val values = Macros.caseObjectsFor[DataField]
而不是手动列出所有案例对象。
为此,必须将基类声明为sealed
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句