我在这种情况下使用工厂模式。但我不知道这是一个很好的实现。请帮我审阅并给我你的意见。感谢您 !对不起,如果我的英语水平不好
1.要求:
输入:列表数据(object[][])
输出:导出列表数据格式化为csv(object[][])
用不同的规则格式化行数据中的每一列
格式规则、零或空规则、舍入规则
每种数据类型可能有一个或多个规则
例如:
第一列:日期类型,格式规则
第二列:时间类型,格式规则,舍入规则
第 3 列:货币类型,格式规则,零或空规则,舍入规则
2.想法
/// <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();