对Java与设计模式态度的转变

我一直自诩自己是Java一生黑。也从来不屑于设计模式这种东西,因为我一直认为,设计模式是为了解决Java的一些缺陷才存在的。对于Python来说,设计模式并不重要。不过最近在做一个新功能开发的时候对Java的态度有了一些改变。

事情的起因是在一个大概有十万行代码的框架中重构他的写Log方式。这个框架原来的Log模块是原作者自己写的,通过打开关闭文件来写Log。现在需要更换成Python的logging模块。对于一个设计相当糟糕的系统来说,要重构是很麻烦的事情。

在原来的Log方式中,文件的句柄通过参数的形式到处传,常常十多个文件句柄同时打开,还会互相影响,相当的混乱。最后由于需要一个地方来将所有模块的Log统一起来,还给系统的入口再加了一个入口,新的入口使用subprocess来执行

`python xxxx`

调用原来的系统模块,并将控制台的输出重定向到文件。

重构的过程相当的痛苦,花了我几乎整个Sprint的时间,细节我会在后续的文章中讲到。今天我要讲的是单例模式让我对设计模式看法的一些改变。

对Python来说,是可以将一个类的实例通过参数的形式直接传递的,所以看起来似乎Python并不需要单例模式。对于新写的代码来说,这当然没有什么问题。但是对已有的代码添加新的功能的时候,这个方法就不太适用了。

如果原来一个方法,它的参数已经有七八个了,这个时候你在加一个参数上去,并不确定会产生什么样的影响。

例如:

1
2
3
4
def foo(a, b, c):
do()
some()
thing()

如果想加一个新的参数,但是又不影响其他的已经在调用这个方法的地方,当然可以这样写:

1
2
3
4
 def foo(a, b, c, d=None):
do()
some()
thing()

如果代码量不大,当然没有问题,但是如果代码量大起来了,这样就会出问题。

例如,现在有一个实例instanceA 在module1 中初始化了,而module3如果想使用instanceA,就必须想办法让instanceA 传递到module3去。但是原本module3和module1并没有什么关系,现在因为需要这个instanceA, 怎么办呢?这个时候发现instanceA 被传递到了module2, 然后又从module2传递到了module4, 最后在module4里面终于找到了一个地方,可以强行把instanceA和module3联系在一起。这样一来,这几个module他们被强制耦合在了一起。

对于程序来说,耦合程度应该越低越好,所以这样的做法,非常不妥。

于是,这个时候单例模式就出现了。

对于module3来说,如果他想要instanceA, 他完全可以再重新new一个,由于是单例模式,于是新的instance 和instanceA是完全一样的。这样就并没有增加多余的耦合关系。

另外,在极客学院录课的时候,最近有涉及到程序集之间通信。这个时候偶然发现设计模式里面的观察者模式可以对我的设计起到相当大的帮助。

就像以前某人说的,你要讨厌一个东西,你必须要比喜欢这个东西的人更了解它。而我以前讨厌Java仅仅是因为Java看起来太罗嗦,太多冗余代码。而我不屑于设计模式,更是因为它是从Java来的。

现在看起来,态度真的应该改变一下了。