在 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"))
例如,当您需要在 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"))