1

私は、ジオメトリの次の基本的な抽象クラスから始めました。

@Serializable
abstract const class Geometry {

    const Str type

    new make( Str type, |This| f ) {
        this.type = type
        f(this)
    }
}

次に、この抽象クラスを拡張して Point をモデル化しました。

const class GeoPoint : Geometry {

    const Decimal[] coordinates

    new make( |This| f ) : super( "Point", f ) { }

    Decimal? longitude()  { coordinates.size >= 1 ? coordinates[ 0 ] : null }
    Decimal? latitude()   { coordinates.size >= 2 ? coordinates[ 1 ] : null }
    Decimal? altitude()   { coordinates.size >= 3 ? coordinates[ 2 ] : null } 
}

これは正常にコンパイルされ、単純なシナリオでは正常に動作しますが、IoC 経由で使用しようとすると、次のエラー メッセージが表示されます。

[err] [afBedSheet] afIoc::IocErr - Field myPod::GeoPoint.coordinates was not set by ctor sys::Void make(|sys::This->sys::Void| f)

Causes:
  afIoc::IocErr - Field myPod::GeoPoint.coordinates was not set by ctor sys::Void make(|sys::This->sys::Void| f)
sys::FieldNotSetErr - myPod::GeoPoint.coordinates

IoC Operation Trace:
  [ 1] Autobuilding 'GeoPoint'
  [ 2] Creating 'GeoPoint' via ctor autobuild
  [ 3] Instantiating myPod::GeoPoint via Void make(|This->Void| f)...

Stack Trace:
    afIoc::IocErr : Field myPod::GeoPoint.coordinates was not set by ctor sys::Void make(|sys::This->sys::Void| f)

コンストラクターに 以外の別のパラメーターがあるためだと思います|This| f。Geology クラスと GeoPoint クラスを記述するためのより良い方法はありますか?

4

1 に答える 1

1

シリアル化には、 という it-block ctor が必要ですmake()。しかし、それはあなたが独自の ctor を定義することを止めるものではありません。懸念事項を分離する手段として、2 つの ctor を分離したままにします。

単純なデータ型の場合、通常はフィールド値を ctor パラメーターとして渡します。

これにより、オブジェクトは次のようになります。

@Serializable
abstract const class Geometry {
    const Str type

    // for serialisation
    new make(|This| f) {
        f(this)
    }

    new makeWithType(Str type) {
        this.type = type
    }
}

@Serializable
const class GeoPoint : Geometry {
    const Decimal[] coordinates

    // for serialisation
    new make(|This| f) : super.make(f) { }

    new makeWithCoors(Decimal[] coordinates) : super.makeWithType("Point") {
        this.coordinates = coordinates
    }
} 

Fantom シリアライゼーションは ctor を使用し、make()ctor を次のように使用できますmakeWithCoors()

point1 := GeoPoint([1d, 2d])  // or
point2 := GeoPoint.makeWithCoors([1d, 2d])

Fantom が引数から解決するので、ctor に名前を付ける必要はないことに注意してください。

また、独自の ctor には任意の名前を付けることができますが、慣例により . で始まることに注意してくださいmakeXXXX()

次に、IoCGeoPointを使用して a を自動ビルドするには、次のようにします。

point := (GeoPoint) registry.autobuild(GeoPoint#, [[1d, 2d]])

それはmakeWithCoors()ctorを使用します。

于 2015-12-18T15:59:03.563 に答える