图灵云教育吧 关注:6贴子:447
  • 4回复贴,共1

别和一种语言厮守终生:为工作正确选择编程语言

取消只看楼主收藏回复

在为您的下一个APP选择编程语言时可以参考下面一些思路。
开发人员在项目上需要作的关键选择之一,就是语言或者语言组的选择,以执行系统。这个选择不仅关系到系统的执行,也关系到设计。例如,是该选择面向对象语言还是面向过程语言?这个选择会对整个项目产生深远影响,亦或是影响项目中的一部分程序的寿命。我们常常不多加考虑就轻易作出选择:我总是用这种语言来执行这种系统;我最了解这个语言;我最喜欢这个语言;我享受用这个语言来编程的过程等等。
既然编程语言影响深远,在选择上就该契合实际。我们常常意识不到自己在选择上的偏见;更何况,有时候我们不喜欢选用一种语言的原因却正是我们必须选择这种语言的原因所在。
如果能打开心胸,坦诚面对自己的偏见,或许就能减少比如硬要往圆孔钉方钉的痛苦。在选择一个比较好或者比较合适的语言时,我们可以考虑以下几个原则。


IP属地:黑龙江1楼2017-03-08 14:39回复
    没有完美的编程语言
    开发人员包括新手都会承认“这个语言当然不是个完美的语言”,但同时也会说“但这是最好的编程语言”,对此我们并不会感到惊讶。说一个语言是一个项目的最好语言关键点在于项目环境,只在某种特定环境中是最佳语言。因此我们的第一个选择原则是:
    没有完美的语言,每个语言都有优劣。
    举例说,许多常用运行时语言如Java或Python的开发人员声称C语言或C++让人不胜其烦,总让他们关注低级细节如内存管理或编译时类型检查的严格粒度。这点无可否认,只要我们所开发的项目并非真正的关注貌似琐碎的任务如内存管理或单一循环内的copy-assignments操作量。
    相反,如果我们所做的项目或项目的一部分对我们的编码效率或安全关键有极端偏见,而这种偏见又是自然而然的事,那么这种看似繁琐的细节可能就是我们所要找的粒度水平。在这种环境下,Jave或Python的运行时性质似乎显得无动于衷或者事不关己的模样。相反,我们会希望最大程度地严格控制在分配或解除分配内存时,执行了多少move-assignments 或copy-assignments,在编译时上捕捉到尽可能多的错误而不是让错误渗透到运行时(或在运行时异常时显现)
    虽然这一个原则在理论上显而易见,但实际上开发者又经常偏离这一原则:我们说我们知道我们最喜欢的语言不是完美语言,但是我们仍旧在开发的每一个项目上使用这个语言,不管是否真正适合。而且,当其他开发者质疑我们的语言选择时,我们又很教条式的捍卫自己的选择,而看不到对方的论点中的优点。所以记住:每一种语言都有优点和缺点。理解你所知道的(和你所不知道的)语言的优缺点并依此作出选择。
    你不喜欢一个编程语言的原因或许正是你需要使用这种语言的原因所在
    可能看似有反直觉,但有时,你不喜欢一个编程语言的原因或许正是你需要使用这种语言的原因所在。继续刚才的例子,我做C++开发人员的时候,经常有很多不同概念要跟踪(内存管理和对象寿命,执行编程三原则Rule of Three等等),所以完成一个项目的一个简单功能也变得很冗长繁琐。这种类型的开发跟踪数周之后,你会发现用Python,Java或其他“更高级别”的语言会感觉像是受了恩惠;但是事实真是如此么?
    有时,我们不喜欢一个编程语言原因或许正是我们需要使用这种语言的原因。如果我在开发一个驱动或者安全关键、实时系统,我上面所表达的繁琐的理由正是这个语言最大的优点。比如,C++提供了一种机制用来表达该对象被复制时所执行的逻辑,当效率或者精确度井然有序的时候,C++在这点上的作用无可估量。
    这点看似很好,但有时又没办法理解为啥我们的憎恶在某种环境下会变成一种优点。所以,这种时候我们该如何抉择?这就引出了第二个原则:
    坦诚面对自己:了解你不喜欢一种语言的原因,别对自己的憎恶教条化处理。
    仍旧是上面C++的例子,我不喜欢长时间用C++编程,因为这个语言要求很高的精准度,很容易导致错误或,就像困于丛林中(只见树木不见森林)。这种精准度会阻碍开发人员去质疑一些决定,“这个对象要建立在堆栈上还是堆上?还是创建在堆栈的某一部分或是另外一个堆?”。在其他语言上,开发人员只要简单的创建一个对象,或用面向对象继承来各自完成任务,并直接转移到下一个功能,因为这些语言(或者更准确的说,编译器或注释器)能负责这些底层实现。
    但是,如果诚实一点,我会承认我不习惯C++这些特性的原因是它让我来承担实现这些细节的责任。在其他语言上,我并不需要负责这些细节,也不懂得如何实现:这些细节已经从开发者身上抽离出来。在一些这种细节必不可缺的环境中,我不喜欢C++的原因正是我们需要用这个语言的原因。
    所以用这种让我们恼怒的语言会让我们苦不堪言么?未必。或许可以换个角度:不是将这些功能视为缺点,或许可以拥抱他们,将他们视为完成任务的一种必须。不说“苦不堪言”,而说“谢天谢地我可以用这个语言来完成任务”。只需记住:在一些环境中,这些功能会是恩赐;而在其他环境中,又会很繁琐。坦诚面对你不喜欢一种语言特征的原因。


    IP属地:黑龙江2楼2017-03-08 14:39
    回复
      越熟悉其他语言,对你越有帮助
      如果你所拥有的唯一工具是锤子,那么每个问题看起来都像是钉子。
      这个原则并不特定适用于软件工程,但也深刻地体现在许多软件开发情况中。很多时候,我们选择一门语言,或一门语言所支持的工具(如Java的JMS,Python的asyncio,Ruby的Rails等),因为我们知道它们的存在。如果我们所熟知的语言只有Java,我们就会用它来解决在Java环境中所遇上的任何问题。比如,“我需要为通信软件创建一个路由框架,可以怎么通过Java来实现?”这便会限制我们能使用的手段并人为地限制我们为工作选择正确语言的能力。
      解决这个问题是为了拓宽你的眼界,学习其他语言的功能与复杂性。正如Andrew Hunt和DavidThomas在《程序员修炼之道》(《The PragmaticProgrammer》)中所建议的那样,重要的原则就是每年学习一种新语言。这并不像听起来的那么简单,因为学习一种语言对不同的人来说意味不同。还有个事实问题是,我们经常用一种单一的语言来实现一个项目,这就使学习的其他语言显得毫无用处。比如如果我在开发Android应用时每天都是用Java,那么学习C#对我来说就显得浪费时间。
      但正如第三个原则所揭示的,这只是假象。 学习其他语言的好处会在我们从不同的角度看待问题,以及选择应对问题工具的能力时凸显出来。为了凸显这种能力,我们必须学习多种语言带给我们的警示,学习开发人员用它们解决问题的方式。比如,如果一个开发人员要用C++执行元编程,TA可能会使用C++的模板元编程TMP(TemplateMetaprogrammming),但也可能会用Java的反射(reflection)。知道了用其他语言解决类似问题的方法就会减少把自己局限在特定思维的风险。
      再举个例子,如果我们需要能够改变一个类的运行时特征,那么一个熟知C++的复杂程度的C++开发人员,可能创造出能够拓展编译时语言边界的解决方案。而另一个稍微熟悉Java的开发人员就能说,“我喜欢C++,但Java的运行时反射更适合解决这个问题”
      一个好的做法是不仅学习语言的语法,也学习语言的特质。在Stackoverflow上查阅那个语言的最普遍问题,加入该语言最流行的社区板块或论坛。


      IP属地:黑龙江3楼2017-03-08 14:40
      回复
        编程语言只是方法,不是目的
        第四个也是最后一个原则似乎最充满哲理,也最重要:
        编程语言是一种方法,不是目的。
        除非你是个语言标准作者或编译器作者,否则编程语言是只是一种通往目标的方法,这个目标便是完成项目:就是完成项目,而不是使用一种特定语言。这并不意味着每个开发人员都无权选择喜欢或不喜欢的语言(实际上,如果够诚实,这些好恶可以成为我们的优点,参考上面第二个原则),但我们不应该自欺欺人地做出这样的决定比如“这是我们用那种语言功能的好机会”,除非这个语言功能确实适用于这个项目。
        将这一点铭记于心很重要:语言只是一种对手头的问题表达解决方案的一种手段。确保你选择了最能实现解决问题域的一种语言。


        IP属地:黑龙江4楼2017-03-08 14:40
        回复
          其他需要考虑的原则:
          这里有一些补充原则供你选择语言时作考虑:
          1、考虑某些语言是如何与其他语言相互作用的。比如,如果你觉得Python是你完成大部分项目的最好语言,但项目中又存在极端要求粒度水平或效率水平的定义良好的部分(通常适用C或者C++),这并不意味着你不能在该项目使用Python。相反,应该使用Python,用C或C++做这些特定部分的编写,并和以Pyhton C API做接口。注意,为了实现这个方案,我们必须知道Python有CAPI;因此知道最流行语言的一些功能对我们很有好处。
          2、中间件可能允许使用多种语言。举例说,如果有两个应用程序需要通信,比如移动设备和服务器应用程序,这并不意味着需要二者必须用同一种语言(虽然可以,如果你判断说,这是最好的选择)如果移动设备是一个安卓手机,服务器应用程序也适合于Python应用程序,那就是用消息代理中间件,比如RabbitMQ,可以让你在通信时使用两种语言:安卓应用程序可以使用Java Rabbit MQ API,服务器应用程序可以使用Python Rabbit MQ API。
          3、拥抱其他语言的怪异。如果你是个Java开发人员,你会使用包来分割源代码的逻辑单位;如果是个Python开发人员,会用Python包架构来做同样的事;如果是C++开发人员,就会使用命名空间或前缀类名(如"DZone_MyClassName").了解你所使用的语言的特别之处,拥抱它们:入乡随俗。否则就像是用意大利口音说德语,因为你更喜欢用意音发音。当然如果一种语言的某个特性长盛不衰,这必有其因,那么你得确保你知道个中原因。


          IP属地:黑龙江5楼2017-03-08 14:40
          回复