有没有更好的方法来编写业务逻辑来验证互斥代码?
Is there a better way to write business logic to validate mutually exclusive codes?
我有两个属性。我需要根据显示兼容值的相当大的矩阵来验证这些属性。
示例属性:
public string firstValue { get; set; }
public string lastValue { get; set; }
样本矩阵:
A B C
A X O O
B O X X
C X O X
设x轴代表"firstValue",y轴代表"lastValue"。程序必须验证 "X" 表示的无效组合是否向用户抛出错误。
样本验证:
if (firstValue == "A")
{
if (lastValue == "A" || lastValue =="C)
Console.WriteLine("Invalid Combination");
}
这显然可以使用 if\else 和切换逻辑以多种方式重构,但是当您向矩阵添加数百个值时,它开始变得可怕。我决定创建一个新的 class,矩阵中每行包含一个函数。
public class MutuallyExclusiveValidation
{
public void CheckA(string lastValue)
{
if (lastValue == "A" || lastValue == "C")
{
Console.WriteLine("Invalid Combination");
}
}
public void CheckB(string lastValue)
{
if (lastValue == "B")
{
Console.WriteLine("Invalid Combination");
}
}
public void CheckC(string lastValue)
{
if (lastValue == "B" || lastValue == "C")
{
Console.WriteLine("Invalid Combination");
}
}
}
然后我设计了类似这样的东西来确保我没有使用超出我需要的代码。谓词将 return 一个布尔值选择并调用需要 运行 的验证方法。 (只是示例,不是生产代码)
public static void CheckForMutuallyExclusiveValues(string firstValue, string lastvalue)
{
var allValidators = GetMutuallyExclusiveValidators(firstValue, lastvalue);
var requiredValidators = allValidators.First(x => x.Key(firstValue));
var validationClassInstance = new MutuallyExclusiveValidation();
requiredValidators.Value(validationClassInstance);
}
public static Dictionary<Predicate<string>, Action<MutuallyExclusiveValidation>> GetMutuallyExclusiveValidators(string firstValue, string lastvalue)
{
var returnDictionary = new Dictionary<Predicate<string>, Action<MutuallyExclusiveValidation>>();
Action<MutuallyExclusiveValidation> validation;
Predicate<string> condition;
validation = x => x.CheckA(lastvalue);
condition = x => x == "A";
returnDictionary.Add(condition, validation);
validation = x => x.CheckB(lastvalue);
condition = (x => x == "B");
returnDictionary.Add(condition, validation);
validation = x => x.CheckC(lastvalue);
condition = (x => x == "C");
returnDictionary.Add(condition, validation);
return returnDictionary;
}
这似乎很管用,但我忍不住想还有更好的方法。有什么想法吗?
编辑:Fabjan 的回答是我针对这个特定问题的答案。还要感谢 Tim Schmelter。
创建一个二维数组并使用某种方法验证记录,例如:
class MyClass
{
bool[,] matrix = new bool[,]
{
{false, true, false}, // x1 y123
{true, false, true}, // x2 y123
{true, false, false}, // x3 y123
};
string[] xValues = { "A", "B", "C" };
string[] yValues = { "A", "B", "C" };
public bool IsValid(string value1, string value2)
{
return matrix[Array.IndexOf(xValues, value1), Array.IndexOf(yValues, value2)];
}
}
class Program
{
static void Main()
{
MyClass c = new MyClass();
Console.WriteLine(c.IsValid("A", "A"));
Console.WriteLine(c.IsValid("B", "C"));
Console.WriteLine(c.IsValid("A", "C"));
Console.ReadKey();
}
}
输出:
您可以使用 Dictionary<string, HashSet<string>>
将 X 值存储为键,将所有无效的 Y 值存储为值。
Dictionary<string, HashSet<string>> InvalidValues = new Dictionary<string, HashSet<string>> {
{"A", new HashSet<string>{"A", "C"}},
{"B", new HashSet<string>{"B"}},
{"C", new HashSet<string>{"B", "C"}}
};
现在您可以有效地检查给定的 x 和 y 值是否无效:
var emptySet = new HashSet<string>();
var invalidValues = allValues
.Where(x => InvalidValues.TryGet(x.FirstValue, emptySet).Contains(x.LastValue));
foreach (Value val in invalidValues)
Console.WriteLine("Invalid Combination: {0}|{1}", val.FirstValue, val.LastValue);
使用这个扩展来 linqify Dictionary.TryGetValue
:
public static TValue TryGet<TKey, TValue>(this Dictionary<TKey, TValue> dict, TKey key, TValue defaultValue = default(TValue))
{
TValue value;
bool success = dict.TryGetValue(key, out value);
if (success)
return value;
else
return defaultValue;
}
这个class:
public class Value
{
public string FirstValue { get; set; }
public string LastValue { get; set; }
}
和一些示例值:
var allValues = new List<Value> {
new Value { FirstValue = "A", LastValue = "C" },
new Value { FirstValue = "A", LastValue = "B" },
new Value { FirstValue = "B", LastValue = "C" },
new Value { FirstValue = "A", LastValue = "A" }
};
我有两个属性。我需要根据显示兼容值的相当大的矩阵来验证这些属性。
示例属性:
public string firstValue { get; set; }
public string lastValue { get; set; }
样本矩阵:
A B C
A X O O
B O X X
C X O X
设x轴代表"firstValue",y轴代表"lastValue"。程序必须验证 "X" 表示的无效组合是否向用户抛出错误。
样本验证:
if (firstValue == "A")
{
if (lastValue == "A" || lastValue =="C)
Console.WriteLine("Invalid Combination");
}
这显然可以使用 if\else 和切换逻辑以多种方式重构,但是当您向矩阵添加数百个值时,它开始变得可怕。我决定创建一个新的 class,矩阵中每行包含一个函数。
public class MutuallyExclusiveValidation
{
public void CheckA(string lastValue)
{
if (lastValue == "A" || lastValue == "C")
{
Console.WriteLine("Invalid Combination");
}
}
public void CheckB(string lastValue)
{
if (lastValue == "B")
{
Console.WriteLine("Invalid Combination");
}
}
public void CheckC(string lastValue)
{
if (lastValue == "B" || lastValue == "C")
{
Console.WriteLine("Invalid Combination");
}
}
}
然后我设计了类似这样的东西来确保我没有使用超出我需要的代码。谓词将 return 一个布尔值选择并调用需要 运行 的验证方法。 (只是示例,不是生产代码)
public static void CheckForMutuallyExclusiveValues(string firstValue, string lastvalue)
{
var allValidators = GetMutuallyExclusiveValidators(firstValue, lastvalue);
var requiredValidators = allValidators.First(x => x.Key(firstValue));
var validationClassInstance = new MutuallyExclusiveValidation();
requiredValidators.Value(validationClassInstance);
}
public static Dictionary<Predicate<string>, Action<MutuallyExclusiveValidation>> GetMutuallyExclusiveValidators(string firstValue, string lastvalue)
{
var returnDictionary = new Dictionary<Predicate<string>, Action<MutuallyExclusiveValidation>>();
Action<MutuallyExclusiveValidation> validation;
Predicate<string> condition;
validation = x => x.CheckA(lastvalue);
condition = x => x == "A";
returnDictionary.Add(condition, validation);
validation = x => x.CheckB(lastvalue);
condition = (x => x == "B");
returnDictionary.Add(condition, validation);
validation = x => x.CheckC(lastvalue);
condition = (x => x == "C");
returnDictionary.Add(condition, validation);
return returnDictionary;
}
这似乎很管用,但我忍不住想还有更好的方法。有什么想法吗?
编辑:Fabjan 的回答是我针对这个特定问题的答案。还要感谢 Tim Schmelter。
创建一个二维数组并使用某种方法验证记录,例如:
class MyClass
{
bool[,] matrix = new bool[,]
{
{false, true, false}, // x1 y123
{true, false, true}, // x2 y123
{true, false, false}, // x3 y123
};
string[] xValues = { "A", "B", "C" };
string[] yValues = { "A", "B", "C" };
public bool IsValid(string value1, string value2)
{
return matrix[Array.IndexOf(xValues, value1), Array.IndexOf(yValues, value2)];
}
}
class Program
{
static void Main()
{
MyClass c = new MyClass();
Console.WriteLine(c.IsValid("A", "A"));
Console.WriteLine(c.IsValid("B", "C"));
Console.WriteLine(c.IsValid("A", "C"));
Console.ReadKey();
}
}
输出:
您可以使用 Dictionary<string, HashSet<string>>
将 X 值存储为键,将所有无效的 Y 值存储为值。
Dictionary<string, HashSet<string>> InvalidValues = new Dictionary<string, HashSet<string>> {
{"A", new HashSet<string>{"A", "C"}},
{"B", new HashSet<string>{"B"}},
{"C", new HashSet<string>{"B", "C"}}
};
现在您可以有效地检查给定的 x 和 y 值是否无效:
var emptySet = new HashSet<string>();
var invalidValues = allValues
.Where(x => InvalidValues.TryGet(x.FirstValue, emptySet).Contains(x.LastValue));
foreach (Value val in invalidValues)
Console.WriteLine("Invalid Combination: {0}|{1}", val.FirstValue, val.LastValue);
使用这个扩展来 linqify Dictionary.TryGetValue
:
public static TValue TryGet<TKey, TValue>(this Dictionary<TKey, TValue> dict, TKey key, TValue defaultValue = default(TValue))
{
TValue value;
bool success = dict.TryGetValue(key, out value);
if (success)
return value;
else
return defaultValue;
}
这个class:
public class Value
{
public string FirstValue { get; set; }
public string LastValue { get; set; }
}
和一些示例值:
var allValues = new List<Value> {
new Value { FirstValue = "A", LastValue = "C" },
new Value { FirstValue = "A", LastValue = "B" },
new Value { FirstValue = "B", LastValue = "C" },
new Value { FirstValue = "A", LastValue = "A" }
};