重构类似的方法

时间:2012-08-26 07:50:28

标签: c# refactoring

使用这种代码:

    public void UpdateCellFont(int id, string colName, Font font)
    {
        CellLocation location = new CellLocation(id, colName);

        if (CellAppearances.ContainsKey(location))
        {
            CellAppearances[location].Font = font;
        }
        else
        {
            CellAppearance cell = new CellAppearance(font, _DefaultBackColor, _DefaultForeColor);
            CellAppearances.Add(location, cell);
        }
    }

    public void UpdateCellBackColor(int id, string colName, Color backColor)
    {
        CellLocation location = new CellLocation(id, colName);

        if (CellAppearances.ContainsKey(location))
        {
            CellAppearances[location].BackColor = backColor;
        }
        else
        {
            CellAppearance cell = new CellAppearance(_DefaultFont, backColor, _DefaultForeColor);
            CellAppearances.Add(location, cell);
        }
    }

    public void UpdateCellForeColor(int id, string colName, Color foreColor)
    {
        CellLocation location = new CellLocation(id, colName);

        if (CellAppearances.ContainsKey(location))
        {
            CellAppearances[location].ForeColor = foreColor;
        }
        else
        {
            CellAppearance cell = new CellAppearance(_DefaultFont, _DefaultBackColor, foreColor);
            CellAppearances.Add(location, cell);
        }
    }

这些方法几乎都做同样的事情 - 每一个都更新Font,BackColor或ForeColor(或者如果字典中没有条目,他们会创建一个新条目。

当他们在强类型的CellAppearance上行动时,如何减少重复?

由于

4 个答案:

答案 0 :(得分:4)

直截了当怎么样?

public CellAppearance GetAppearance(int id, string colName){
    var location = new CellLocation(id, colName);
    if(!CellAppearances.ContainsKey(location))
       CellAppearances.Add(location, cell);
    return CellAppearances[location];
}

// usage:
GetAppearance(1,"hello").Font = myFont;
GetAppearance(2,"blubb").BackColor = myColor;

答案 1 :(得分:2)

代表救援!

在这种情况下,TheHe的答案应符合要求,但一般情况下,您可以通过使用委托作为方法参数来解决此类情况(并以稍微不同的方式组织您的main方法):

public void UpdateCellProperty (int id, string colName,
                                Action<CellAppearance> appearanceAction)
{
    CellAppearance cell;

    CellLocation location = new CellLocation(id, colName);
    if (CellAppearances.ContainsKey(location))
    {
        cell = CellAppearances[location];
    }
    else
    {
        cell = new CellAppearance(_DefaultFont, _DefaultBackColor,
                                  _DefaultForeColor);
    }
    appearanceAction(cell);
}

public void UpdateCellFont(int id, string colName, Font font)
{
    UpdateCellProperty(id, colName, c => c.Font = font);
}

public void UpdateCellBackColor(int id, string colName, Color backColor)
{
    UpdateCellProperty(id, colName, c => c.BackColor = backColor);
}

public void UpdateCellForeColor(int id, string colName, Color foreColor)
{
    UpdateCellProperty(id, colName, c => c.ForeColor = foreColor);
}

我看到这种模式被称为“中间模式的洞”。非常合适:您定义了一个带有代理注入的“洞”的方法体。

答案 2 :(得分:1)

这些方法的条件性使它们变得复杂和重复。如果外观已经存在,你做一件事;如果没有,你会做别的事情。因此,请确保外观存在:

public void EnsureCellAppearance(CellLocation location)
{
    if (CellAppearances.ContainsKey(location))
        return;
    CellAppearances.Add(location, new CellAppearance(_DefaultFont, _DefaultBackColor, _DefaultForeColor));
}

现在你的方法更简单了:

public void UpdateCellFont(int id, string colName, Font font)
{
    CellLocation location = new CellLocation(id, colName);
    EnsureCellAppearance(location);
    CellAppearances[location].Font = font;
}

答案 3 :(得分:0)

您可能必须使用反射将代码概括为不同类型的多个字段。不确定是否值得。