我刚刚在C#/ Silverlight中创建了我的第一个主要应用程序。最后,总行数超过12,000行代码。考虑到这是一个php / javascript应用程序的重写,我创建了2年,超过28,000行,我实际上为我的成就感到自豪。
在stackoverflow和其他在线网站上阅读了很多问题和答案后,我遵循了许多海报的建议:我创建了一些课程,程序,以及我一年前复制和粘贴的东西;我创建了逻辑图表以找出复杂的功能;确保没有疯狂的隐藏字符(使用标签代替空格);和其他一些事情;必要时发表评论(我有很多评论)。
我的应用程序包含4个水平布局的图块,用户控件加载到每个图块中。您可以随时加载一到四个切片。如果你有一次切片加载,切片会占用整个画板...如果你有2个加载,每个占用一半,3个三分之一,四分之一。
这些切片中的每一个都代表(为了这个例子)一个光控制。每个切片中都有3个滑块控件。现在,当我编写滑块的功能时,我在公共函数内部使用了一个switch / case语句,该语句将在指定的切片/滑块上运行命令。这使得一些重复的代码,但我看不到它,因为每个切片的命名不同。所以我会做slice1.my.commands(); slice2.my.commands();等。
我的问题是如何进一步清理我的代码? (可悲的是我无法发布任何代码)。有没有办法从我的代码中删除这个重复?
答案 0 :(得分:11)
您需要的是与您的朋友进行战略模式的界面。例如:
public interface ISlice
{
public Slider Slide {get;set;}
}
public class Slice1 : ISlice
{
public Slider Slide { get; set; }
}
public static class SliceSlider
{
public static void DoSomethingCoolWithTheSliceSlide(ISlice slice)
{
slice.Slide.LookitMeIAmLearningDesignPatterns();
}
}
答案 1 :(得分:7)
编写更少的代码不应该是您的目标。最后,所有这些都与TCO(总体拥有成本)有关。
虽然拥有更少的代码可以提高TCO,但有一个因素会对TCO产生更大的影响:可维护性。您应该编写最易维护的代码。首先阅读Robert Martin's Clean Code。
更新
你也说“我有很多评论”。这是您可以改进代码的一个方面。正如您将从Martin的书中学到的那样,好的代码几乎不需要任何评论。 Martin说“评论是谎言”和“应保留用于有关代码和设计的技术说明。”。
更新2:
当我添加它时,这是罗伯特·马丁的书中我最喜欢的引用:
答案 2 :(得分:2)
我倾向于同意史蒂文。编写更少的代码或更少的行并不总是目标。回想一下史蒂夫·沃兹尼亚克的一些故事,他曾经制作过非常紧凑的硬件,将大量的逻辑放入一个非常小的包装中,但是很少有人能够遵循他的所作所为,维护或制造它。
话虽这么说,我建议你对设计模式非常熟悉。它们可能不会减少您的代码行,但它们可能使您更容易编写,维护和理解代码。很多时候,它们确实减少了你拥有的行数。以下是一些资源:
答案 3 :(得分:2)
接口和抽象类是.net平台中非常强大的一部分。
接口只不过是对类的合同要求。即:接口是实现该接口的类必须具有的一组定义的方法和/或属性。界面只是合同声明。
抽象类非常强大,因为您可以将逻辑“转换为”实现该抽象类的类。但那是另一场球赛。
考虑:
public interface ISlice
{
bool DoStuff(string someParameter);
}
public class MySpecificSliceOfType : ISlice
{
// this must have a method implementation for the [bool DoStuff(string)] method
public bool DoStuff(string mySpecificParameter)
{
// LOGIC in the Specific class
return(true);
}
}
public class MyOtherSliceOfType : ISlice
{
// this must have a method implementation for the [bool DoStuff(string)] method
public bool DoStuff(string myOtherParameter)
{
// LOGIC in the Other class
return(true);
}
}
虽然这是一个非常简单的示例,但在类MySpecificSliceOfType'和'MyOtherSliceOfType'上声明ISlice接口的接口实现意味着必需的DoStuff()方法不管你有哪一个,因为你可以做的事情像:
bool sliceReturn = ((ISlice)currentSlice).DoStuff(currentStringParameterValue);
这可以帮助您解决以下问题:
bool sliceReturn = false;
switch(typeofSlice)
{
case "other" :
sliceReturn = MyOtherSliceOfType.DoStuff(currentStrignParamterValue);
break;
case "specific" :
sliceReturn = MySpecificSliceOfType.DoStuff(currentStrignParamterValue);
break;
}
如果你有>这里说明的点更强大。 2种不同的类型。
接口和抽象类也很好地与C#类型检查相结合。
接口是反射中的一个基础...一些非常谨慎使用的东西,但是因为它可以在特定的情况下节省很多......而且在序列化(也就是序列化)中可以真正帮助你飞了。
答案 4 :(得分:0)
由于你无法真正发布任何代码,我不妨随意抛出。你能把这些切片放到一个数组中吗?如果是这样,您可以通过让每个控件设置一个变量(我称之为whichSlice
)来摆脱一些冗余代码。所以控件都将whichSlice
设置为正确的数字1-4,然后运行正常的开关并调用slices[whichSlice].my.commands();