Kat*_*ath 2 c# switch-statement
我在C#/ Winforms中有一个应用程序,它允许用户在网格上放置对象以创建游戏关卡.它有几个工具用于放置瓷砖/灯/门/实体等.目前我只使用枚举来存储当前选定的工具,并有一个switch语句来运行每个工具代码.因为我一直在为应用程序添加更多工具,所以它开始像意大利面一样,有很多重复的代码.
这是我的编辑器类中的鼠标按下功能的缩减版本:
public void OnEditorViewMouseDown(Point mousePos)
{
// Check if the click is out of bounds.
if (IsLocationOOB(mousePos)) return;
if (CurrentTool == ToolType.GroundTile)
{
// Allow drags along whole tiles only.
m_DragManager.DragType = DragManager.DragTypeEnum.Tile;
m_DragManager.StartDrag(mousePos);
}
else if (CurrentTool == ToolType.WallTile)
{
// Allow drags along grid edges only.
m_DragManager.DragType = DragManager.DragTypeEnum.Edge;
m_DragManager.StartDrag(mousePos);
}
else if (CurrentTool == ToolType.PostTile)
{
// Allow drags along grid points only.
m_DragManager.DragType = DragManager.DragTypeEnum.Point;
m_DragManager.StartDrag(mousePos);
}
else if (CurrentTool == ToolType.AreaLight)
{
// Allow drags anywhere. ie. not snapped to the grid in some way.
m_DragManager.DragType = DragManager.DragTypeEnum.FreeForm;
m_DragManager.StartDrag(mousePos);
}
else if (CurrentTool == ToolType.PointLight)
{
m_CurrentWorld.AddLight(TranslateToWorldCoords(mousePos));
}
else if (CurrentTool == ToolType.PlaceEntity)
{
m_CurrentWorld.PlaceEntity(TranslateToWorldCoords(mousePos));
}
}
Run Code Online (Sandbox Code Playgroud)
该开关用于其他几个函数(OnMouseMove,OnMouseUp),它看起来像是糟糕的设计(在多个函数中复制了大开关).有什么建议以更清洁,更可扩展的方式重构这样的东西?我目前正在考虑拥有一个基Tool类,并让每个工具都有自己的类来覆盖它使用的函数(OnMouseDown()等).这听起来合情合理吗?
谢谢阅读.
你有很好的直觉.
通常,在OOP中,当你有一行if或者很多的开关时,它就会产生很强的代码味道.使这种气味消失的最好方法是采用多态性.
你应该继续你的想法,有一个基本的抽象类BaseTool,使用不同的OnXXX方法实现为nops(只返回,所以你只需要指定行为,如果你的工具知道如何对方法采取行动),并且每个工具继承自BaseTool并通过覆盖相关方法来实现自己的行为.
所以你的方法最终成为了
public void OnEditorViewMouseDown(Point mousePos)
{
currentTool.OnEditorViewMouseDown(mousePos);
}
Run Code Online (Sandbox Code Playgroud)
根据您的设计,您还应该考虑将DragManager传递给方法,以免与存在的实例变量绑定.一个EditorContext(包含DragManager),无需获取"全局"变量就可以满足方法所需的所有内容,这将使您的方法在重构时更加自包含且不那么脆弱.设计本身将取决于责任:谁负责什么.
| 归档时间: |
|
| 查看次数: |
566 次 |
| 最近记录: |