软件设计之道:平衡之术
.NET程序员是幸福的,基本上是被MS给宠坏了,老板们是乐坏了,可是身为程序员却高兴不起来(个中原因自己体会吧)。借着MS的开源春风,让我们看看MS到底是怎么宠坏我们这些可爱的.NET程序员的。在MS设计产品时遵循哪些规则,又是怎么解决一些棘手的问题的。让我们看看微软的完全开源的IronPython,看看MS是怎么耍宝的。
微软现在已经是Python Software Foundation (PSF)的成员(跟当初微软加入Java队伍好相似呵),那理所当然IronPython得和CPython兼容以照顾原有的Pythoner们,但IronPython又是建立在.NET FrameWork上的,同样得很好的照顾到大量.NET程序员。这两者之间肯定会有冲突,微软是如何在这两大群体间保持平衡的呢?让我们看几个简单的例子来体会IronPyhon的设计之美。
一个看起来很简单的字符串处理问题:
>>> s.upper()
Python中使用upper函数去得到大写的字符串,但是.NET中我们使用String.ToUpper()方法。如果是你,这时你会怎么做,也许你会想到.NET扩展方法从而这样处理:
>>> s.upper()
'PYTHON AND .NET WORKING TOGETHER'
>>> s.ToUpper()
'PYTHON AND .NET WORKING TOGETHER'
可是这样的话原来的那些Pythoner就会吼了,他们要求兼容性,CPython可不支持ToUpper()方法。那再想想,有什么方法能解决这个问题呢,真是众口难调啊。刚才想到扩展方法,恩,我们可以这样处理:
>>> s.upper()
'PYTHON AND .NETWORKING TOGETHER'
>>> s.ToUpper()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'ToUpper'
>>> import clr
>>> s.ToUpper()
'PYTHON AND .NETWORKING TOGETHER'
>>>
怎么样,现在大家都满意了吧。类似的我们可以解决IronRuby中的to_upper;VB中的toupper,ToUpper,TOUPPER。
>>> System.Math.DivRem(5,2)
(2, 1)
>>> System.Math.DivRem(5,0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: 试图除以零。
System.Math.DivRem(5,0)
except ZeroDivisionError,e:
print e,type(e)
试图除以零。 <type 'exceptions.ZeroDivisionError'>
System.Math.DivRem(5,0)
except System.DivideByZeroException,e:
print e,type(e)
System.DivideByZeroException: 试图除以零。
在 _stub_$17##16(Closure , CallSite , CodeContext , Object , Int32 , Int32 )
在 _stub_MatchCaller(Object , CallSite , Object[] )
在 Microsoft.Scripting.Actions.CallSite`1.UpdateAndExecute(Object[] args)
在 Microsoft.Scripting.Actions.UpdateDelegates.Update4[T,T0,T1,T2,T3,TRet](Ca
llSite site, T0 arg0, T1 arg1, T2 arg2, T3 arg3)
在 Initialize$27##26(Closure , CodeContext ) <type 'DivideByZeroException'>
>>> try:
System.Math.DivRem(5,0)
except System.Exception, e:
print type(e)
<type 'DivideByZeroException'>
>>>