Basic
従業員の給与は、との 2 つの要素から計算されStandardPoint
ます。1 人の従業員は、毎月 1 つの Basic ポイントと 1 つ以上の (またはまったくない) StandardPoint を取得します。
StarPerformerPoint 、 RecognitionPoint 、 ReferralPoint 、 BrandingPoint など、さまざまな StandardPoints があります。
TotalAnnualSalary を計算する機能があります。従業員は、1 年間に最大 4 つの標準ポイントを利用する資格があります。これ以上点を取っても年俸合計は4点しか出ません。
次のコードがあります。それは正常に動作します。ただし、非効率的なメモリ使用率があります。StandardPointElement は複数回作成されます。
このシナリオでオブジェクトの作成を最適化するにはどうすればよいでしょうか?
アップデート
Flyweight パターンのようなものを使用できますか?
ウィキペディアはFlyweight パターンについて述べています
flyweight は、他の同様のオブジェクトとできるだけ多くのデータを共有することによって、メモリの使用を最小限に抑えるオブジェクトです。これは、単純な反復表現が容認できない量のメモリを使用する場合に、多数のオブジェクトを使用する方法です。
Flyweight Design Pattern - C#の記事で、Shailendra Chauhan は次のように述べています。
外部データは実行時にオンザフライで計算され、flyweight オブジェクトの外部に保持されます。したがって、ステートフルにすることができます。
コード
interface ISalaryScoreElement
{
int SalaryScore { get; }
}
public class BasicElement : ISalaryScoreElement
{
public int SalaryScore
{
get
{
return 100;
}
}
}
public class StandardPointElement : ISalaryScoreElement
{
public int SalaryScore
{
get
{
return 10;
}
}
}
従業員クラス
class Employee
{
private List<string> eligibility;
public List<string> EligibleSalaryTypes
{
get
{
return eligibility;
}
}
public Employee(List<string> eligibility)
{
this.eligibility = eligibility;
}
public int GetTotalAnnualSalary()
{
int totalSalary = 0;
ISalaryScoreElement sal = null;
CalculatorFactory factory = new CalculatorFactory();
int occurenceCountForStandardPoint = 0;
foreach (string salaryType in EligibleSalaryTypes)
{
switch (salaryType)
{
case "Basic":
sal = factory.GetSalaryElement("BasicElement");
break;
case "ReferralPoint":
sal = factory.GetSalaryElement("StandardPointElement");
break;
case "BrandingPoint":
sal = factory.GetSalaryElement("StandardPointElement");
break;
case "RecognitionPoint":
sal = factory.GetSalaryElement("StandardPointElement");
break;
case "StarPerformerPoint":
sal = factory.GetSalaryElement("StandardPointElement");
break;
default:
throw new Exception("No mapping available");
}
if (sal is StandardPointElement)
{
occurenceCountForStandardPoint++;
if (occurenceCountForStandardPoint > 4)
{
//StandardPointElement can be considered a maximum of 4 times for salary calculation
continue;
}
}
totalSalary = totalSalary + sal.SalaryScore;
}
return totalSalary;
}
}
工場
class CalculatorFactory
{
public ISalaryScoreElement GetSalaryElement(string salaryKey)
{
ISalaryScoreElement c = null;
switch (salaryKey)
{
case "BasicElement":
c = new BasicElement();
break;
case "StandardPointElement":
c = new StandardPointElement();
break;
default:
throw new Exception("Factory cannot create the object specified");
}
return c;
}
}
クライアント
class Program
{
static void Main(string[] args)
{
List<string> eligibleBonus = new List<string>();
//For January 2013
eligibleBonus.Add("Basic");
eligibleBonus.Add("StarPerformerPoint");
//For February 2013
eligibleBonus.Add("Basic");
eligibleBonus.Add("StarPerformerPoint");
eligibleBonus.Add("ReferralPoint");
//For March 2013
eligibleBonus.Add("Basic");
eligibleBonus.Add("BrandingPoint");
eligibleBonus.Add("RecognitionPoint");
//For April 2013
eligibleBonus.Add("Basic");
eligibleBonus.Add("BrandingPoint");
Employee e = new Employee(eligibleBonus);
int effectiveSalary = e.GetTotalAnnualSalary();
Console.WriteLine(effectiveSalary);
Console.ReadKey();
}
}