Skip to content

Story: Preserve immutable types under explicit names and shared contracts #39

Closed

Description

@Alexandre-T

Preserve immutable types under explicit names and shared contracts

As a developer using spatial-types,
I want to identify immutable spatial values explicitly while sharing contracts with mutable values,
so that consumers can select the appropriate representation without confusing their guarantees.

Context

Parent Epic: #38.

Existing classes must retain their immutable behavior after renaming. This establishes the public foundation for the remaining Stories.

This is the first implementation Story of #38: rename the existing immutable types before adding mutable concrete classes. The library has never been used in production; no deprecated aliases or compatibility layer are required.

Approved contract: immutable aggregates reject mutable components rather than converting them implicitly.

Acceptance Criteria

  • Every existing concrete spatial type is renamed with the Immutable suffix in its existing dimension and Geometry/Geography namespace; former class names are removed without aliases or deprecation.
  • All concrete immutable spatial classes are final; shared abstract bases do not expose public mutation or copy-with-replacement operations to the wrong variant.
  • Common spatial/type interfaces expose read operations only. ImmutableSpatialInterface and the applicable ImmutableInterface contracts expose with… operations exclusively for immutable objects.
  • MutableSpatialInterface and applicable MutableInterface contracts extend the common read contracts and carry only the mutation operations relevant to mutable objects; detailed type-specific setters are implemented in the following Stories. No mutable class extends a concrete immutable class.
  • Existing immutable constructor, accessor and with… behaviors are preserved, including partially null ordinates from Story: Allow partially null point ordinates #36.
  • with… operations return a distinct instance without changing the receiver or indirectly changing an immutable source.
  • Immutable aggregate constructors and replacement methods reject mutable spatial components, including nested mutable components, without implicit conversion and without changing the source aggregate or supplied objects.
  • Spatial component contracts and getters of immutable aggregates expose immutable components; coordinate-array input remains supported and creates immutable descendants.
  • Neither variant exposes a dimension setter. MutableSpatialInterface carries declared-SRID/reference and spatial-mode (family) setters; these change metadata without recalculating ordinates. Immutable equivalents remain with… operations.
  • Coordinates and SpatialReference remain immutable auxiliary values without requiring an Immutable suffix.

Constraints

  • Coordinate layout and spatial type remain fixed. Geometric validity is delegated to explicit spatial-validator use; do not introduce automatic validation, repair, reprojection or dimension conversion. Changes to declared family or reference preserve coordinates. Preserve the representable states established by Story: Allow partially null point ordinates #36.
  • Follow the naming and namespace layout defined by Epic: Support mutable and immutable spatial objects #38. Preserve the distinction between technical representation and normative geometric validity under ISO/IEC 13249-3 and applicable OGC specifications.

Definition of Done

The project's common Definition of Done applies.

  • composer test-local passes.
  • composer quality passes.
  • Tests verify final immutable classes, read/immutable/mutable interface separation and rejection of mutable components, using a test double if concrete mutable types are not yet available.
  • Regression tests cover unchanged immutable behavior and partially null ordinates after renaming; factories, tests and repository documentation use the renamed immutable classes.
  • Story-specific public API documentation is updated.

Metadata

Metadata

Assignees

No one assigned

    Labels

    impact:apiAffects the public APIimpact:architectureRequires or affects an architecture decisionimpact:breakingIntroduces a backward-incompatible change

    Type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions