我有一个像素/位置,我们在图表上称它为4,4。 我试图重构一个函数来检查它周围的像素是否符合某个标准,在所有8个方向(对角线,水平和垂直方向),如果符合该标准,采取一个共同的行动,有一个返回值。
例如:
int weight=0;
if (CheckWeight(new Point(4,4)) == true)
weight +=100;
if (CheckWeight(new Point(4,5)) == true)
weight +=10;
if (CheckWeight(new Point(4,3)) == true)
weight +=10;
if (CheckWeight(new Point(5,5)) == true)
weight +=10;
if (CheckWeight(new Point(3,3)) == true)
weight +=10;
if (CheckWeight(new Point(3,4)) == true)
weight +=10;
if (CheckWeight(new Point(5,4)) == true)
weight +=10;
if (CheckWeight(new Point(5,3)) == true)
weight +=10;
if (CheckWeight(new Point(3,5)) == true)
weight +=10;
有没有一种很好的方法来重构这些,所以如果我必须在这里改变某些东西,比如功能我打电话来检查重量,或者我要检查的条件,或者体重增加,我是没有重复我的努力8次?
我有其他程序员,我知道已经建议在一张支票下合并,我显然不能这样做,因为它可能会满足其中3项检查,并给我一个分量这次是30分,其中5分,下次给我50分的重量。
编辑:此例程将在1920x1080像素地图上运行,因此数百万次;性能可能是重构中涉及的一个真正问题。
答案 0 :(得分:3)
int weight = 0;
for (int dx = -1 ; dx <= 1 ; dx++) {
for (int dy = -1 ; dy <= 1 ; dy++) {
if (CheckWeight(new Point(4+dx, 4+dy))) {
weight += (dx==0 && dy == 0) ? 100 : 10;
}
}
}
为了加快速度,您可以使用一个可爱的小技巧展开一个循环:
// Declare this in your class
static readonly int[] dd = new int{1,-1,-1,0,-1,1,0,1,1};
// Use this code to calculate the weight
int weight = CheckWeight(new Point(4, 4)) ? 100 : 0;
for (int i = 0 ; i != 8 ; i++) {
if (CheckWeight(new Point(4+dd[i], 4+dd[i+1]))) {
weight += 10;
}
}
答案 1 :(得分:2)
for-loops怎么样?
int x = 4;
int y = 4;
int weight = 0;
for (int dx = -1; dx <= +1; dx++) {
for (int dy = -1; dy <= +1; dy++) {
if (CheckWeight(new Point(x+dx, y+dy)))
weight += 10;
}
}
答案 2 :(得分:2)
一种可能的方法是将公共代码重构为for循环,迭代遍历目标附近的所有点。示例代码如下:
var target = new Point(4, 4);
int weight = 0;
if (CheckWeight(target) == true)
weight += 100;
var points = GetNearestPointsFrom(target);
foreach (var p in points)
{
if (CheckWeight(p) == true)
weight += 10;
}
您需要实现GetNearestPointsFrom
方法才能返回正确的点数。通过这种方式,您还可以封装逻辑,以便在单独的方法中断言最近的点,我发现它更易于维护。
更新:
考虑到您受到性能限制的限制,并且您提到可能需要通过另一个函数更改CheckWeight
,我将验证是否将if
检查包含在接受{{Predicate<Point>
的方法中1}}和权重增量值不会对性能产生太大影响。这样改变CheckWeight
方法或增量只执行一次。示例代码:
private static void GetWeight(Predicate<Point> predicate, int weightIncrement)
{
int weight = 0;
if (predicate(new Point(4, 4)) == true)
weight += 100;
if (predicate(new Point(4, 5)) == true)
weight += weightIncrement;
// ... Remaining checks ...
}