设计模式从同一输入参数输出单独的不同文件

时间:2014-09-02 22:14:58

标签: c# design-patterns

我有这个Food类有20个属性。我需要使用这个Food类并输出3个不同的文件,使用这20个字段的变体。例如,文件1仅包含8个字段。文件2包含15个字段。文件3包含18个字段。

所以现在,我有这三种不同的方法。

    FoodService()
    {
        void WriteRecommendedFood(IList<Food> foodList);
        void WriteRecommendedFoodCalculation(IList<Food> foodList);
        void WriteRecommendedFoodAllEligibleFoods(IList<Food> foodList);
    }

所以我写道:

    public void WriteRecommendedFood(IList<Food> foodList)
    {
            using (StreamWriter sw = new StreamWriter("file.csv", false)
            {
                    StringBuilder sb = new StringBuilder();
                    foreach (Food f in foodList)
                    {
                            sb.Append(f.Field1); 
                            //Repeat for the # of fields I want to spit out
                            sb.Clear();
                            sw.WriteLIne(sb.ToString());
                    }
                    sw.Close();
            }
    }

我觉得我正在写三次相同的代码(略有不同)。 我开始阅读不同的设计模式,如访问者和策略模式,但我不确定改进我的代码的设计模式。 (注意:此时我只需要将其输出到逗号分隔文件。此外,从UI端,用户可以选择要输出哪一个(所有3个文件中的一个。)任何建议?

2 个答案:

答案 0 :(得分:2)

似乎这三个函数之间唯一的变化是写入的字段列表。有几种方法可以表示程序中的“字段”(以及字段列表);其中一个最方便的功能就是从Food实例中提取该字段的值。

此表示的类型为Func<Food, object>,因此使用List<Func<Food, object>>您就可以了。

public void WriteFoodData(IEnumerable<Food> foodList, IEnumerable<Func<Food, object>> valueProviders)
{
    using (StreamWriter sw = new StreamWriter("file.csv", false))
    {
        StringBuilder sb = new StringBuilder();
        foreach (Food f in foodList)
        {
            foreach (var provider in valueProviders)
            {
                sb.Append(provider(f).ToString());
            }
            sw.WriteLIne(sb.ToString());
            sb.Clear();
        }
    }
}

现在您可以创建“字段列表”并使用它来调用此方法:

var valueProviders = new List<Func<Food, object>>
{
    f => f.Field1,
    f => f.Field4,
    // etc
};

var foods = /* whatever */
WriteFoodData(foods, valueProviders);

答案 1 :(得分:1)

我会从FoodService中删除格式化的责任并将其注入。

    public class FoodService()
    {
        public void WriteRecommendedFood(IList<Food> foodList, IFoodFormatter formatter)
        {
            using (StreamWriter sw = new StreamWriter("file.csv", false)
            {
                StringBuilder sb = new StringBuilder();
                foreach (Food f in foodList)
                {
                   sw.WriteLine(foodformatter.Format(f));
                }
                sw.Close();
            }
        }
    }

    interface IFoodFormatter
    {
        string Format(Food f);
    }

您可以创建具体的格式化程序,例如CalculationFormatterElligableFoodsFormatter