1

I would like some input to the following problem. Our product consists of many separate "modules" which can depend on each other.

To bundle them up to a final product we create another "module" to bundle all these modules to one.

The biggest problem is customer specific code. Let's assume customer A like module B in a different way than customer C needs module B to behave. And this problems extends to all modules. So every module could come in different flavours if you like.

The current solution is to overwrite behaviour in the end project and create a new end project for every customer.

Has any of you a good idea to handle this problem? I would love some input on this problem.

3
  • You seem to already use "distribution projects" to bundle all modules for a customer distribution. At some point you have to write down the differences between the customers. What is your problem with your current solution? Where do you put work in, when you create the customer distribution project?
    – chromanoid
    Commented May 19, 2016 at 19:57
  • There are literally dozens of copies of this question on this site. The answer is always Plug-In Plug-In Plug-In.
    – RubberDuck
    Commented May 20, 2016 at 23:05
  • @RubberDuck no. There are other ways besides "plugins". You could use buildtools to compile functionality without having a plugin system at all. Plugins are one kind of plugability. Commented May 22, 2016 at 7:33

3 Answers 3

2

I think this is a prime example of when IoC containers can be useful. You can create different configurations for each customer that decides how your factories are initialized, what strategies are injected, what classes you use for what interfaces and so on.

This, together with an all-around pluginish design lets you vary functionality in subtle ways in a really neat manner. The real challenge is of course to find what parts are moving and where you need to protect yourself from change.

2
  • and the front end? For me it sounds I have to build a different front end for big changes in the logic?
    – Daniel
    Commented May 19, 2016 at 5:46
  • It depends. What do you mean by "changes in the logic"? If you have the same use-cases but with different validation rules or authentication or just tweaked business rules in general, you can generalize your UIs using something like the MVP/MVVM patterns and again let your config/IoC container inject different strategies and validators etc. then just make different views if they need to look different too. If you have blatantly different use-cases that have little or nothing to do with eachother, then yeah, you're gonna have to make different UIs to invoke them.
    – sara
    Commented May 19, 2016 at 6:59
2

The question is not independend from the concrete project and what technical abilities you have to ensure modularity.

In terms of patterns, this is a classical Strategy Pattern together with Inversion of Control. You have to abstract away every concrete functionality and factor it out to the module.

Say you were doing a software to calculate taxes. In a naive implementation you would implement a UI with buttons and actions and alongside the tax calculation. Your software is a real success, that you have requests from all over the globe to customize for many languages and tax-systems.

Internationalization is easily done with string-replacement (so to say). But, besides other languages you have to deal with completely different business logic / tax laws. In order to accomplish your task, you begin to abstract away the concrete business logic into modules. E.g. you define a common API for every set of business rules and encapsulate the rules in different engines.

You separate commands like calculate taxes from the implementation in the concrete engine. So you end up with your application acting as a record player with the abstract ability to play music and which music is played depends on the concrete vinyl.

In the UI, you have containers, which could be filled dynamically with components depending on the module configuration you use.

How you solve this problem technically is up to you:

  • using a plugin system
  • compiling one product from different sources
  • shipping your product with every possible module and decide at runtime, what to use
  • having a webapplication with slightly different endpoints for customer-components

etc. pp.

tl; dr

you have to make your architecture pluggable

1

I think the core of your problem is insufficient decomposition of your "modules". You need to split them to a fine-enough grained model that you can find more reuse. If Customer A, which I will call Cust1 wants something in Module B, which I will call Mod1 that is different than Customer C, which I will call Cust2 wants, then you probably want to extract the common bits of Mod1 into a new Module Mod2, which is shared between Cust1 and Cust2. Then Cust1 can create a new module based on Mod2 which we will call Mod2Cust1, and Cust2 can create a new module based on Mod2 which we will call Mod2Cust2. If there is no way to decompose Mod1, into the submodules, then they are inherently different enough that there is no reuse between them, and you need separate modules for each customer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.