Answers:
注释掉代码。它的块,也许几百行。从理论上讲,嘿,它被注释掉了,它没有任何危害,也许我们将来会需要它。
我将用“ copy-pasta”打另一个明显的例子。复制几乎与您想要的代码相同的代码,然后进行一些更改(而不是提取到方法中)。
这在90年代后期的某些功能和API测试代码中尤其普遍:从字面上看,成百上千个(甚至上千个)几乎完全相同的测试用例,可以分解成几个带有3个或4个参数的功能-甚至更好,由数据驱动。我大学毕业后的第一份工作实际上是8个月的重写和重构使用过时方法的数千行复制粘贴。到我完成时,测试文件还不到其原始大小的十分之一,并且更易于维护(并且可读!)。
我想我可以写很多有关Pattern Mania和解决方案的文章,这些解决方案可以用更少的精力解决,但我想指出的是我最近读过的一篇很棒的文章,上面有一个很好的例子说明了如何简化简单的解决方案。
地区
在C#中,您可以定义可在IDE中折叠的代码区域,从而将其隐藏,除非您要处理该代码。我一直在(目前正在进行)一个项目,该区域跨越数百条线(希望我夸大了),千行功能中有多个区域(再次希望我在开玩笑)。
从好的方面来说,成为该地区的开发商在识别区域内的特定功能方面做得很好。如此之多,以至于我能够对该区域执行提取方法并继续前进。
地区鼓励开发人员“隐藏”他们的废话。
DoNotUseRegions
。
#region SQL Update
使其可折叠,因此需要较少的滚动。
一旦与所有状态都保存在浏览器中的Web应用程序一起使用。(为确保无故障可伸缩性,所有异常均被忽略)。
当前,我正在处理一段旧代码,并且我喜欢以前的编码器获取列表的第一个元素的方式:
String result;
for(int i = 0; i < someList.size(); i++) {
result = someList.get(i);
break;
}
但是我在这段代码中看到的最糟糕的情况是定义内联JSP页面的类,使用scriptlet和out.println编写所有HTML,CSS和Javascript:print(
锁定字符串文字
synchronized("one") { /* block one A*/ }
synchronized("one") { /* block one B*/ }
类名很长。(在JRE中)
com.sun.java.swing.plaf.nimbus.
InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonWindowNotFocusedState
继承结构不良
com.sun.corba.se.internal.Interceptors.PIORB extends
com.sun.corba.se.internal.POA.POAORB extends
com.sun.corba.se.internal.iiop.ORB extends
com.sun.corba.se.impl.orb.ORBImpl extends
com.sun.corba.se.spi.orb.ORB extends
com.sun.corba.se.org.omg.CORBA.ORB extends
org.omg.CORBA_2_3.ORB extends
org.omg.CORBA.ORB
不是的异常。
public interface FlavorException { }
无意义和神秘的错误处理
if (properties.size() > 10000)
System.exit(0);
不必要的对象创建
Class clazz = new Integer(0).getClass();
int num = new Integer(text).intValue();
为其他目的引发异常
try {
Integer i = null;
Integer j = i.intValue();
} catch (NullPointerException e) {
System.out.println("Entering "+e.getStackTrace()[0]);
}
将实例对象用于静态方法。
Thread.currentThread().sleep(100);
在非最终字段上同步
synchronized(list) {
list = new ArrayList();
}
常量字符串的无意义副本
String s = new String("Hello world");
对String.toString()的无意义调用
String s = "Hello";
String t = s.toString() + " World";
调用System.gc()释放一些内存
将局部变量设置为null以释放一些内存
// list is out of scope anyway.
list = null;
}
出于性能原因(或任何其他微优化)使用++ i代替i ++
假人迭代器:
Iterator iCollection = collection.iterator();
for(int i = 0 ; i < collection.size() ; i++ ){
if(collection.get(i) == something){
iCollection.remove();
}
}
Singletono工厂:
public class SomeObject{
private SomeObject() {}
public static SomeObject getInstance(){
return new SomeObject();
}
}
if-else驱动的开发(也称为开放式关闭原则-进行修改时开放,以便于理解):
if (sth1){
...
}else if(sth2){
..
}
...
..
else if(sth1000000000000){
...
}
StringPattern(也称为StringObject):
a) sendercode
if(sth1)
str+="#a";
if(sth2)
str+="#b";
...
if(sth1000)
str+="#n";
b) receiver
regexp testing if str contains #a, #b, ... #n
else if
通常是完成工作的唯一方法。我正在考虑弦乐;不能使用开关。使它有用的条件应相同。
引起我极大痛苦的是“天空中的大地图”模式。扔在地图上而不是使用适当的对象。您不知道未经调试就包含什么“变量”,并且不追溯代码就不知道它可能包含什么。通常,将字符串映射为对象,或将字符串映射为字符串,您可能应该将其解析为基元。
我认为我见过的最糟糕的反模式之一是使用数据库表作为临时存储,而不是使用计算机内存。
问题域是专有的,不允许我对其进行解释,但是不必了解基本问题。这是一个用Java编写的带有后端数据库的GUI应用程序。它是要获取某些输入数据,对其进行处理,然后将处理后的数据提交给数据库。
我们的项目有一个相当复杂的算法,该算法会保存中间值以供以后处理。没有将临时对象封装在...对象中,而是创建了一个数据库表,例如“ t_object”。每次计算值时,都会将其添加到此表中。算法完成工作后,它将选择所有中间值并将它们全部处理在一个大型Map对象中。在完成所有处理之后,标记为要保存的其余值将添加到实际数据库模式中,并且“ t_object”表中的临时条目将被丢弃。
该表也像唯一列表一样使用,数据只能存在一次。如果我们在表上实现了约束,这可能是设计的一个不错的功能,但是最终我们遍历整个表以查看数据是否存在。(不,我们甚至没有使用在CONTAINS中使用where子句的查询)
由于这种设计,我们遇到的一些问题是专门调试的。该应用程序的构建是为了对数据进行管道传输,因此将有多个GUI在数据到达此算法之前对其进行预处理。调试过程是处理一个测试用例,然后在完成上述部分后立即暂停。然后,我们将查询数据库以查看该表中包含哪些数据。
我们发现的另一个问题是,没有从该临时表中正确删除数据,这将在将来干扰运行。我们发现这是由于未正确处理异常,因此应用程序无法正确退出并且没有删除其控制的表中的数据。
如果我们使用了面向对象的基本设计并将所有内容都保留在内存中,那么上述这些问题将永远不会发生。首先,调试会很简单,因为我们可以轻松地在应用程序中设置断点,然后检查堆栈和堆中的内存。其次,从应用程序异常退出后,java内存将自然被清除,而不必担心从数据库中删除它。
注意:我并不是说这种模式本质上是不好的,但是在本示例中,我发现当基本的OO原理就足够时,它是不必要的。
我不确定这个反模式的名字,因为这是我第一次看到这样的东西。你们能想到这种模式的好名字吗?
IMO,我所见过的最糟糕的反模式是“我们不需要任何臭皮的模式”。反模式:设计模式的想法是浪费时间,您可以通过将其倾斜并复制/来更快地编写代码。根据需要粘贴。
值得一提的是,有使用旧的VB6样式从数据库中加载对象的代码:
Foobar oFoo = new Foobar();
oFoo.FooID = 42;
if (oFoo.Load()) {
// do something with oFoo
}
本身并不是真正的反模式,但显示出缺乏利用适当架构和关注点分离的优势。
另外,这样的事情:
// this name is misleading, we may not always want to stand in fire,
// we may want to stand in slime or voidzones or ice patches...
public Foobar StandInFire() { }
// why is this here???
public string BeatWithNerfBat(string whom) { }
// ????
public int GivePony(string to) { }