已然这个决议会致使深化而久远的成果,那么咱们是不是在做这个挑选时应当愈加务实?许多时分,咱们会盲目地偏颇于咱们挑选的言语。而且,有时分咱们之所以不喜爱挑选这种言语的因素或许恰是为啥咱们要挑选那种言语的因素。
假如咱们能够铺开胸襟,坦白地对待自个持有的成见,那么咱们就能够减轻一些相似在装饰时硬要将方钉钉进圆形孔的苦楚。尽管咱们没有啥诀窍来为项目挑选完美言语,但仍是能够遵从一些准则,协助咱们做出一个十分好,更适宜的言语挑选。
没有完美的言语
这一点对任何人,乃至是菜鸟而言,都是在意料之中的,而且咱们许多人都情愿供认,“当然,这种言语并不是完美的言语,”但与此一起,咱们许多人仍是会说,“这言语是最佳的编程言语”。说一种言语是项意图最佳言语的要害是项意图布景,也即是说,最佳的言语只存在于必定的范围内。这即是咱们的第一条准则:
没有完美的言语:每一种言语都有它的长处和缺陷。
例如,许多一般运用运行时言语,如Java或Python的开发人员,宣称C或C ++令人透不过气来,会由于重视例如内存办理这类低层次的细节,或关怀编译时类型查看的严厉粒度,而摧残分置于开发人员的职责。这是现实,只需咱们正在开发的项目不重视看似琐碎的使命,如内存办理或发生在单一循环中的copy-assignment的数量。
相反,假如咱们作业在一个项目,或项意图一部分,那么关于代码应当怎样高效以及程序的要害性安全的成见需求是自然而然的,这些看似繁琐的细节或许恰是咱们正在寻觅的粒度水平。在这种新的布景下,Java或Python的运行时性质好像过于漠不关怀或过于心猿意马。相反,咱们期望当内存分配和开释的时分,能够严厉控制有多少move-assignment和copy-assignment被履行,并在编译时捕捉尽或许多的过错,而不是让过错进入运行时(体现为运行时反常)。
尽管在理论上“没有完美的言语”这一点听起来是清楚明了的,可是咱们作为开发人员的行动一般会违背这个概念:咱们说咱们知道咱们最喜爱的言语是不完美的,但咱们仍是持续对咱们开发的项目运用这种言语,不管它是不是适宜。此外,当别的的开发人员质疑咱们挑选的言语时,咱们会坚决保卫咱们的挑选,而不情愿从他或她的辩驳中看见现实的本相。请记住:每一种言语都有它的长处和缺陷。了解你把握的言语的长处和缺陷,然后依据实际状况做出挑选。
你不喜爱一种言语的因素或许即是你应当运用它的因素
这好像违背直觉,但有的时分,咱们之所以不喜爱一门言语或许恰是运用某种言语的因素。仍是上面的比如,在我作为一个C ++开发人员的经历中,许多时分由于有那么多不一样的概念要盯梢(内存办理和方针寿数时刻,C ++编程三准则等),以致于完结项意图一个简略功用都会变得繁琐不胜。在用C ++开发几周以后,运用Python,Java或另一种“更高档”的言语,几乎就像上天的赏赐:但真的是这么的吗?
有时分,或许咱们不喜爱一门言语的因素恰是咱们要运用该言语的因素。假如我正在开发一个驱动程序或一些要害性安全,实时的体系,上面表述的繁琐不胜的因素或许恰是这个言语的最大优势。例如,C ++供给了一种机制用于表达当方针被仿制时被履行的逻辑,这在功率和谨慎性有条有理的时分是十分名贵的。
这或许看上去都极好都很棒,因而咱们很难切当指出在某个布景下,某种你看不顺眼的言语或许反而更有协助。那么,咱们该怎样知道哪些你不喜爱的言语是有协助的呢?这就引出了咱们的第二条准则:
对自个要诚笃:知道自个为啥不喜爱一门言语,不要教条化自个的憎恨。
例如,在上面那个C ++的比如中,我之所以不喜爱长时刻地用C ++编程,是由于这言语请求思维谨慎,不然很简单犯错,就像是被困于丛林中(过多地重视树木,而不是树林这个全体)。这种谨慎会阻碍开发人员去质疑,如,“我要在仓库上或堆上创立方针吗,或许部分在仓库上,另一部分在堆上?”或“要让这个类可拓展,应当经过模板参数仍是经过承继?”等决议。在别的言语中,开发人员只需别离创立一个方针以及运用面向方针的承继就能够完结这些使命,然后进入到下一个功用,由于言语(或许,更精确地说,编译器或解说器)重视这些细节。
可是,假如我对自个诚笃的话,我会供认,我之所以不喜爱C ++的这些功用,是由于它将表达这些细节的职责归咎于我。在别的言语中,我不只不需求担任这些细节,而且我也没有职责表达这些细节:它们被笼统远离开发人员。在一个这些细节是必不可少的上下文中,我不喜爱C ++的因素恰是我应当运用这种言语的因素。
这是不是意味着,咱们应当愁眉苦脸地运用这些会让咱们对这言语恼怒的功用?也没有必要。或许你能够换个视点:不要将这些功用当作缺陷,或许咱们应当拥抱它们,将它们当作完结使命的必需品。咱们不该当说“这真是一个悲惨剧,”而应当说,“谢天谢地,我竟然能用这种言语做到这一点。”请记住:在某些布景下,这些功用将是上天的赏赐,而在别的状况下,它们 才是负担。至于为啥不喜爱某一门言语的功用,请诚笃地通知自个。
越了解别的言语,越好
关于这一点,即是咱们要说的第三个准则:
假如你具有的仅有东西是一个锤子,那么你看每一个疑问都像是钉子。
这条规矩并不适用于软件工程,但它尖利地体现了许多软件开发的状况。许多时分,咱们挑选一种言语,或一种言语支撑的东西(如Java的JMS,Python的ASYNCIO,Rails的Ruby等),是由于咱们知道它们存在。假如咱们仅有了解的言语是Java,那么咱们会将咱们碰到的一切疑问都适应到Java的上下文中。例如,“我需求为一个通讯运用创立一个路由构造。在Java中我该怎样做呢?”这就约束了可供咱们运用的东西,并人为地约束咱们为完结作业挑选适宜东西的地步。
处理这个疑问的办法是扩展你的视界,了解别的言语的的功用和扑朔迷离的当地。正如Andrew Hunt和David Thomas在《The Pragmatic Programmer》中给出的主张,一个好的做法即是,每年学习一门新的言语。这可不没有听上去那么简单,学习一门言语对不一样的人将意味着不一样的工作。还有一个衍生疑问是,咱们对正在进行中的项目通常只会运用这一种言语,然后使得学习的另一种言语显得毫无用处。例如,假定我是一个Android开发人员,基本上天天只用Java,那么学习C#或许就会显得不达时宜地浪费时刻。
不要被假象所遮盖。学习别的言语的优势体现在咱们能从不一样的视点去看疑问,而且运用最适宜该疑问的东西。为了做到这一点,咱们有必要学习别的言语的有关正告,以及开发人员运用这些言语处理疑问的办法。例如,假如一个开发人员想用C ++履行元编程,那么他或她能够运用C ++中的Template Metaprogrammming(TMP),但他或她也能够运用Java中的反射。了解别的言语是怎样处理相似疑问的,能够削减咱们以为它毫无用处的危险。
再说一个比如,假如咱们需求能够改动一个类的运行时特征,那么一个深化了解C ++扑朔迷离性的C ++开发人员,或许会企图假造一个延伸这个编译时言语的边界的处理方案。而另一个C ++开发人员,由于对Java也有必定的了解,就能够说,“我喜爱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 ++写,然后运用Python C API接口此组件。请注意,要拟定这么的处理方案,咱们需求知道Python有一个C API;因而,了解最盛行言语的这些功用是很有协助的。
中间件能够答应运用多种言语。例如,假如有两个有必要进行通讯的运用程序,如移动设备和一个服务器运用程序,但这并不意味着它们有必要运用一样的言语(当然也能够一样,假如你判别以为这是最佳决议的话)。假如这个移动设备是一款Android手机,而服务器运用程序十分适宜作为一个Python运用程序的话,那么运用一个音讯署理,如RabbitMQ,能够让你在通讯的一起运用这两种言语:Android运用程序能够运用Java RabbitMQ API,而服务器运用程序能够运用Python RabbitMQ API。
拥抱别的言语的乖僻的当地。假如你是一个Java开发人员,那么你会运用包来分隔源代码的逻辑单元;假如你是一个Python开发人员,那么你会运用Python的包构造做一样的工作;假如你是一个C ++开发人员,那么你会运用命名空间或前缀的类名(即“DZone_MyClassName”)。了解你正在运用的言语的特别的当地,并拥抱它们:在罗马,就入乡随俗。不然的话就像是由于你更喜爱单词用意大利语发音,而用意大利口音说德语,这么就显得不三不四了。当然也有或许一种言语的一个功用长期存在,可是这么的话,其间必有其因素:保证自个理解其间的道理。