C# 重构类似的方法
使用这种代码:C# 重构类似的方法,c#,refactoring,C#,Refactoring,使用这种代码: public void UpdateCellFont(int id, string colName, Font font) { CellLocation location = new CellLocation(id, colName); if (CellAppearances.ContainsKey(location)) { CellAppearances[location].Font =
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);
}
}
这些方法都做了几乎相同的事情——每个方法都会更新字体、背景色或前景色(或者如果字典中没有条目,它们会创建一个新条目)
当它们作用于强类型的cell外观时,如何减少重复
谢谢您可能需要使用反射来将代码概括为几个不同类型的字段。不确定这是否值得。那么直接说怎么样
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;
救援代表们!
在这种情况下,He的答案应该符合要求,但通常情况下,您可以通过使用委托作为方法参数(并以稍微不同的方式组织您的主要方法)来解决此类情况:
public void UpdateCellProperty(int-id,string-colName,
动作外观(动作)
{
细胞外观细胞;
CellLocation location=新的CellLocation(id,colName);
if(CellAppearancess.ContainsKey(位置))
{
单元=单元外观[位置];
}
其他的
{
单元格=新的单元格外观(\u DefaultFont,\u DefaultBackColor,
_前景色);
}
外观作用(细胞);
}
public void UpdateCellFont(int-id、字符串colName、字体)
{
UpdateCellProperty(id,colName,c=>c.Font=Font);
}
public void UpdateCellBackColor(int id、字符串colName、颜色backColor)
{
UpdateCellProperty(id,colName,c=>c.BackColor=BackColor);
}
public void UpdateCellForeColor(int-id、字符串colName、颜色foreColor)
{
UpdateCellProperty(id,colName,c=>c.ForeColor=ForeColor);
}
我看到这种模式被称为“中间模式中的空洞”。非常恰当:你定义了一个带有“洞”的方法体。这是与委托一起注入的。正是这些方法的条件性使它们变得复杂和重复。如果外观已经存在,则执行一件事;如果外观不存在,则执行另一件事。因此,请确保外观存在:
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;
}
@你的意思是-1?:)都一样。你是对的,它不像你的解决方案那么简洁,但我想指出一个“重构类似方法”的通用模式。它在很多场合对我都有好处。它将重复部分从可变代码中分离出来。核心方法往往非常稳定,在学员中,您可以在没有仪式代码的情况下专注于任务本身。是的,这是其中的一部分-但请注意,需要更新的是字体、背景色和前景色(实际上还有更多,但为了清晰起见,我将其缩减)。所以我仍然需要三个方法——UpdateCellFont、UpdateForeColor、UpdateBackColor……好的,所以“cell”将使用默认值创建。然后我仍然有三个方法(UpdateFont、UpdateBackColor、UpdateFolector),但它们应该只调用一行GetAppearance(id,“colName”)。Font=Font等?是的。。。正确的。。在您的解决方案中,您甚至可以先创建默认样式,然后更新特定设置。。。我觉得这样简单明了…我不知道如何接受你的改变。。。看起来不错——比我的更正确;)
public void UpdateCellFont(int id, string colName, Font font)
{
CellLocation location = new CellLocation(id, colName);
EnsureCellAppearance(location);
CellAppearances[location].Font = font;
}