Ashley John
Ashley John

Reputation: 2453

Design the classes

Hi I have a set of Calculator class that does the calculation for different types of Measures.I also have a factory class which calls the appropriate classes based on the type of Measure.

This is how my class looks like .

 private MeasureBase GetMeasureCalculator(MeasureType measureType)
    {
       MeasureBase returnValue;
        switch (measureType) 
        {
            case NewPqriMeasureType.Type1:
                returnValue = new Type1Calculator(_session);
                break;
            case NewPqriMeasureType.Type2:
                returnValue = new Type2Calculator(_session);
                break;
            default:
                returnValue = new Type1Calculator(_session);
                break;
        }
        return returnValue;
    }

This factory method is called like this.

   public IEnumerable<MeasureResult> GetMeasureResults(IEnumerable<int> measures, 
        IFocusSettings focusSettings)
    {
        IEnumerable<PqriMeasureResult> returnValue = Enumerable.Empty<MeasureResult>();

        IEnumerable<MeasureDefinition> measureDefinitions = _session.QueryOver<MeasureDefinition>()
          .WhereRestrictionOn(
              measure => measure.Id
          )
          .IsIn(measures.ToArray())
          .List();

        foreach (MeasureType measureType in Enum.GetValues(typeof(MeasureType)))
        {
            IEnumerable<int> measureKeys = measureDefinitions
                .Where(measureDefinition => measureDefinition.MeasureType == measureType)
                .Select(measureDefinition => measureDefinition.Id);

            if (measureKeys.Count() > 0)
            {
                returnValue = returnValue.Concat(
                    GetMeasureCalculator(measureType) // factory method
                        .CalculateMeasureResults(measureKeys, focusSettings)
                );
            }
        }

        return returnValue;
    }

Now the CalculateMeasureResults method is in my MeasureBase class.Its more like a template method pattern where function calls inside the CalculateMeasureResults is overridden inside the child classes.

Now here is my Problem. My Type2 for the measures is again going to be subtyped. say Type2_a,Type2_b. How can i incorporate it in current design. What i want is i will have is two concrete classes for Type2_a and Type2_b. When i call Type2Calculator.CalculateMeasureResults it should call the calculate for these two sub types and give me the result.My current design design doesn't allows this as CalculateMeasureResults is defined in my base class.

MeasureBaseClass

public abstract class MeasureBase
{

    protected MeasureBase(ISession session)

    {
        _session = session;

    }

    public abstract MeasureType AggregationType { get; }


     public string abstract DoFunction1();

     public string abstract DoFunction2();


    public IEnumerable<MeasureResult> CalculateMeasureResults(IEnumerable<int> measures,
                                                                           IFocusSettings focusSettings)
    {
        return _session.CreateSQLQuery(     DoFunction1()+DoFunction2()
                          )

       )
       .SetResultTransformer(Transformers.AliasToBean<MeasureResult>())
       .List<MeasureResult>();
    }

}

Upvotes: 0

Views: 95

Answers (1)

Rich O&#39;Kelly
Rich O&#39;Kelly

Reputation: 41767

If you're looking for a quick 'hacky' fix, simply declare CalculateMeasureResults as virtual in your base class and override at your leisure.

But from what it looks like, the CalculateMeasureResults should be the abstract method. You can then subclass with another abstract class to provide the default implementation that currently exists in MeasureBase and subclass away from there.

Upvotes: 1

Related Questions