This discussion is archived
4 Replies Latest reply: Dec 12, 2012 5:19 AM by 814889 RSS

Which Design Pattern and how to design using OOP this scenario

814889 Newbie
Currently Being Moderated
I am having trouble designing a module, can anybody help me?

Because it will be hard to maintain this kind of module, I also think that this can test my skill of design pattern usage.

Requirement

This is basically an agricultural project (web application). I need to design a module where some calculation takes place.

There are different crops involved like maize, tomato, okra etc. Each of these crops has different traits.

Each trait has a measurement scale which lies in integer like 200-1000. Now let's say I have planted the crop and done measurement noted down the traits. Now I want to do some sort of measurement. Some measurements are simple and some are complex.

Example

Lets take an example of crop maize. I have recorded observations for 15 traits. (We'll use trait1-trait15 as examples, the actual name can be like plt_ht, yld, etc.)

I recorded 5 observations for each trait:

trait1 trait2 trait3 trait5 trait6..... trait15
01,02,03,04 01,02,03,04 01,02,03,04
User logs into system and selects his crops and enters data for these observations. I have to calculate either average or sum of the data entered for each trait.

Complexity / centre of the problem

So far it's simple but complexity comes when I have some different formulas for some of the traits.

Example: trait YLD has a formula based on which I have to calculate its value, which may also depend on some other traits. Each different crop can have different traits.

All this I am able to do - whenever user selects crop I will check for those specific traits and do calculations (if it's not a special trait then I either average or sum it, based on db entry), but there is a lot of hard coding.
I would like to have suggestions on a better way of handling this.

My code needs to handle both simple and complex calculations.
Simple calculations are easy, I have take average of value entered for trait.
The problem comes when I have to do complex calculations, since each crop have different traits with their own formulas, so to calculate I have to check for crop and then for complex trait. So I have to hardcode the trait name of complex traits.
Can any tell me how I can design this using Java oops [?!?] so that I can make it generic?

I have about 10 different crops. Some calculations are specific to crops, so there will be lot of code like the if below:
 hasZeroValue = (HashMap<String, ArrayList<String>>) dataValues[1];
} else if(cropId.equalsIgnoreCase("MZ") && traitName.equalsIgnoreCase("Shelling")) {
    avg=HybridTestDataUtility.calculateAvg(traitName, dataPoint, dataTraits, traitValues,dataPvalues, dataPoint, type);
    avg=avg*dataPoint;
    traitAvg=getMaizeYeild(traitName, traitAvg, population, avg, hybrid, area);
} else if(cropId.equalsIgnoreCase("OK") && traitName.equalsIgnoreCase("YLDGM")) {
    avg=HybridTestDataUtility.calculateAvg(traitName, dataPoint, dataTraits, traitValues,dataPvalues, dataPoint, type);
    //avg=avg*dataPoint;
    Object[] dataValues=getOKRAYield(traitName, traitAvg, population, avg, dividend,hasZeroValue,hybrid,repl);
    traitAvg = (HashMap<String, Float>) dataValues[0];
    hasZeroValue = (HashMap<String, ArrayList<String>>) dataValues[1];
} else if(cropId.equalsIgnoreCase("HP") && traitName.equalsIgnoreCase("w1-w10")) {
    avg=HybridTestDataUtility.calculateAvg(traitName, dataPts, dataTraits, traitValues,dataPvalues, dataPoint, type);
    avg=avg*dataPoint;
    Object[] dataValues=getHotPepperYield(traitName, traitAvg, population, avg,dividend,hasZeroValue,hybrid,repl);
    traitAvg = (HashMap<String, Float>) dataValues[0];
    hasZeroValue = (HashMap<String, ArrayList<String>>) dataValues[1];
} else if(cropId.equalsIgnoreCase("TO") && traitName.equalsIgnoreCase("TLSSG_70")) {
    traitAvg=calculateTLCV(traitName, traitAvg,dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues,50);
} else if(cropId.equalsIgnoreCase("TO") && traitName.equalsIgnoreCase("TLSSG_100")) {
    traitAvg=calculateTLCV(traitName, traitAvg,dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues,50);
} else if(cropId.equalsIgnoreCase("TO") && traitName.equalsIgnoreCase("YVMV_60")) {
    traitAvg=tomatoYVMVCalculation(traitName, traitAvg,dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues);
} else if(cropId.equalsIgnoreCase("TO") && traitName.equalsIgnoreCase("YVMV_90")) {
    traitAvg=tomatoYVMVCalculation(traitName, traitAvg,dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues);
} else if(cropId.equalsIgnoreCase("TO") && traitName.equalsIgnoreCase("YVMV_120")) {
    traitAvg=tomatoYVMVCalculation(traitName, traitAvg,dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues);
} else if(cropId.equalsIgnoreCase("TO") && traitName.equalsIgnoreCase("ELCV_60")) {
    traitAvg=tomatoYVMVCalculation(traitName, traitAvg,dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues);
} else if(cropId.equalsIgnoreCase("TO") && traitName.equalsIgnoreCase("ELCV_90")) {
    traitAvg=tomatoYVMVCalculation(traitName, traitAvg,dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues);
} else if(cropId.equalsIgnoreCase("TO") && traitName.equalsIgnoreCase("ELCV_120")) {
    traitAvg=tomatoYVMVCalculation(traitName, traitAvg,dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues);
} else if(cropId.equalsIgnoreCase("OK") && traitName.equalsIgnoreCase("YVMV_60")) {
    traitAvg=tomatoYVMVCalculation(traitName, traitAvg,dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues);
} else if(cropId.equalsIgnoreCase("OK") && traitName.equalsIgnoreCase("YVMV_90")) {
    traitAvg=tomatoYVMVCalculation(traitName, traitAvg,dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues);
} else if(cropId.equalsIgnoreCase("OK") && traitName.equalsIgnoreCase("YVMV_120")) {
    traitAvg=tomatoYVMVCalculation(traitName, traitAvg, dataPoint, dataTraits, hybrid, repl, traitValues, dataPvalues);
} else if(cropId.equalsIgnoreCase("OK") && traitName.equalsIgnoreCase("ELCV_60")) {
Can anybody think of a way to make a generic approach to this?
  • 1. Re: Which Design Pattern and how to design using OOP this scenario
    Kayaman Guru
    Currently Being Moderated
    Maybe create a class for each crop (with possibly a common superclass or interface) that encapsulates the calculation rules. A possibility is also to have the class identify which crop/trait it can do the calculations for.
    Then you can suggest the crop for each instance you have, and only the suitable one(s) will actually perform the calculation.

    Having huge if--else groups usually means bad design, causing maintainability issues and general programmer anger.
  • 2. Re: Which Design Pattern and how to design using OOP this scenario
    814889 Newbie
    Currently Being Moderated
    Thank you,

    There about 10 crops and each crop has 100 trait within that 100 traits 10 of them behave differently .Can you please expain me more.
  • 3. Re: Which Design Pattern and how to design using OOP this scenario
    Kayaman Guru
    Currently Being Moderated
    Vicky wrote:
    Can you please expain me more.
    I'm afraid it's not that simple. There's no shrinkwrapped solution that I can give you, "do it like this".
  • 4. Re: Which Design Pattern and how to design using OOP this scenario
    814889 Newbie
    Currently Being Moderated
    There are crops and each crop have traits , traits are actually a mesuremet
    scale to decide growth of a seed of a particular crop.
    This module is to for planters to observe growth of seeds sowed of certain
    crops and take down n no of observation for each trait and upload in csv format.Once they enter
    data i have to either avg out the values or sum the values or sometimes
    there are more complex function that i have to apply it may differe for each
    trait .This is the whole module about.Just to give an idea about how they
    will enter data


    Hyubrid(seed) trait1 trait2 trait3 trait5 trait6..... trait15
    Hybrid1 01 02 03 04 01
    HYbrid2 04 06 08 04 01
    HYbrid2 04 06 08 04 01
    HYbrid2 04 06 08 04 01
    HYbrid2 04 06 08 04 01

    Once they enter data in this format i have to give result something like
    this.

    Here avg colum does not necessaryly mean avg it can be sum or any formula
    based resutl.Hybrid is the seed for which they record the observation.
    I have shown avg column only for two tratis it is actually for all the
    traits.


    Hyubrid(seed) trait1 Avg trait2 avg trait3 trait5 trait6..... trait15
    Hybrid1 01 01 02 04 03 04 01
    HYbrid2 04 04 06 10 08 04 01
    HYbrid2 04 04 06 12 08 04 01
    HYbrid2 04 04 06 14 08 04 01
    HYbrid2 04 04 06 12 08 04 01

    Hope this clarifies atleat a but

    The data are not correctly indented but there is no way i can format it.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points