我一直在使用Scala替换Java枚举模式
发布时间:2020-12-16 09:06:37 所属栏目:安全 来源:网络整理
导读:在 Java中,我做了很多数据集成工作.一直出现的一件事是在多个系统之间映射数据.所以我经常做这样的事情 public enum DataField{ Field1("xmlField","dbField","system1Field"; private String xml; private String db; private String sys; private DataFiel
在
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,但在我的外部接口系统中,它可能首先被调用.这种模式非常好地将所有这些结合在一起,并且以紧凑,类型安全的方式使这些类型的系统中的消息传递变得非常容易. 现在我不记得为什么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 } 令人讨厌的是我们必须手动创建值列表.但是,在这种情况下,我们可以做一些宏黑客攻击来减少样板: 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] 而不是手动列出所有案例对象. 为此,必须将基类声明为密封. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
推荐文章
站长推荐
热点阅读