• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Different functionality for different customers

 
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I am designing a specialized software application that shall be used by only two companies (most likely will always only be two, but possibility of three or four eventual end users). 99% of the code is identical for both customers, but a small percentage is slightly different (Example: A = B + C for customer one while A = B + C + D for customer two. A few constants are different based on the customer (so not truly constant)). I don't want two code bases.

What is the best way to integrate the exceptions into the code so each customer receives the correct calculations, etc..?

Thanks!
 
Ranch Hand
Posts: 775
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
For situations like you outlined, where not only the values may differ between customers but the number of variables (or the process) may differ between customers, the devil is often in the details.

Clearly you need to have some kind of abstraction point that you can use to hide the customer-specific differences. Template Method and Factory Method are obvious design patterns to consider... but only to a point. If the degree of customer-specific variation becomes too great, it may become harder to truly isolate those customer-specific difference just via those approaches alone. You can end up with some variation of "the fat interface problem", where you declare more and more methods or method parameters to accomodate all the variations, but for any one customer only a modest subset of those are applicable.

Definitely best to start simple, but if simple doesn't pan out then it is good to also keep in mind the patterns with more ability to impact multiple design elements - like Abstract Factory, Bridge, or Facade. Depending on the specifics of your app, one of those patterns could be used to keep you in sync when you have multiple components each having some customer-specific variations.

For an obvious example where keeping multiple components in sync is a challenge, imagine not just that you had to perform a calculation with 3 versus 4 variables, but also:

  • read/write 3 versus 4 variables to and from a database
  • allow view or modification of 3 versus 4 variables in a web page
  • obtain initial values of 3 of the variables from service "A", versus 2 of the variables from "A" and the other 2 from "B"


  • [ February 15, 2006: Message edited by: Reid M. Pinchback ]
     
    Ranch Hand
    Posts: 150
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Originally posted by TR Smith:
    What is the best way to integrate the exceptions into the code so each customer receives the correct calculations, etc..?

    Thanks!



    Hi TR,

    This sounds like the Strategy pattern to me. You could have an abstract superclass Calculation which contains the common methods. You also have CustomerACalc and CustomerBCalc classes which extend Calculation class class.

    Calculation declares abstract methods, which are the ones that differ between customers. Each of the subclasses implements these methods in the way that is suitable for that particular customer.



    HTH,

    Fintan
     
    author
    Posts: 608
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Can the differences be captured as meta-data? Perhaps the solution is to simply have two different configuration files/databases for them?

    - Scott
     
    (instanceof Sidekick)
    Posts: 8791
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Google up on "dependency inversion" for an interesting aspect of all this. Often a component "higher" in the architecture depends on interfaces defined "lower". For example, we call APIs defined by JDBC, we have a dependency on the JDBC interfaces.

    To plug in a different strategy for each customer, the "lower" level strategies must implement a common interface defined by the "higher" level core part of the system. If we write database drivers, we are forced to implement another set of interfaces defined by JDBC so JDBC can plug in any vendor's driver as a strategy.

    If the core owns the interface it can confidently call any implementation and expect it to work. You can get the implementation class from configuration and add new customers without touching the core:

    "Dependency injection" is another neat technique to push all the configurable dependencies into the core at startup. An application assembler reads the configuration and passes the proper strategies to the various components.

    This looks very similar, but simplifies the component and possibly removes its dependency on the configuration.
     
    reply
      Bookmark Topic Watch Topic
    • New Topic