Project hierarchy at odds with class hierarchy

This is a question about an object-oriented programming concept

I’m creating a game with various features – group games, games played under an aliases, games that allow users to exchange messages

Q: Should I have a separate class for each feature?

: If so, how do I bring these various “feature classes” together?

: Do I have a subclass that combines the features by treating feature-classes as base classes? That seems counter-intuitive, since it is not the basic game that inherits from the features; it is the features that inherit or build on the basic game.

: Perhaps, once again, the class factory concept provides the answer. I would have one giant class, combining all features, but a factory would be used to assemble it from manageable “class fragment” components.

: What is the normal or recommended way to implement a features hierarchy?

By EarthBotV2 via Discussions on Python.org at 06Jul2022 12:18:

This is a question about an object-oriented programming concept

I’m creating a game with various features – group games, games played under an aliases, games that allow users to exchange messages

Q: Should I have a separate class for each feature?

For a complicated feature, probably, if only to isolate the state and
code.

: If so, how do I bring these various “feature classes” together?

: Do I have a subclass that combines the features by treating feature-classes as base classes? That seems counter-intuitive, since it is not the basic game that inherits from the features; it is the features that inherit or build on the basic game.

The nature of a superclass is that in some ways it is the “basic”
class: it describes common interfaces, but doesn’t provide all the
implementation. So this isn’t necessarily nonsensical.

You might implement the features as mixins, expecting to be part of a
game: providing methods and supporting attributes. Or you might
implement the features standalone, accepting references to relevant
other objects. For example, you might define a Player, a group of
Players, a Messages class which used a reference to a Players
instance, etc. And define a game to have references to each of these.

class Game:
    def __init__(self, max_users, allow_aliases=False, allow_messaging=False):
        self.max_users = max_users
        self.allow_aliases = allow_aliases
        self.players = Players()
        self.messages = Messages(self.players)
        self.aliases = {}
    def __getitem__(self, name):
        ''' Get `Player` by alias or direct name.
        '''
        if self.allow_aliases:
            player = self.aliases.get(name)
            if player:
                return player
        return self.players[name]

In this example, allowing aliases is a mode rather than a class.
Multiplayer is also a mode expressed as the max number of users. You
make a class for all the players, and a class for a messaging system
which mediates between your self.players collection of players.

All this is made up and may not fit your plans.

I think I’m aiming at:

  • some “features” may just be “modes”: on/off, or a limit on the number
    of players
  • make self contained things for complex stuff like a messaging system,
    or a player, or a group of players
  • classes needn’t be a strict hierachy - superclasses and subclasses are
    a hierarchy, but your game structure might just be a graph of
    connected things (a game, some players, a messaging system, each
    knowing about the others as relevant)

: Perhaps, once again, the class factory concept provides the answer.
I would have one giant class, combining all features, but a factory
would be used to assemble it from manageable “class fragment”
components.

Aye, this.

: What is the normal or recommended way to implement a features
hierarchy?

I’m more a prototyper than a class designer. Write a feature standalone.
If you make a variant feature of the same kind, write it, then consider
how similar they are. Pull the similarities (method names, common state
attributes) into a superclass, leaves the differences in the subclasses.
i.e. get the pragmatics right before trying to generalise too much.

This is ad hoc advice, not design theory advice I guess, and a bit
rambling.

Cheers,
Cameron Simpson cs@cskk.id.au

Your response is very helpful! It gives me much to think about. I appreciate the time and thought you put into composing the post.

I’m coming to the conclusion that a class tree, even with multiple bases, is not adequate for modeling the real world. But a network, where anything goes, amounts to no structure at all. I suspect that what is needed is a two ended tree – branching out from the base class then branching back in to a “crown class” – where the crown might contain little more than references, as in the example you offer.

It’s an interesting question, is it not? Anyway, it’s back to work!

= =

Your comment prompted me to read about mixins. Waded through the comments at StackOverflow .

Came to the conclusion that a mixin is just a “helper class”. The main class includes it in the __bases__ list to steal its functionality, not to inherit. If that is a correct understanding, then the __bases__ list can be used to specify both the vertical parentage and the horizontal resources to be plagiarized. Perhaps it would make sense then to have two lists, one for vertical inheritance and one for horizontal appropriation!