I have a table-like feature set in a game. What it means is I have 10 types of battle, and 10 types of features related to battles, like hints, start/end logic, rewarding/spending resources, statistic etcetera. For every type of battle each feature has it's own unique conditions and outcomes, resulting in total of 100 individual logic pieces. I'm unable to come to any adequate arranging pattern for this logic. And I need this pattern for team of developers to follow, otherwise there is complete chaos. What's really important, these logic pieces should be working somewhat independent in several different module-based projects, where each project can or cannot include some of features and battle types. And for the cherry on top: not all battle types should have implemented a logic for every feature.
1. Initially I had a swicth-case statement in every feature for each type of battle.
- intuitive, easy to read (Clarity+)
- quick to modify (Maintainability+)
- every logic bit of a feature in one place (Clarity++)
- all battle types listed in one place (Cohesion++)
- necessity to modify code in every feature in case of adding new battle type (Extensibility--)
- no code pattern, resulting in freedom to add anything anywhere (Maintainability--)
2. For my next iteration I've decided to mirror that scheme and list all feature logic bits inside controllers dedicated for each battle type. I've added one interface covering all features. It's somewhat based on Template-method pattern.
- everything considering one type of battle in one place (Clarity++)
- adding new type of battle is easy, just need to implement one interface (Extensibility++)
- adding new feature is easy, just add new method to interface and be forced by compiler to implement it everywhere (Extensibility++)
- one class contains too much different logic of different features. (Cohesion+++)
- it's not clear where such controller should be located, considering module-based system of projects (???)
3. Now I'm planning to create a "table" of classes, each individual controller for each feature-battle crossing. For each feature there should be an interface, and for each battle type an implementation of such interface. Accessing such implementation would be through a special manager.
- full abstraction. (Extensibility+++ Clarity-)
- implementations can be placed inside module of a feature (Clarity+)
- huge amount of tiny classes (Maintainability- Clarity-)
- No compile errors in case of missing implementations. Need to develop new observer, to throw errors in case of some implementation missing, or existing when not expected, resulting in necessity to have small database with all feature settings. (Complexity++ Extensibility-)
- nesseity to develop a special manager for accessing logic. All logic bit must be registered to it's battle type by mentioning ID from enum BattleType. (Complexity+)
None of these solutions seems good enough. So, what's the best course of action here? Thanks Internet!