I am using flyweight pattern. [But this may not be the best solution]
REFERENCES
- Implementing the Singleton Pattern in C# - Jon Skeet talks about Thread Safety also.
- Why is the Flyweight Pattern practical?
- Flyweight Design Pattern - C#
Flyweight Factory
class CalculatorFlyweightFactory
{
Dictionary<string, ISalaryScoreElement> calculators = new Dictionary<string, ISalaryScoreElement>();
public int TotalObjectsCreated
{
get { return calculators.Count; }
}
public ISalaryScoreElement GetSalaryElement(string salaryKey)
{
ISalaryScoreElement c = null;
if (calculators.ContainsKey(salaryKey))
{
c = calculators[salaryKey];
}
else
{
switch (salaryKey)
{
case "BasicElement":
c = new BasicElement();
calculators.Add("BasicElement", c);
break;
case "StandardPointElement":
c = new StandardPointElement();
calculators.Add("StandardPointElement", c);
break;
default:
throw new Exception("Factory cannot create the object specified");
}
}
return c;
}
}
Flyweights
interface ISalaryScoreElement
{
int SalaryScore { get; }
//Newly Added
int OccurenceCount { get; set; }
}
public class BasicElement : ISalaryScoreElement
{
public int SalaryScore
{
get
{
return 100;
}
}
public int OccurenceCount { get; set; }
}
public class StandardPointElement : ISalaryScoreElement
{
public int SalaryScore
{
get
{
return 10;
}
}
public int OccurenceCount { get; set; }
}
Function
public int GetTotalAnnualSalary()
{
int totalSalary = 0;
ISalaryScoreElement sal = null;
CalculatorFlyweightFactory flyweightFactory = new CalculatorFlyweightFactory();
foreach (string salaryType in EligibleSalaryTypes)
{
switch (salaryType)
{
case "Basic":
sal = flyweightFactory.GetSalaryElement("BasicElement");
break;
case "ReferralPoint":
sal = flyweightFactory.GetSalaryElement("StandardPointElement");
break;
case "BrandingPoint":
sal = flyweightFactory.GetSalaryElement("StandardPointElement");
break;
case "RecognitionPoint":
sal = flyweightFactory.GetSalaryElement("StandardPointElement");
break;
case "StarPerformerPoint":
sal = flyweightFactory.GetSalaryElement("StandardPointElement");
break;
default:
throw new Exception("No mapping available");
}
if (sal is StandardPointElement && sal.OccurenceCount >= 4)
{
//StandardPointElement can be considered a maximum of 2 times for salary calculation
continue;
}
sal.OccurenceCount = sal.OccurenceCount + 1;
totalSalary = totalSalary + sal.SalaryScore;
}
return totalSalary;
}