2

Situation:

My app exists as standard and branded version, the branded version has some tiny additional features but most stuff is the same.

Right now i have a basic library with popups and visual elements that i can use in every app i make. Then there are several modules (libraries) (features of the app "things one can do") and two final app projects.

One module, in the branded version can use auxilliary hardware (ah). So my idea was to split up the module into a library base-module and create an additional library for the ah and then make two module one with and one without ah. This way any basic change to the module would be incorporated into all apps but the branded one would chose the module with ah and the standard app would take the one without.

There is a chance that a second branded version will come soon, with some modules different and maybe different hardware used by some modules. I would have to split up even more and i fear for chaos. But the only other way i see is that i create omni-modules that can handle every possible variation and will be instantiated with a selection of which features to contain. But it is clear that "brand a" will never use hardware of "brand b" and vice versa, so the selection will really just be "standard, a or b" but the module is built to handle them all which might bloat up the module.

So how would i split up my libraries and or module to handle this without much chaos ?

edit

My main concern is long term maintenance. After 2 years someone wants to add a feature to brand version xyz and i have to figure out into which library/at what level to implement it to not touch other versions.

Having many libs may make it hard to figure out the relations/dependencies between them but that can be compensated by proper documentation. Having it all in one lib/module means that i need to follow variables that enable/disable features to find out where they change/do stuff.

But how far do i split stuff up?

  • First you should have your own version of your libraries and those of your apps, your apps depends on specifics version of your libraries. Second : for can create specific module for each brand specific stuff, and only the application for the specific brand would have a dependcies toward it. Do you know Maven ? Or other tools that handles dependencies for you (and not only ) – Walfrat Aug 1 '17 at 14:35
1

If this were my project, I would make all the components that are common into their own modules. Thus, allowing them to be versioned, tested, and released on their own schedules. Create a middle layer that leveraged feature flags to enable and disable the parts of the application. This could be done manually in configuration or automatically by checking which modules are loaded. Finally, I would finish it off by creating branded applications that extended the Middle Layer and selected the features they need, along with providing the assets for branding.

Module 1--|                 |--Branded A
          |                 |
Module 2--|---Middle Layer--|--Branded b
          |                 |
Module 3--|                 |--Branded C   

As for the chaos, small modules may be frowned upon by some, still, they have many practical advantages over larger monolithic projects. Small modules are easier to write, they are easier to test, easier to version, and easier to release. The only way to avoid the chaos managing the modules is to break out features that are generally complete and there is a direct need to share them.

If a module is under heavy development and being released frequently you can reduce the chaos by updating every few weeks instead of daily.

0

I agree that splitting feturesets into vertical-slices is a good thing on the level of classes/namespaces.

On the level of different/independant moduls/libs i see more harm than benefit to have a specific library per brand-app : It may make maintanace and refactoring harder:

  • which feature is available in what module/brand: this is a political decision I assume that this will change a lot over time.

Having one modul/lib per featureset is a good thing. Having one modul/lib per brand-app is not.

I would prefer to have version specific global boolean constant where the compiler / obfuscator will optimize away features if const is false.

// class GlobalConfig is different for every variant
public class GlobalConfig {
    public static final boolean hasFeatureA = false;
}

if (GlobalConfig.hasFeatureA) {
    // this code will be removed by java compiler if GlobalConfig.hasFeatureA == false
}
  • I don't understand ur global const idea, for libs to know about the const it would have to be implemented in the very base lib – NikkyD Aug 2 '17 at 13:42
  • if (GlobalConfig.hasFeatureA) { goes into the different product-flavors (which you called BrandApp) to control, if a feature is available in the flavor or not. – k3b Aug 2 '17 at 14:32

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.