What is the best way to organize classes / packages in a framework so that the client of my application can easily extend them?

Suppose I am responsible for developing the Scrabble game, as one of the main requirements of the client is the ability to try different ways and methods of the game later. I have already made a design that is flexible enough to support these changes. It remains only to leave a request to the client (access modifiers for objects) and how to organize it (how to expose my objects in namespaces / packages).

How can I define such things so that the client can easily use my standard implementation (the standard Scrabble game and still be able to make all the changes that he wants?) I assume that I need some kind of structure that he can work with .

I organized my classes / interfaces in a non-strict multi-level system:

Data types

Contains the basic data types that can be used throughout the system. Access to this package and its members can be obtained by any user in the system. All its members are publicly available.

Domain

Contains all the interfaces that I have defined, and which may be useful for creating new Scrabble implementations for clients. Also contains value types, such as Piece, which are used in the game. All its members are publicly available.

Implementation

Contains all the necessary classes / code for implementing my standard Scrabble game in the Implementations.StandardScrabble package. If the client decides to implement other variants of the game, he can create them in the Implementation. XYZ, for example. These classes are protected by all packages, and the only thing that is available outside the package is the facade of the game. Uses Domain and Data Types packages.

User interface

Contains a user interface class that I implemented so that both the client and users of the program can run the game (my implementation). Access to all other layers.


There are several drawbacks to how I organize things, the most obvious of which is that if a client wants to create his own version of the game, he will have to basically implement almost everything on his own (I share interfaces in the Domain, but he can’t do anything with them to do). I feel that perhaps I should pass all the implementation classes to the Domain and then only have the facade that creates my standard Scrabble in the "Implementations" namespace?

How would you approach this? Is there any recommended reading on how to create such programs (mostly frameworks)?

thanks

+6
java c # oop frameworks uml
source share
4 answers

I think that you are trying to give too much freedom to the client. This must be making your job difficult. Based on what you described, it seems that the client will be able to modify almost all parts of your game - model, logic, user interface ... I think it would be better to limit the variable areas in your application, but to expose some of them through a common Plugin set of interfaces. This would make it easier for the user - he would only need to find out how the plugins work, and not the entire application logic. Define areas for your plugins, if you want - UI plugin, game mode plugin and so on. Many production applications and games work this way (think of Diablo II and the AWESOME many plugins that are!).

+2
source share

For algorithms and strategies, I would define interfaces and implementations by default and provide abstract superclasses that are extended by your own implementations, so that all template code is in an abstract superclass. In addition, I would allow the client to subclass your impl. Just make more than one implant and you will see what to place there.

But most importantly: Give your client a code. If he needs to understand where to place his code, he must also be able to see what you have encoded. No need to hide things.

+2
source share

No matter what design you come up with, I would be mistaken on the side of hiding as much of the implementation as possible. After you expose the implementation, you cannot return it (if you are not ready to wage a fiery war with your client base). You can always provide a default implementation later as you see fit.

In general, I would start by providing only thin interfaces. Then, before providing abstract classes, I can suggest utility classes (e.g. Factories , Builders , etc.).

I would recommend reading Effective Java by Josh Bloch for useful general practices when developing object-oriented code.

+2
source share

MVC / Compund Pattern

You can publish an earlier version of your package. later you can update it based on user requirements.

If you use the wisdom of MVC or another complex template, I believe that you can also easily upgrade your package.

0
source share

All Articles