正确的工厂模式

问题描述 投票:0回答:0

我在这种情况下使用工厂模式。但我不知道这是一个很好的实现。请帮我审阅并给我你的意见。感谢您 !对不起,如果我的英语水平不好

1.要求:

  • 输入:列表数据(object[][])

  • 输出:导出列表数据格式化为csv(object[][])

  • 用不同的规则格式化行数据中的每一列

    • 格式规则、零或空规则、舍入规则

    • 每种数据类型可能有一个或多个规则

      • 例如:

        • 第一列:日期类型,格式规则

        • 第二列:时间类型,格式规则,舍入规则

        • 第 3 列:货币类型,格式规则,零或空规则,舍入规则

2.想法

基于:https://www.dofactory.com/

  • 基本规则
    /// <summary>
    /// Product
    /// </summary>
    public interface IRule
    {
        object RuleBuilder(object value, CsvOutputConfiguration configuration);
    }
  • 制定规则

        /// <summary>
        /// ConcreteProduct
        /// </summary>
        public class TimeFormatRule : IRule
        {
    
            public object RuleBuilder(object value, CsvOutputConfiguration configuration)
            {
                if (RuleHelper.TimeIsValid(value, out TimeOnly time))
                {
                    if (configuration.GlobalSetting.FormatTime == 0) return value;
                    else if (configuration.GlobalSetting.FormatTime == 1) return value.ToString("HH:mm");
                }
                return value;
            }
        }
    
        /// <summary>
        /// ConcreteProduct
        /// </summary>
        public class TimeRoundRule : IRule
        {
    
            public object RuleBuilder(object value, CsvOutputConfiguration configuration)
            {
                if (RuleHelper.TimeIsValidGreaterThanZero(value, out string TimeOnly time))
                {
                   var roundTime = new TimeOnly(configuration.RoundTime, 0);
                   if (time < roundTime)
                      return roundTime;
                   else return time;
                }
                return value;
            }
        }
    
        /// <summary>
        /// ConcreteProduct
        /// </summary>
        public class ZeroFormatRule : IRule
        {
            public DataType DataType { get; init; }
    
            public ZeroFormatRule(DataType dataType)
            {
                DataType = dataType;
            }
            public object RuleBuilder(object value, CsvOutputConfiguration configuration)
            {
                if (DataType == DataType.Km && (int)value == 0)
                   return 0.00;
                else if (DataType == DataType.Amount && (int)value == 0)
                   return $"${0:N3}"
    
                else if (DataType == DataType.Time && (int)value == 0)
                   return "00:00"
                return value;
            }
        }
    
        public enum DataType
        {
            Time,
            Km,
            Amount,
            Number
        }
    
  • 基地创建者

        /// <summary>
        /// Creator class
        /// </summary>
        public abstract class Column
        {
            private List<IRule> _rules = new();
            public List<IRule> Rules { get { return _rules; } }
    
            public Column()
            {
                BuildColumn();
            }
    
            public abstract void BuildColumn();
    
            public object ConvertValue(object value, CsvOutputConfiguration configuration)
            {
                object convertedValue = value;
                foreach (IRule rule in Rules)
                {
                    convertedValue = rule.RuleBuilder(convertedValue, configuration);
                }
    
                return convertedValue;
            }
        }
    
  • 创造者

        /// <summary>
        /// ConcreteCreator
        /// </summary>
        public class TimeColumn : Column
        {
            public override void BuildColumn()
            {
                Rules.Add(new TimeRoundRule());
                Rules.Add(new TimeFormatRule());
                Rules.Add(new ZeroFormatRule() { DataType = DataType.Time });
            }
        }
    
        /// <summary>
        /// ConcreteCreator
        /// </summary>
        public class KmColumn : Column
        {
            public DataType DataType { get; init; }
    
            public override void BuildColumn()
            {
                this.Rules.Add(new ZeroFormatRule() { DataType = DataType.Km });
            }
        }
    
    
    
  • 超级创作者

        /// <summary>
        /// Super creator
        /// </summary>
        public abstract class RowCreator
        {
    
            public List<Column> Columns { get; init; }
    
            public CsvOutputConfiguration Configuration { get; init; }
            protected RowCreator(List<Column> columns, CsvOutputConfiguration configuration)
            {
                Columns = columns;
                Configuration = configuration;
            }
    
            public abstract object[][] CreateRow();
        }
    
  • 超级创造者

        /// <summary>
        /// Concreator
        /// </summary>
        public class MonthlyRowCreator : RowCreator
        {
            public object[][] Data { get; init; }
            public MonthlyRowCreator(List<Column> columns, CsvOutputConfiguration configuration, object[][] data) : base(columns, configuration)
            {
                Data = data;
            }
    
    
            public override object[][] CreateRow()
            {
                var results = new object[][] { };
                for (int i = 0; i < Data.Count(); i++) 
                {
                    for (int j = 0; j < base.Columns.Count; j++)
                    {
                        results[i][j] = Columns.ElementAt(j).ConvertValue(Data[i][j], base.Configuration);
                    }
                }
    
                return results;
            }
        }
    
  • 客户端实现

    // ------------- Client implementation
    object[][] listData = new object[][] {
        new object[] { "0800", 15.5 },
        new object[] { "0700", 15.5 },
        new object[] { "1500", 13.5 },
        new object[] { "0800", 0 },   
    };
    
    // ------------ Define rule
    var listColumn = new List<Column>()
    {
        new TimeColumn(),
        new KmColumn()
    };
    // ------------ Setting
    var configuration = new CsvOutputConfiguration()
    {
        FormatTime = 1,
        RoundTime = 2
    };
    
    // ------------ Call factory
    
    RowCreator creator = new MonthlyRowCreator(listColumn, configuration, listData);
    
    var finalData = creator.CreateRow();
    
c# factory-pattern
© www.soinside.com 2019 - 2024. All rights reserved.