4 Replies Latest reply: Dec 12, 2012 7:19 AM by 814889 RSS

    Which Design Pattern and how to design using OOP this scenario

    814889
      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
          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
            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
              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
                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.