2

I'm making an online game and it has a server handling smaller game server. We call it "MasterServer". This MasterServer listens to commands from both TCP and HTTP and answers to them using its own services. The thing is, the number of services is growing and I'm worried that it could reach a point where having then as simple fields would be too much.

Here's how it looks like

public class MasterServerImpl implements MasterServer
{
    private final Logger logger;

    private final LevelService levelService;
    private final LevelStatsService levelStatsService;
    private final ScoreService scoreService;
    private final AccountService accountService;
    private final FriendService friendService;
    private final GameHostingService gameHostingService;
    private final CosmeticService cosmeticService;
    private final MessageService messageService;
    private final ConfigService configService;
    private final VersionService versionService;
    private final CrashReportService crashReportService;
    private final ShopService shopService;

    private final DatabaseConnection dbConnection;
    private final QueryProvider queryProvider;

    private final HttpCommandReceiver httpCommandReceiver;
    private final TCPCommandReceiver tcpCommandReceiver;
    private final ChatServer chatServer;

// ...
// in constructor


    dbConnection = new DatabaseConnection(configService.getDatabaseURL(), configService.getDatabaseUsername(), configService.getDatabasePassword());

    try
    {
        dbConnection.testConnect();
    }
    catch(SQLException ex)
    {
        throw new InvalidConfigException("Could not connect to database", ex);
    }

    queryProvider = new QueryProviderImpl();

    levelService = new LevelServiceImpl(dbConnection, queryProvider, baseDir);
    levelStatsService = new LevelStatsServiceImpl(dbConnection, queryProvider);
    scoreService = new ScoreServiceImpl(dbConnection, queryProvider, baseDir);
    accountService = new AccountServiceImpl(dbConnection, queryProvider);
    friendService = new FriendServiceImpl(dbConnection, queryProvider);
    gameHostingService = new GameHostingServiceImpl(this, logger, port + 2);
    cosmeticService = new CosmeticServiceImpl(dbConnection, queryProvider);
    messageService = new MessageServiceImpl(dbConnection, queryProvider);
    versionService = new GameVersionService(versionRange, configService.getUpdateURL());
    crashReportService = new CrashReportServiceImpl(baseDir);
    shopService = new ShopServiceImpl(dbConnection, queryProvider);

    httpCommandReceiver = new HttpCommandReceiver(this, logger, configService.getHttpPort());
    tcpCommandReceiver = new TCPCommandReceiver(this, logger);
    chatServer = new ChatServerImpl(accountService, messageService, logger);

For commands to work, I pass them a MasterServer instance which is an interface with specification for each services. Basically it's an interface of getter for all services. So I've got a lot of getters too in that class.

Is there a better design than simply adding stuff without caring? A lot of service could get added in the future. Each service is long enough and merging them would lose some clarity in the structure.

3

With the example code you provided, your MasterServer is essentially the container for all your components (instantiating them through hand written code). You are getting to the point where dependency injection frameworks will really help you out. For example Spring in Java or NInject for C#.

That said, you should also start thinking about divisions of responsibility. For Example, you could have a CommandService that the HttpCommandReceiver and TcpCommandReceiver call when they receive commands. The CommandService would then execute those commands. You'll find that you will have families of services that work directly with each other, and you can reduce the number of touchpoints and the main interaction of your app will be with a handful of services that talk to each other at an application appropriate level of abstraction.

It also helps to communicate the design when you can consolidate your services/components into a handful of related component families.

  • Inside HttpCommandReceiver and TcpCommandReceiver there already is a collection of commands that use almost all the services availables. The commands exist to manage and interact with all the rest of the application and that touches all the services. A single command might only touch some services but all the commands combined touches all the services. Putting the logic of all the commands into a single CommandService would make a huge, unusable service. – Winter Jun 25 '18 at 16:09
  • 2
    @Winter, I only used that as an example. Another option is a message queue or event bus where the services that need to can subscribe to the command. They respond to only the commands that pertains to them and ignore all others. I don't know your system with the same level of detail as you do. I can only make suggestions for illustrative purposes. – Berin Loritsch Jun 25 '18 at 16:37
0

No, generally speaking having many services means you are splitting your logic out into separate classes and loosely coupling them.

However, the MasterServer sounds like it might be getting a bit weird.

You don't include an example of how you are using it, but my spidey sense is tingling. I would guess it shouldn't have any Getters for the services and you shouldn't be passing it around.

0

You should probably look at some dependency injection framework (read https://stackoverflow.com/questions/130794/what-is-dependency-injection) so you don’t have to pass this collection of dependencies around everywhere. Instead, you would define some service or other class that your classes depend on somewhere (like yourDatabaseConnection and the dependency injection framework will automatically insert it in classes that need it, for example with constructor injection. There are many frameworks out there, see what suits your needs. Spring does it quite well but may be too big of a framework for this purpose.

  • It doesn't sound like you're describing services. – Robert Harvey Jun 25 '18 at 16:51
  • Yeah I’ll just edit it so it’s about dependencies in general, thanks. – Sebastiaan van den Broek Jun 25 '18 at 16:54

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.