枚举作为Scala中建模类型的成员值或特征?

时间:2016-06-09 22:39:59

标签: scala enums data-modeling traits

假设我拦截了网络流量并测量了每个数据包的时间,大小和类型(TCP,UDP,AppleTalk)。没有其他类似的IP地址或数据被测量,应该建模。过滤和计算统计数据是我的想法。我无意使用额外的信息或函数扩展TCP,UDP,...的特化类。我是Scale的新手,想知道正确的方法是什么。

使用C / C ++中的枚举:

object TransportType extends Enumeration {
     type TransportType = Value
     val TCP = Value("TCP")
     val UDP = Value("UDP") 
     val AppleTalk = Value("AppleTalk")

 }

 class Packet(val time:int , val size:Int, val type:TransportType)

 val p1 = new Packet(0, 200, TransportType.UDP)
 val p2 = new Packet(1, 1000, TransportType.TCP)

或者有特征:

object TransportType {
     trait TCP
     trait UDP
     trait AppleTalk
 }

 class Packet(val time:int , val size:Int)

 val p1 = new Packet(0, 200) with TransportType.UDP
 val p2 = new Packet(1, 1000) with TransportType.TCP

在后一种情况下,可能存在没有特殊类型的数据包。在第一种情况下这是不可能的。我对这些建模差异不感兴趣。我想知道是否建议在第二个解决方案中创建许多特征/类,并使用类型系统来编码属性。如果第二个解决方案是正确的,那么假设数据包具有另一个属性Origin。可以这样建模:

object Origin {
     trait NA
     trait SA
     trait EU
     trait Asia
     trait Africa
     trait Australia
 }

 val p1 = new Packet(0, 200) with TransportType.UDP with Origin.Asia

第二种解决方案是正确的 - Scala-tic - 解决方案吗?

1 个答案:

答案 0 :(得分:1)

一个很好的通用方法(有很多例外,保留和特殊情况,就像所有通用方法一样),我建议用这种方式来看待:成员是属性,而特征是行为。

如果模型中的tcp数据包的行为与udp不同(例如,一个具有另一个没有的方法,或者有一些函数接受一个作为参数,而不是另一个等。),它应该是一个特性,否则,一个属性应该做(如果有需要你仍然可以有没有“特殊类型”的数据包 - 只需使属性可选,所以,这并不重要)。