1

Suppose I have some Java code such as the following (in this case, the use of the name "interaction" is referring to interacting with an object in a video game):

public abstract class Interaction
{
    private Interaction()
    {
        // ...
    }

    // base class stuff here, some public some private

    public static final class OneShotInteraction extends Interaction
    {
        public OneShotInteraction()
        {
            // empty
        }
    }

    public static final class OngoingInteraction extends Interaction
    {
        public OngoingInteraction()
        {
            // ...
        }

        // ...
    }

    public static final class ItemExchangeInteraction extends Interaction
    {
        public ItemExchangeInteraction()
        {
            // ...
        }

        // ...
    }

    public static final class InventoryInteraction extends Interaction
    {
        public InventoryInteraction()
        {
            // ...
        }

        // ...
    }
}

In this code, I'm defining derived classes for handling different types of interactions that all inherit from a shared base class.

My reasons for structuring the code in this way are:

  1. I want to limit the possible types of interactions to the ones defined here. I don't want code from other packages or modules being able to deliberately or inadvertently make their own interaction subclasses.

  2. The interaction classes need to be able to access other package-protected members of the package that they're currently in.

  3. I don't want to pollute the namespace of the package.

So I can't:

  • Put the derived classes in a separate package, because this requires using a public constructor in the base class and breaks (1).

  • Put the derived classes plus base class in a separate package, because this breaks (2).

  • Put the derived classes outside of the base class in the same package, because this breaks (3).

So my question is, would it be considered a bad pattern to put derived classes inside of their base class in this manner, considering the benefits that I see to namespace organisation and eliminating possible mistakes in the future?

2
  • Please show code that uses such a classs, in order to see how your design restrictions are actually enforced. Feb 13, 2023 at 8:58
  • Mostly it comes down to file organization. If the classes are very small, this is convenient. If they are very big, this is inconvenient. Feb 13, 2023 at 13:11

1 Answer 1

1

There is a good deal of opinion in this. I like the pattern and think it has exactly the benefits you mention.

However, here are some things to consider:

  • The "don't want to clutter the package" argument is very subjective. You could make the default constructor package-private and just put the subclasses into the same package, in separate files. It's really not that big a deal, and it may be a necessary compromise if other developers balk at the idea of putting all these classes into the same file.
  • If you do make them nested classes of Interaction, don't repeat that name in the inner classes' names. You will always have to refer to them with a qualified name anyway, and Interaction.OneShotInteraction is horrible; Interaction.OneShot is good.
  • If you are on Java 17 or later, use the new sealed classes feature that's made for exactly this use case.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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