1
\$\begingroup\$

I have an interface which is for an object which has bounds in a 2D plane.

interface Boundable : Positionable {

    /**
     * Returns the [Bounds] (the [Position] and [Size]) of this [Boundable].
     */
    fun bounds(): Bounds

    /**
     * Returns the [Size] of this [Boundable].
     */
    fun size(): Size

    /**
     * Tells whether this [Boundable] intersects the other `boundable` or not.
     */
    fun intersects(boundable: Boundable): Boolean

    /**
     * Tells whether `position` is within this boundable's bounds.
     */
    fun containsPosition(position: Position): Boolean

    /**
     * Tells whether this boundable contains the other `boundable`.
     * A [Boundable] contains another if the other boundable's bounds
     * are within this one's. (If their bounds are the same it is considered
     * a containment).
     */
    fun containsBoundable(boundable: Boundable): Boolean
}

This is something like Rect in the Java SDK for example. Currently Boundable inherits from Positionable:

/**
 * Represents an object which is positionable within its parent.
 * Note that once positioned a [Positionable] can't be moved.
 * If you want re-positionable objects @see [Movable].
 */
interface Positionable {

    fun position(): Position = Position.zero()

}

Positionable is for objects which have a Position within a larger object on the same plane. This setup worked so far but now I need to have 3 versions of Boundable. One, which does not inherit from Positionable (to be used for detached or root objects), one which does and one which is Movable:

/**
 * A [Movable] object is a specialized [Positionable].
 * It can not only be positioned but moved as well.
 */
interface Movable : Positionable {

    fun moveTo(position: Position): Boolean

    fun moveBy(position: Position) = moveTo(position() + position)

    fun moveRightBy(delta: Int) = moveTo(position().withRelativeX(delta))

    fun moveLeftBy(delta: Int) = moveTo(position().withRelativeX(-delta))

    fun moveUpBy(delta: Int) = moveTo(position().withRelativeY(-delta))

    fun moveDownBy(delta: Int) = moveTo(position().withRelativeY(delta))
}

My problem is figured out a name for the variants, but I'm not satisfied with them. I came up with PositionableBoundable and MovableBoundable but they sound weird.

Are these names adequate or should I change them to something more descriptive?

\$\endgroup\$
2
\$\begingroup\$

Everything is an Entity!

If you would follow the Entity Component System approach, that is. The idea is that all objects are entities, and each Entity has several components. Size, Position, Movable - all this are different aspects of what an Entity possibly could do and are therefore each it's own Component. As for Systems, that's where most of the logic is.

Names like PositionableBoundable and MovableBoundable sound weird because it is weird, you are trying to use one name for two things. Composition over inheritance is the key here.

As for the name Boundable, I would probably have gone for just Box or Rect which are more well known.

\$\endgroup\$
  • \$\begingroup\$ I agree that an ECS is a solution here but I'm working on a library and I'd like to have explicit responsibilities for my objects so it is easier to use and reason about for my users. In my model Rect is Bounds. Boundable is an object which has bounds but they can change (therefore Bounds is immutable). This model works pretty well because I'm using Kotlin's delegation feature (the by keyword). So what you are saying that I should just have a Boundable (or whatever it will be renamed to) and have my implementors implement Positionable and Movable individually? \$\endgroup\$ – Adam Arold Sep 30 '18 at 12:33
  • \$\begingroup\$ I'm working on an UI toolkit and I already have a Box sadly. \$\endgroup\$ – Adam Arold Sep 30 '18 at 12:34
  • \$\begingroup\$ @AdamArold I can't say much more without looking at more of your code and knowing more about your goal with the library. \$\endgroup\$ – Simon Forsberg Sep 30 '18 at 12:50
  • \$\begingroup\$ Here is the lib: github.com/Hexworks/zircon \$\endgroup\$ – Adam Arold Sep 30 '18 at 15:15
  • \$\begingroup\$ And the Boundable: github.com/Hexworks/zircon/blob/master/zircon.core/src/main/… \$\endgroup\$ – Adam Arold Sep 30 '18 at 15:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.