我们程序员在着手一个项目时需要做出的一个关键决定是选择一种语言或一组语言来实现系统。这个决定不仅会影响系统的实施,还会影响设计。例如,我们应该使用面向对象语言还是过程语言?选择什么语言对项目的生命周期和作为项目一部分的程序有深远的影响,很多时候我们去选择语言:这是我用来实现这些类型系统的语言;这是我最熟悉的语言;这是我最喜欢的语言,我喜欢用它编程;etc.既然这个决定会带来深远而长远的后果,我们在做这个选择的时候是不是应该更加务实一些呢?很多时候,我们会盲目偏爱自己选择的语言。此外,有时我们不喜欢选择一种语言的原因可能正是我们选择该语言的原因。如果我们能够坦诚面对自己的偏见,就可以减轻装修时试图将方钉装入圆孔的痛苦。虽然我们没有什么秘诀可以为项目选择最好的语言,但是还是有一些原则可以帮助我们做出更好更合适的语言选择。没有完美的语言这一事实??对任何人来说都不足为奇,即使是新手,我们中的许多人都愿意承认,“当然,这种语言不是完美的语言,”但与此同时,许多我们仍然会说,“这种语言是最好的编程语言”。说一种语言是项目的首选语言,关键在于项目的上下文,即首选语言只存在于一定范围内。这是我们的第一个原则:没有完美的语言:每种语言都有其优点和缺点。例如,许多通常使用Java或Python等运行时语言的开发人员声称C或C++令人窒息,因为他们担心内存管理等底层细节,或者担心编译时类型检查。严格的粒度,而阻塞点则由开发人员负责。只要我们正在开发的项目不关注看似微不足道的任务,如内存管理或单个循环中发生的复制分配的数量,这就是事实。反之,如果我们在做一个项目,或者项目的一部分,那么对于代码的效率和程序的安全性,自然会有偏差的需求,而这些看似繁琐的细节可能只是粒度级别我们正在寻找。在这种新的背景下,Java或Python的运行时性质似乎太冷漠或太心不在焉。相反,我们希望在分配和释放内存时,能够严格控制执行了多少move-assignment和copy-assignment,尽可能多地在编译时捕获错误,而不是让错误渗透到runtime(表示为runtime)异常的)。虽然“没有最好的语言”这一点在理论上听起来很明显,但我们作为开发人员的行为常常背离这个概念:我们说我们知道我们最喜欢的语言不是最好的,但我们仍然继续在我们开发的项目中使用这种语言,是否合适。此外,当另一个开发人员质疑我们选择的语言时,我们将强烈捍卫我们的选择,而不是在他或她的反驳中看到真相。请记住:每种语言都有其优点和缺点。了解自己掌握的语言的优缺点,然后根据情况做出选择。您不喜欢一种语言的原因就是您应该使用它的原因,这似乎违反直觉,但有时,我们不喜欢一种语言的原因可能正是我们使用它的原因。还是上面的例子,以我作为C++开发者的经验,很多时候因为有太多不同的概念要跟进(内存管理和对象生命周期,C++编程的三原则等等),以至于完成project一个简单的功能可以变得繁琐。在用C++开发几周之后,使用Python、Java或其他“高级”语言几乎就像是天赐之物:但事实真的如此吗?有时候,也许我们不喜欢一种语言的原因正是我们想要使用这种语言的原因。如果我正在开发驱动程序或一些安全关键的实时系统,上述繁琐的原因可能是这种语言的最大优势。例如,C++提供了一种机制来表达复制对象时要执行的逻辑,这在需要效率和严谨性的情况下是非常宝贵的。这可能看起来都很棒,所以很难准确地指出你不喜欢的语言在什么情况下可能更有帮助。那么我们怎么知道哪些你不喜欢的语言是有帮助的呢?这引出了我们的第二个原则:对自己诚实:知道为什么你不喜欢一种语言,而不是教条地讨厌它。比如上面的C++例子,我之所以长期不喜欢用C++编程,是因为这门语言需要认真思考,否则很容易出错,就像被困在丛林中(过于专注于树木而不是整个森林)。这种严格性可防止开发人员提出诸如“我是要在堆栈上还是在堆上创建对象,还是部分在堆栈上部分在堆上创建对象?”这样的问题。或“要使此类可扩展,它应该使用参数还是通过继承?”等等。在其他语言中,开发人员可以通过简单地单独创建一个对象并使用面向对象的继承来完成这些任务,然后继续进行下一个功能,因为语言(或者更准确地说,编译器或解释器)会处理这些细节.然而,如果我对自己诚实,我会承认我不喜欢C++的这些特性的原因是它让我有责任表达这些细节。在其他语言中,我不仅不对这些细节负责,而且也不对表达它们负责:它们是从开发人员那里抽象出来的。在这些细节必不可少的上下文中,我不喜欢C++的原因正是我应该使用该语言的原因。这是否意味着我们应该对那些让我们对语言感到厌烦的功能做鬼脸?不必要。或许你可以换个角度:不要把这些功能当作缺点,或许我们应该拥抱它们,把它们当作完成任务的必需品。与其说,“这真是一场悲剧”,不如说,“谢天谢地,我可以用这种语言做到这一点。”请记住:在某些情况下,这些功能是上帝的礼物,而在其他情况下,它们很麻烦。对自己不喜欢某项语言功能的原因诚实。对其他语言越熟悉越好。为此,我们将讨论第三个原则:如果您拥有的唯一工具是锤子,那么每个问题对您来说都像钉子。这条规则不适用于软件工程,但它尖锐地刻画了许多软件开发情况。很多时候,我们选择一种语言,或者一种语言支持的工具(比如Java的JMS,Python的ASYNCIO,Rails的Ruby等),因为我们知道它们的存在。如果我们唯一熟悉的语言是Java,那么我们将把遇到的所有问题都适应Java上下文。例如,“我需要为通信应用程序创建路由框架。我如何在Java中执行此操作?”这限制了我们可用的工具,并人为地限制了我们为工作选择正确工具的能力。解决这个问题的方法是拓宽你的视野,了解其他语言的特性和复杂性。正如AndrewHunt和DavidThomas在《The Pragmatic Programmer》中建议的那样,一个好的做法是每年学习一门新语言。这并不像听起来那么容易,学习一门语言对不同的人来说意味着不同的事情。还有一个衍生问题,我们倾向于只在正在进行的项目中使用这一种语言,这使得学习另一种语言变得毫无用处。例如,假设我是一名基本上每天只使用Java的Android开发人员,那么学习C#似乎是一种不恰当的时间浪费。不要被幻想所迷惑。学习其他语言的好处是我们可以从不同的角度看问题,使用最适合问题的工具。为了做到这一点,我们必须了解与其他语言相关的注意事项,以及开发人员使用这些语言解决问题的方式。例如,如果开发人员想要在C++中执行元编程,他或她可以在C++中使用模板元编程(TMP),但他或她也可以在Java中使用反射。了解其他语言是如何解决类似问题的,可以降低我们认为它没用的风险。再举一个例子,如果我们需要能够改变一个类的运行时特征,一个非常熟悉C++错综复杂的C++开发人员可能会尝试制定一个解决方案来扩展这种编译时语言的边界。而另一个对Java也有一些了解的C++开发人员可以说,“我喜欢C++,但Java的运行时反射更适合这个问题。”因为任何开发者选择的编程语言太多了,所以优先学习哪些语言很重要。不妨从当今最流行的语言开始(参考《most popular languages on Github》、《Language Trends on Github》、《The 9 most popular computer languages》、《according to the Facebook for programmers》等)。语言是手段,而不是目的这是第四条也是最后一条原则,听起来可能最哲学,但也可以说是最重要的:编程语言是手段,而不是目的。除非您是语言标准或编译器的作者,否则您应该将编程语言视为一种手段而不是目的。语言。这并不意味着每个开发人员都没有权利询问他或她喜欢或不喜欢什么语言(事实上,如果我们对自己诚实,那些喜欢和不喜欢的东西实际上可以使我们受益;参见第二个原则上面),但我们不应该自欺欺人地做出这样的决定,“这对我来说是一个使用该语言特性的好机会”,除非该语言的特性确实符合项目的需要。重要的是要记住,语言只是表达如何解决手头问题的一种方式:确保选择最能表达您如何解决问题领域的语言。其他注意事项以下是选择语言时的一些额外注意事项:考虑该语言如何与其他语言交互。例如,如果您认为Python是大多数项目的最佳语言,但您的项目中有一个定义明确的组件需要极高的粒度或效率(C或C++更适合),这意味着您不能在这个项目上使用Python。相反,请考虑使用Python,用C或C++编写特定组件,然后使用PythonCAPI与该组件进行交互。请注意,要制定这样的解决方案,我们需要知道Python有一个CAPI;因此,了解最新语言的这些特性是有帮助的。中间件可以允许多种语言。例如,如果有两个应用程序必须通信,例如移动设备和服务器应用程序,并不意味着它们必须使用相同的语言(当然可以,如果你判断这是最好的决定)如果).如果移动设备是Android手机,并且服务器应用程序非常适合作为Python应用程序,那么使用RabbitMQ等消息代理可以让您同时使用两种语言进行通信:Android应用程序可以使用JavaRabbitMQAPI,而服务器应用程序可以使用PythonRabbitMQAPI。拥抱其他语言的怪癖。如果您是Java开发人员,那么您将使用包来分隔源代码的逻辑单元;如果您是Python开发人员,那么您将使用Python的包结构来做同样的事情;如果您是C++开发人员,那么您将使用命名空间或在类名前添加前缀(即“DZone_MyClassName”)。了解您所讲语言的特点,并接受它们:在罗马,入乡随俗。否则就像说带有意大利口音的德语,因为你更喜欢用意大利语发音这个词,让它变得不伦不类。当然,一种语言的某个特性也有可能长期存在,但在这种情况下,一定是有原因的:一定要理解原因。
