在 Intersystems Caché 中使用 ENUM 的最佳实践是什么?

What's the best practice to work with ENUM in Intersystems Caché?

例如,当您需要在 Java 中实现类似以下示例的解决方案时,Caché 本身不会实现 Java 等 ENUM,但在 Caché 中,最佳实践是什么?

public enum Planet {
    MERCURY (3.303e+23, 2.4397e6),
    VENUS   (4.869e+24, 6.0518e6),
    EARTH   (5.976e+24, 6.37814e6),
    MARS    (6.421e+23, 3.3972e6),
    JUPITER (1.9e+27,   7.1492e7),
    SATURN  (5.688e+26, 6.0268e7),
    URANUS  (8.686e+25, 2.5559e7),
    NEPTUNE (1.024e+26, 2.4746e7);

    private final double mass;   // in kilograms
    private final double radius; // in meters
    Planet(double mass, double radius) {
        this.mass = mass;
        this.radius = radius;
    } 
    private double mass() { return mass; }
    private double radius() { return radius; }
}

final Planet mars = Planet.MARS;

访问代码一样简单Planet.MARS

我以前从未用缓存做过这样的事情,但我想你可以做这样的事情:(Ab)使用属性的动态调度。

Class TST.Planet Extends %RegisteredObject  
{

  Property Mass As %Library.Double;
  Property Radius As %Library.Double;

  /// Property dispatch method to catch references to 
  /// virtual properties.<br>
  /// This should not be called directly.<br>
  Method %DispatchGetProperty(pProperty As %String) [ Final, Internal ]
  {
        #Dim Planets As %Library.String // multidimensional
        s Planets("MERCURY")=3.303e+23_"\"_2.4397e6
        s Planets("VENUS")=4.869e+24_"\"_6.0518e6
        s Planets("EARTH")=5.976e+24_"\"_6.37814e6
        s Planets("MARS")=6.421e+23_"\"_3.3972e6
        s Planets("JUPITER")=1.9e+27_"\"_7.1492e7
        s Planets("SATURN")=5.688e+26_"\"_6.0268e7
        s Planets("URANUS")=8.686e+25_"\"_2.5559e7
        s Planets("NEPTUNE")=1.024e+26_"\"_2.4746e7
        if $DATA(Planets(pProperty)) {
          s result = ##class(TST.Planet).%New()
          s result.Mass=$PIECE(Planets(pProperty),"\",1)
           s result.Radius=$PIECE(Planets(pProperty),"\",2)
          q result
        }
      }
  }

然后你必须像这样使用它:

s x = ##Class(TST.Planet).%New()
s x = x.MARS
zw x

EDIT: can also do s x =##Class(TST.Planet).%New().MARS

得到这个结果:

x=<OBJECT REFERENCE>[2@TST.Planet]
+----------------- general information ---------------
|      oref value: 2
|      class name: TST.Planet
| reference count: 2
+----------------- attribute values ------------------
|               Mass = 642100000000000000000000
|             Radius = 3397200

可计算参数示例

Class so.Enum Extends %RegisteredObject
{

Parameter MERCURY As COSEXPRESSION = "..%New(3.303e+23, 2.4397e6)";

Parameter VENUS As COSEXPRESSION = "..%New(4.869e+24, 6.0518e6)";

Parameter EARTH As COSEXPRESSION = "..%New(5.976e+24, 6.37814e6)";

Parameter MARS As COSEXPRESSION = "..%New(6.421e+23, 3.3972e6)";

Parameter JUPITER As COSEXPRESSION = "..%New(1.9e+27,   7.1492e7)";

Parameter SATURN As COSEXPRESSION = "..%New(5.688e+26, 6.0268e7)";

Parameter URANUS As COSEXPRESSION = "..%New(8.686e+25, 2.5559e7)";

Parameter NEPTUNE As COSEXPRESSION = "..%New(1.024e+26, 2.4746e7)";

Property Mass As %Double;

Property Radius As %Double;

Method %OnNew(mass, radius) As %Status
{
    set ..Mass=mass
    set ..Radius=radius
    quit $$$OK
}

}

而且,你可以这样使用它

USER>w ##class(so.Enum).#MERCURY.Mass
330300000000000000000000
USER>w ##class(so.Enum).#MERCURY.Radius
2439700
USER>w ##class(so.Enum).#MERCURY.Radius
2439700
USER>w ##class(so.Enum).#EARTH.Radius
6378140
USER>w ##class(so.Enum).#EARTH
1@so.Enum
USER>w ##class(so.Enum).#MERCURY
1@so.Enum

你可以将它定义为一个宏

#define MERCURY ##class(so.Enum).#MERCURY

#define Planet(%planet) $parameter("so.Enum",$zcvt("%planet","U"))