`
RednaxelaFX
  • 浏览: 3047506 次
  • 性别: Icon_minigender_1
  • 来自: 海外
社区版块
存档分类
最新评论

向后兼容性与老化

    博客分类:
  • rant
阅读更多
只想记个链接而已,标题党了(苦笑

Bruce Eckel发了篇帖子,Will Open-Sourcing Java Remove Competetive Corporate-Think?。其中的观点并不新了,他自己最近的几篇帖子里其实都有类似的内容。不过今天读到的这篇让我想随便记几句。

跟Bruce一样,Sun让我感到很困惑的一点就是"no one has been able to figure out Sun's business plan"。技术层面上Sun一直不缺人才,但在奇怪的商业策略的引领下这些技术总让人觉得没能发挥出它们最大的潜力。有一个挺有趣的观点(也不新了):Sun是想学习Microsoft的商业策略,并标榜自己为anti-Microsoft。某种程度上来说这有点道理。至少Bruce提到的这点我觉得很符合我接触到的状况:"Rather than fixing the problem, respond with rhetoric (another lesson learned from Microsoft)"。

Enough rants on Sun. I don't really care about what happens to Sun anyway. 我是联想到最近关注的C# 4.0的一些设计,也是严重受限于向后兼容性。

假如把一门语言或者一个库的API比做一件衣服,把这个语言或者库所要解决的问题领域比做一个人,那么一开始这个人还是个小婴孩,总不能把衣服做得太大。慢慢的这个小孩长大了,在一定范围内衣服可以修补、扩张来满足新的需要,但这样的修补会让衣服变得越来越重。超出这个范围后,如果不把衣服拆解回到零件的状态再重新组装的话,衣服就很难再继续改进来满足需要了。
一个问题领域也总是有从简单到复杂的发展过程的。一开始如果把语言或者API设计得太复杂,那会:1、提高学习曲线,使它难以学习;2、难以适应后续的变更。那么假如一开始设计得很简单,后面要继续满足新需求多半需要添加新的元素;对语言来说这意味着新的语法结构,对API来说这意味着新的类、新的方法或函数。为了保持向后兼容性,添加新元素的同时就无法去掉旧的过时的元素,使语言或API变得越来越重,甚至影响到新设计的可能性——也就是所谓的老化。持续下去的话,最终人们将不得不使用新的语言或者库来解决新出现的问题,让原来的语言处理它老化之前就能处理的问题(注意:这并不是说原来的语言就“死”了。只是在它的问题领域已经“成熟”了而已)。

程序员真的需要向后兼容性么?当然,如果能保持向后兼容性同时又能提供新的服务,如果这两者不矛盾的话,自然是好的。没人会心甘情愿的只为了升级运行时环境而修改一大堆代码。但程序员本来就应该习惯“为了解决问题”而写程序。如果因为向后兼容性绑住了手脚而无法解决问题,那这个向后兼容性的代价也太大了。很多时候,真正的进化都意味着要放弃绝对的向后兼容性,像是Python和Ruby的发展过程中许多东西都为了适应新的需要而在改变着。

C# 4.0里有可选参数(optional parameter)的语法结构。这种语法结构在C++里已经存在多年,即便在.NET平台上也有VB.NET一直支持,看似微不足道的。但就是因为保持向后兼容性,它不得不做了个尴尬的设计:如果将虚方法与可选参数一起使用,会带来十分不直观的行为。例子的话请参考这里:Optional parameters - Conclusion: Treat like "unsafe"。下面把例子的代码引用过来:
public class Derived : Base {
    public override string Test(int test = 2) {
        return "Derived " + test.ToString();
    }
}
 
public class Base : IBase {
    public virtual string Test(int test = 1) {
        return "Base " + test.ToString();
    }
}
 
interface IBase {
    string Test(int test = 3);
}
 
sealed class Program {
    static void Main(string[] args) {
        Base b = new Base();
        Console.WriteLine(b.Test());

        IBase bi = b;
        Console.WriteLine(bi.Test());

        Derived d = new Derived();
        Console.WriteLine(d.Test());

        Base d2 = d;
        Console.WriteLine(d2.Test());

        IBase d2i = d2;
        Console.WriteLine(d2i.Test());
    }
}

而输出是:
引用
Base 1
Base 3
Derived 2
Derived 1
Derived 3

也就是说同一个虚方法从不同的基类调用时很可能会出现行为的差异。这与一般对虚方法的认识有相当的出入,很不直观。虽说C++也是这样,但C#也没必要全盘照搬C++的行为嘛。
VB.NET在这方面的处理就不一样——它将可选参数的默认值考虑为signature的一部分,如果派生类在覆盖基类的虚方法时对同一个可选参数提供了不同的默认值,编译器会报错。这样就阻止了发生上述问题的可能性。
那为什么C# 4.0不学VB.NET呢?C# 4.0小组的成员告诉我是因为向后兼容性。因为当前在C#里用户可以使用OptionalAttribute和DefaultParameterValueAttribute来修饰方法的参数,而C# 4.0也是使用这两个属性来修饰可选参数的。如果在C# 4.0里用户写出这样的方法:
void Foo([DefaultParameterValue(10), Optional]int x, int y = 10)

则x的默认值不会被编译器检查(因为老的C#编译器是不检查的),而y的默认值会被编译器检查。既然无法保证C# 4.0里所有的可选参数都能够被检查,那就只好整体都不检查,从而带来上述的问题了。
据说开发小组内部为这个问题争论过很多次,但最终还是决定采用这样的设计;全是让向后兼容性害的……

诶。C#和.NET Framework显然都在老化。Anders也说每次给C#添加新特性都意味着带来了老化,所以要非常小心。即便他和他的设计组很小心也还是带来了不可忽视的老化。而Microsoft一直有过不久就发布新平台来代替旧平台的传统,不知道.NET Framework能撑多久呢?

也有明明老化得很严重却还一直撑着的例子。例如说Win32 API。那里面许多设计都带着早期Windows的影子,有些API早该去掉了,却还一直存在。
又例如x86指令集。这算不上API,应该算是ABI(Application Binary Interface)的一部分吧。为了保持向后兼容性,新的x86兼容芯片还是得支持8086的一些过时依旧的运行模式。但也正是因为一直向后兼容,x86平台一直保持着强大的生命力。这个例子又说明了什么呢?

======================================================================

另外也想记点关于编程语言与API的关系。许多人认为核心语言应该非常小,非常简洁但足够强大,保持设计的稳定,让上面的库去承担语言发展的变化部分。对研究编程语言的人来说这自然是最好不过的,像LISP那样以不变应万变就是最好的例证。(不是说LISP的语言没变化,只是最核心的部分一直都没怎么变)。
对应用程序员来说,这种思路其实没多少意义。当你需要解决问题的时候,你会发现手边的工具都有所谓的“表面区域”;编程语言和上面的API都是表面区域的一部分。从某种意义上说,所有的库都可以看成是以某种编程语言为元语言的DSL(特定领域语言)。无论是编程语言发生了变化还是库发生了变化,对应用程序员而言都意味着表面区域变了,意味着自己写的程序可能需要修改。
十年前如果有人问是学习Java语言难还是学习它上面的库难,答案或许是两者都差不多;但到现在各种框架层出不穷,学习Java语言本身显然比不上学习框架的难度。而那些框架的API发生的变化都直接牵动着程序员的筋。不是框架不好,而是问题领域本身变复杂了。
语言和库都会遇到向后兼容性和老化。即便把许多常用的语法结构用库来实现,也改变不了它们的变化会影响到表面区域的问题。
4
0
分享到:
评论
4 楼 KKFC 2009-01-07  
更新的时候给一部分人相当的机会,市场就是这样造就而成的。
3 楼 CloudiDust 2008-12-14  
说到这个,还是蛮佩服ruby和python的勇气的说~

不过版本间的不兼容性多少都是个问题~

其实……最悲惨的一个例子是C99啊,只要一考虑到跨平台的问题,那就基本只能C89了……可怜的标准……

.Net Framework么……话说在WPF还没有替代WinForms,全面托管的Windows系统层还没有出现的时候(我觉得这几乎不可能),微软应该不敢大动干戈才对。

想想到现在因为WinXP的意外长寿,我们都不能假定每个用户都安装了足够新的.Net呢,所以基于.Net写(给一般用户使用的)桌面小应用的不多啊,虽然我觉得这个东西比用C++合适。(用SliverLight来缓解这种状况么? =口=)
2 楼 RednaxelaFX 2008-12-13  
yywill 写道

老化是一件大好事,代表了成熟。C和C++不是很老很老的语言么?而现在开发工资 C > C++ > JAVA > C#

你如果想提高自己的工资要么就去学一门老化的语言,要么就去等待自己学的语言老化吧。

这话是不错。就像古董会因为年代久远,数量稀少而升值一般。
最后这句话我很喜欢 ^_^

最近业界对“成熟”的看法也有不少讨论就是了。有人说成熟意味着难以接受新的发展,Bruce Eckel显然是这一派的;有人说成熟是好事,意味着稳定,并以C/C++为证,yywill兄的观点似乎是这一系的。

这两种观点并没有本质上的矛盾。Bruce也一直强调说他并不反对使用Java来解决它原本就擅长的东西。例如说这段:
Bruce Eckel 写道
Java itself will continue to be a core workhorse, just as C++ has been. But like C++, I think people will reduce the use of the more difficult and newer features and keep their code simple, mostly because they will only be doing small portions of applications using those languages and will do whatever they can in the more powerful enabling languages.


这两种观点会影响到的主要还是设计“表面区域”的人而已。对应用程序员来说没啥,反正问题领域本身的变化就足够驱动写新代码的需要了,无论表面区域变不变。
1 楼 yywill 2008-12-13  
老化是一件大好事,代表了成熟。
C和C++不是很老很老的语言么?
而现在开发工资 C > C++ > JAVA >C#

你如果想提高自己的工资要么就去学一门老化的语言,要么就去等待自己学的语言老化吧。

相关推荐

    老化APK和资源.zip

    这涉及到硬件兼容性、系统稳定性、用户体验等多个方面。 3. **系统集成测试**:将`agtest`放入`/system`目录,表明测试可能涉及系统级别的集成,确保测试组件与机顶盒的其他系统组件协同工作。 4. **应用启动与...

    存储设备老化工具

    6. **兼容性广泛**:存储设备老化工具应支持多种类型的存储设备,如HDD硬盘、SSD固态硬盘、NAS网络存储、SAN存储区域网络等,以及各种文件系统,如FAT、NTFS、EXT系列、XFS等。 在使用存储设备老化工具时,需注意...

    自动切换相机前后摄的老化测试专项

    6. **兼容性测试**:检查不同应用软件和系统版本下相机切换功能的稳定性。 三、测试方法 1. **自动化脚本**:编写自动化测试脚本,确保测试的可重复性和准确性,减少人为误差。 2. **压力测试**:设计高负载场景...

    老化报告老化报告老化报告

    3. **系统稳定性**:随着系统运行时间的增加,可能积累的错误和不兼容性会逐渐暴露,影响系统的稳定性和可用性。报告会评估系统稳定性,并提出改善系统健壮性的策略。 4. **安全性问题**:老化的系统和软件可能无法...

    专题资料(2021-2022年)F1980无菌医疗器械包装的加速老化试验标准指南.doc

    它不涵盖包装与产品间交互作用或兼容性的评估,这些应在产品设计初期进行考虑。此外,标准还强调了加速老化试验与实际时间老化研究的差异,以及包装过程确认、运输、储存等因素不在本指南范围内。 本指南引用了多个...

    单片机的电池兼容性设计说明.doc

    本文档主要讨论了单片机(Microcontroller Unit, MCU)的电池兼容性设计,但实际上更深入地探讨了单片机的电磁兼容性(Electromagnetic Compatibility, EMC)问题,这是电子设备设计中的一个重要方面。随着单片机在...

    适老化无障碍测评评分标准文件

    8. **性能与兼容性**:考虑到部分老年人可能使用较旧的设备或网络环境,网站加载速度和兼容性也是重要的评估指标。 9. **隐私与安全**:适老化设计还需注重用户隐私保护,避免复杂的安全设置对老年人造成困扰。 ...

    通用微处理器等效老化试验方法.pdf

    老化试验的目的是确保产品的使用可靠性,并评估不同产品的质量与可靠性水平。通过提高温度,可以加速故障的出现,从而在早期阶段发现并剔除有问题的集成电路。 综上所述,通用微处理器等效老化试验方法是一项重要的...

    适老化改造中物联网智能家居的探索与应用.pdf

    其次,智能家居系统在设计时要考虑到与旧家电的兼容性,因为很多老年人仍然使用传统的家电产品,这些产品在接口和制作工艺上可能比较落后,无法与新兴的智能家居系统直接对接。因此,需要通过额外的接口和中枢平台与...

    老化

    标题中的“老化”一词可能是指计算机系统的老化过程,尤其是软件和硬件随着时间推移而出现的性能下降或兼容性问题。在IT行业中,老化通常与系统维护、升级和替换策略有关。描述中同样只提到“老化”,这可能暗示我们...

    电子政务-开关电源全自动老化和测试传动机构.zip

    此外,电子政务在引入开关电源自动化老化和测试传动机构时,还需关注系统的可扩展性、兼容性和智能化程度。随着技术的发展,未来可能需要集成更多先进的测试功能,如故障模拟、智能诊断等。同时,系统应具备良好的...

    电子政务-插入式混合集成电路老化试验插座.zip

    1. **兼容性**:老化试验插座必须与各种尺寸和类型的HIC相匹配,以适应不同种类的集成电路测试。 2. **接触质量**:插座的触点应具有良好的导电性,确保与HIC的连接稳定,减少接触电阻,防止热量积累和信号损失。 ...

    行业分类-电子-关于光伏并网微逆变器和LED驱动电源老化测试系统的说明分析.rar

    LED驱动电源的设计需考虑到效率、功率因素校正、电磁兼容性(EMC)以及热管理等问题。老化测试对于LED驱动电源至关重要,因为它需要在各种实际工作条件下验证其性能,如高温环境、连续开关操作、负载变化等,以确保...

    电子政务-同轴电缆抗氧耐老化粘接料及其生产方法.zip

    原料选择要考虑粘接料的化学性质,确保其与同轴电缆材料的兼容性;混合过程是为了将各种成分均匀融合,形成稳定的复合材料;固化则是通过加热或化学反应等方式,使粘接料形成坚固的连接状态。这些步骤都需要精确控制...

    SAK-136老化测试运转箱操作标准.doc

    《SAK-136老化测试运转箱操作标准》文档主要涵盖了AC产品老化测试的整个流程,包括操作前准备、操作程序、注意事项以及保养维护等关键环节,旨在确保测试的安全性和准确性。 一、适用范围 该操作标准适用于上海正峰...

    如何解决拼接屏老化与花屏现象

    液晶拼接屏的像素点由液晶体组成,长时间高负荷运行会使某些像素点过热,一旦温度超过其承受极限,就会导致像素点永久性损坏,形成常说的“坏点”。这种老化过程会加速,尤其是在连续工作96小时以上的情况下,严重时...

    行业文档-设计装置-一种节能型大功率开关电源老化台.zip

    设计大功率开关电源时,需要考虑热管理、电磁兼容性(EMC)、动态响应以及安全标准等多个方面。在老化台上进行测试,可以验证这些关键性能指标是否达到设计预期。 此外,文件中的"一种节能型大功率开关电源老化台.pdf...

    行业资料-交通装置-POE供电电源产品的老化车.zip

    2. **安全性**:POE系统设计有安全措施,如电压和电流限制,以确保只向兼容的设备供电,避免对非POE设备造成损害。 3. **节省成本与安装便利**:使用POE,可以减少电源插座和独立电源适配器的需求,降低布线成本,...

    WTS-LH2205新能源汽车充电模拟老化柜

    【新能源汽车充电模拟老化柜】是一种专用于测试和老化新能源汽车交流充电桩的设备,支持国标、美标和欧标接口。该设备具备多种功能,适用于不同标准的充电桩测试,确保其性能稳定和安全。 技术参数如下: 1. 输入...

Global site tag (gtag.js) - Google Analytics