2014-02-06 77 views
-1

员工的工资计算来自两个要素 - BasicStandardPoint。一名员工每个月将获得一个Basic和一个或多个(或不包含)StandardPoint。如何避免创建多个对象实例?

有各种StandardPoints - StarPerformerPoint,RecognitionPoint,ReferralPoint,BrandingPoint。

有一个功能来计算TotalAnnualSalary。在一年内,员工有资格获得最多4个标准积分。即使他得到更多分数,也只会计算总年薪计算中的4分。

我有以下代码。它工作正常。但是,存在一个无效的内存利用率。 StandardPointElement被创建多次。

我们如何在这种情况下优化对象创建?

UPDATE

我们可以使用类似轻量级的模式?

维基说约Flyweight pattern

甲轻量级是,通过与其它类似的对象共享尽可能多的数据可以最小化存储器使用的对象;当简单的重复表示使用不可接受的内存量时,这是一种大量使用对象的方法。

在文章Flyweight Design Pattern - C#,赛伦德拉Chauhan保持提到了以下

外在数据被计算的飞行装置在运行时,它被保持在轻量级对象以外的区域。因此它可以是有状态的。

Why is the Flyweight Pattern practical?

代码

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; 
     } 
    } 

} 

Employee类

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(); 
    } 

} 
+2

您已经发布了一段代码,几乎给了我们一些指导:“但是,内存使用效率并不高。 StandardPointElement是多次创建的“。这还不够具体,请更准确地描述你认为你的问题代码是什么,以及你认为问题是什么。 –

回答

0

我使用轻量级的模式。 [但这可能不是最好的解决方法]

enter image description here

参考

  1. Implementing the Singleton Pattern in C# - Jon Skeet关于线程安全也举行了会谈。
  2. Why is the Flyweight Pattern practical?
  3. Flyweight Design Pattern - C#

飞锤厂

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; 
    } 
} 

飞铁

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; } 
} 

功能

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; 
    } 
1

通话双方factory.GetSalaryElement("BasicElement");factory.GetSalaryElement("StandardPointElement");只有一次,在循环开始之前,和重用在循环的对象。

或者,如果你真的没有什么好做,有一个内部字典Dictionary<string, ISalaryScoreElement>CalculatorFactory类的字段,如果当前对象不存在将被填充,并从那里对象将被检索到,如果它确实存在。

1

你实际上是内存不足,还是什么?

无论如何,您始终可以为您只希望创建一次的课程实施Singleton pattern。关于如何实施的最佳讨论是由Jon Skeet撰写的:http://csharpindepth.com/Articles/General/Singleton.aspx

+0

我已经更新了这个问题 – Lijo

+0

@Lijo,在你粘贴对象的代码不使用内存,所以我仍然不明白你为什么担心这个问题.Flightweight模式很好,但有些情况下,你没有任何东西可以共享...... – Grzenio

1

听起来好像你想要使用单身模式为StandardPointElement。要做到这一点,创建一个静态字段来保存单个值。消费者将使用此值而不是陈述new StandardElementPoint()。此外,我所做的构造protected,以防止消费者意外地创造新的价值

public class StandardPointElement : ISalaryScoreElement 
{ 
    public static readonly StandardPointElement Instance = 
     new StandardPointElement(); 

    protected StandardPointElement() { } 

    public int SalaryScore 
    { 
     get 
     { 
      return 10; 
     } 
    } 
} 

新归在你的代码的new StandardElementPoint所有使用到StandardElementPoint.Instance

相关问题