对网络应用程序的担心不是“面向未来”


106

我是本地小型SaaS Web应用程序的Web开发人员。目前,它有大约六个客户。

随着我继续设计应用程序,要说服自己投入到项目的任何时间对我来说变得越来越困难,这在开始阶段就已经发生了。随着对项目和我已经编写的代码的重视,我担心我提交的所有其他工作将在不久的将来被推翻,因为随着业务的增长,该应用程序的扩展性将不佳。

作为一名申请实习的大学生,我曾让雇主质疑我的选择,即在面试过程中不使用任何网络框架,这只会使我进一步怀疑我以前的工作。我只是不知道任何Web框架,也不知道要开始使用哪个框架。

我在一月份以全职开发人员的身份进入了实习岗位,在那里我将开始学习前端框架,但是完成应用程序的压力越来越大,我正在考虑完全废弃该应用程序并重新开始,这是我以前做过的 该应用程序当前以PHP和jQuery(用于AJAX调用)构建,并使用MySQL作为其数据库。关于如何克服这种思维障碍并确保我的应用程序可扩展的任何想法?提前致谢。


93
使用框架意味着更便宜,而不是客观上更好。企业总是会问“为什么不便宜”,因为那是他们的工作。回答“为什么这个框架不是一个框架或自定义框架”需要多年的经验。作为学生/实习生,您可能无法给出任何有意义的答案,仅仅是因为您没有参与足够的项目来见证给定框架如何解决给定问题。没有这样的经验,您唯一能做的就是沦为给定框架营销的猎物。
Agent_L

24
您对未来的唯一了解是,您对未来一无所知。所以就继续活在当下。未来,您会发现各种方法可以使您陷入困境,但是您却浪费了很多时间来避免这种情况!
alephzero

20
“对我已经编写的……代码越来越重视”附着于我们的工作并抵制更改是我们的天性。但是,即使您这样做了,它也仍然存在于版本控制中。就像现实世界一样,软件也必须进行更改。在构建代码时,不要害怕删除代码或对其进行实质性更改。
bitoflogic

8
至于取消该项目,我建议不要这样做。从头开始通常感觉很不错,因为面对许多已经解决的问题,您会获得很大的动力。最终,您又回到了一个不适合模型的新问题,而花了很多时间在改写新问题上。一旦知道瓶颈所在,您就可以随时解决它们。
bitoflogic

6
@james_pic您是否在没有基本框架的情况下进行Web项目(例如.NET中的asp.net核心,等等)?那么,您是否在简单的http库之上重新实现了路由逻辑和所有其他内容?这似乎太过分了,我看不出应该给您带来什么好处。
Voo

Answers:


201

完美是善的敌人。

或换一种说法,今天不用担心。如果您的应用程序执行了所需的操作,那就很好。进一步重写软件的一部分并不是一件坏事。到那时,您1)更清楚地知道您要构建的内容,以及2)知道哪些位实际上是瓶颈。您可能会花费大量时间来编写可扩展到一百万用户的应用程序,但是对于您当前的六个客户而言这并没有比您今天拥有的更好


23
好点子。如果您花了2个月的时间才能使它避免将来进行1周的重写,那么您已经损失了7周的时间。接受将会发生的变化,并且只有在几乎确定需要进行更改时,才进行未来的证明。
尼尔

83
雅尼(YAGNI),婴儿,雅尼
凯文(Kevin)

32
另一种情况是“ 过早的优化是万恶之源 ”。也许值得一提的是,您的用户数不会从6个跃升至100万。如果6个客户足以支付一位开发人员的费用,那么即使您达到100个客户时,代码也可能需要一个不同的结构,以允许多个开发人员同时进行开发。这与优化性能大不相同,而且发生的时间比必须处理100万用户要早得多。
R. Schmitz

22
@ R.Schmitz如今,这种引用在与Knuth在《计算机编程》中的使用方式完全不同的上下文中使用。Knuth坚决反对整个“刚开始编程,而后担心优化”。他的意思是,人们在错误的时间优化了代码的错误部分。这绝不意味着您不应该在开始编写代码之前就花一些时间来思考体系结构以确保其效率。您可能更喜欢其他观点,但您不应该在此引用Knuth作为捍卫者。
Voo

20
@ R.Schmitz回到Hoare / Knuth所说的“优化”意味着循环计数和我们今天不再要做的其他事情,而不是“在开始编码之前先考虑好的架构”。用报价作为借口根本不考虑好的系统设计,根本不是他们的初衷。
Voo

110

关于如何克服这种思维障碍并确保我的应用程序可扩展的任何想法?

问题的症结不是可扩展性。问题的症结在于认为您会在第一次就解决问题

您应该专注于编写干净的代码。因为当您将来(不可避免)要更改某些内容时,简洁的代码可最大程度地提高便利性。那是您应该拥有的真正目标。

您现在想要做的就是尝试考虑编写完美的代码。但是,即使您设法做到这一点,谁会说要求不会改变,或者您可能是基于错误的信息或错误的沟通来做出决定的?

即使不是你的错,也无法避免犯错误。专注于编写易于在以后进行更改的代码,而不是希望编写将来不需要更改的代码。

对项目和我已经编写的代码越来越重视,

我对此表示同情。但是,附加到您编写的代码是一个问题。

唯一应该恒定的是您希望解决特定问题。解决该问题的方式只是次要问题。

如果明天发布的新工具会将您的代码库减少80%,您是否会因为不再使用代码而感到沮丧?还是对代码库变得更小,更干净/更易于管理感到高兴?

如果是前者,则有一个问题:您没有看到代码的解决方案。换句话说,您只专注于代码,而没有看到更大的图景(它旨在提供的解决方案)。

我担心我所做的所有其他工作都将在不久的将来被推翻,因为随着业务的增长,该应用程序的扩展性将不佳。

对于不同的日子,这是一个不同的问题。

首先,您要构建可行的东西。其次,您可以改进代码以修复可能仍然显示的任何缺陷。您当前正在做的事情是推迟执行第一项任务,因为您担心随后必须执行第二项任务。

但是还有其他选择吗?你不能告诉未来。如果您花时间思考未来的可能性,无论如何您最终都会猜测。猜测总是容易犯错。

而是构建应用程序,并证明确实存在问题。问题解决后,便可以开始解决。

换句话说:亨利·福特从未制造过符合2018年标准/期望的汽车。但是如果他没有按现代标准制造出有缺陷的T型车,就没有人会开始使用汽车,就没有汽车工业,也没有人会尝试改进汽车。

我曾经让雇主质疑我的选择,即在面试时不使用任何网络框架,这只会使我进一步怀疑我以前的工作。

这里的重要部分不是您使用的是哪个框架(任何以此为依据对您进行评估的雇主都无法正常工作)。这里的重要部分是知道您在做什么以及为什么这么做

例如,您可能会特别避免使用现有框架,因为您想通过首先采用困难的方式来了解为什么框架有用。或者,您可能正在尝试制作自己的框架。

唯一的错误答案是“我不知道”,因为这表明缺乏做出明智决定的能力。对雇主而言,这一个危险信号。

我只是不知道任何Web框架,也不知道要开始使用哪个框架。

同样的问题在这里出现。解决方案不是思考更多,而是采取行动:

  • 停止思考完美的答案
  • 选择一个框架。除非您有偏好,否则请随机选择一个。使用飞镖,掷骰子,掷硬币,挑卡片。
  • 用它。
  • 您喜欢使用它吗?有什么令人讨厌的东西吗?
  • 查找如何防止这些不良因素。您是否滥用了框架,或者这仅仅是框架应该如何工作的?
  • 一旦您对框架有所了解(不管您是否喜欢),就选择一个新框架并重复该过程。

要了解更多信息,请阅读《做事的心态》>《思考的心态》。作者尽我所能解释。

但是完成应用程序的压力越来越大,我正在考虑完全废弃该应用程序并重新开始

除非当前的代码库是绝对无法维持的混乱;您正在做出相反的决定。
开发人员通常认为扔东西是更好的选择。这是非常普遍的感觉。但这很少是正确的选择。

丢掉代码并从头开始,就像在上班途中卡在交通中,担心自己上班迟到(错过最后期限),而是开车回家尝试再次沿着同一条路行驶。这没有道理。您可能会遇到交通拥堵的情况,但与在家时相比,您离工作更近了。



10
@MartinBonner虽然在Joel所说的文章中确实是这样,但是如果这实际上是您从事的第一个项目,并且您是唯一从事过该项目的人,那么很有可能您将成为能够写出更好的东西。我记得我重写了我从事的第一个大型个人项目,这在当时可能是正确的决定-原始原型已经损坏,无法修复,因为编写该原型时我不知道自己在做什么。
James_pic

4
@Flater我同意这里编写的大部分内容,除了一件事:如果您要选择一个框架,而您对框架一无所知,则至少可以检查该框架的采用程度。例如,它在github上有几颗星星?有多少个问题?有多少贡献者?上次更新时间是什么时候?回答这些问题至少可以帮助您选择一个可以获取帮助的框架,雇用更了解该框架的人,等等
。– Jalayn

@Jalayn One会假设没有先知的初学者很可能会偶然发现众所周知的框架。
扁平的

3
这是一个很好的答案,因为它鼓励采取纪律严明的方法。我花了好几年的时间才能完全理解这样的建议!
kashiraja

18

尽管Facebook和Google投入了大量资金来说服您,否则前端框架的存在主要有两个原因:

  • 首先,通过在客户端中放置状态和逻辑,将硬件/网络需求转移到客户端操作
  • 其次,与支持第一点所必需的其他客户端逻辑有关,它们提供了隔离的执行上下文,因此您可以将其他人的代码填充到页面中而不会破坏任何内容。

如果您的应用程序本质上是有状态的,要保存客户端的应用程序状态的数量非常复杂,并且如果您期望许多客户端的网络延迟很长(移动,或远离服务器),或者是否有很强的业务需求来支持特别高级的CSS或动态元素创建。

框架营销希望您相信他们的特殊架构方法可以提高开发速度并简化维护。对于从事简单项目的小型团队来说,这显然是不正确的。隔离代码和组织导入可能有助于大型团队更快地将产品推向市场。它为单人开发团队提供的功能已经很少了。

与实际实现功能相比,您将花费更多的时间来学习如何将现有的功能代码放入框架中,并且很有可能某人会更新某些东西,并且用该框架编写的代码将在18个月内停止运行,除非有人在那里不断维护它。

Vanilla JS,以及程度较小但仍相当重要的JQuery,都不会遭受这些问题的困扰。除了一些值得注意的例外,JQuery + AJAX应用程序不依赖于浏览器特定的行为,并且在合理的情况下放弃了外部依赖关系,它们在最初编写时经过很小的改动就可以继续工作10-15年。

框架非常适合典型的初创公司,它们支持正在进行的,复杂的,面向公众的Web应用程序。他们使大型团队可以很好地协调,与供应商添加框架很好地集成,并支持新的小部件和设计范例,以帮助您保持竞争力。

对于您将要放弃的,拥有固定受众的小型软件工具,这都不重要。采用框架既会减缓您适应新范式的开发速度,又会带来不必要的兼容性风险。保持客户端代码简单(理想情况下是自托管)意味着兼容性风险的表面积显着下降。浏览器将发生变化,CDN URL将停止工作,依赖项将过时-但没有人触摸该服务器,它将保持正常运行。

除非采用框架可以解决您当前遇到的特定架构问题或可以很快预见的框架,否则不要采用框架,并且强烈考虑采用其他方法来解决该问题(如果这完全成立)。


2
当我想到“框架”时,我会想到诸如jQuery或Angular或React之类的东西,它为实现自己的烦人(通常很难正确实现并且与跨浏览器兼容)提供了很多构建块。
蓬松的

@fluffy具体来说,您认为Angular或React为您做的事情比在非移动浏览器中在2018年在普通JS或JQuery中做同样的事情要容易得多吗?如今,FF / Chrome / Edge具有足够的通用表面积,可以在不使用垫片的情况下构建功能齐全的小型应用程序。
Iron Gremlin

3
@IronGremlin你在开玩笑吗?您是否曾经使用过双向数据绑定或Angular / Vue /任何模板?对于这些功能有用的应用程序,它们是一个极大的简化,并且让您摆脱了基于事件的易碎代码。接下来,CPU。当然,使用JS框架通常会减轻服务器的负担,但这纯粹是副产品,您说这是造成它们的主要原因。接下来,“简单体系结构(...)似乎更适合此项目”。好吧,鉴于我们对该项目知之甚少,这是一个牵强的陈述。
Frax

2
我的意思是,您说的重点是“并非所有事物都必须是或应该是'丰富的js应用程序'”。我同意这一点。但是,我认为您的答案无法正确传达-如果您对其进行编辑,效果会更好。
Frax

1
我从未听说过将CPU卸载到客户端作为使用JS的理由 -我会说在客户端上使用JS的历史趋势表明了这一点(我并不是说(一个,最重要的)原因),而且似乎还在增长自从jQuery突破浏览器不兼容的Gordian结以来,呈指数级增长。
–radarbob

7

要使应用程序“面向未来”,最好的办法是遵循系统设计中的最佳实践,以最大程度地消除问题的耦合和分离。您的应用程序中没有什么部分可以避免过时,但是您可以做很多事情,以将因X原因而过时的代码与不一定受X影响的代码隔离开来。

但是,我认为您对应用程序的增长/可扩展性的关注应小于您自己的经验和功能的增长率。您所描述的思维障碍对我来说听起来像是学习停滞或对许多已知未知因素的意识,而没有解决它们的策略或工具。

尽管框架通常可以通过MVC之类的高级设计模式为没有经验的人提供相关的初始指导,但它们并不是特别适合解决“面向未来”的挑战。相反,它们往往通过提供强大的凝聚力而更有效地用作加速发展的方式,并且通常以更紧密的耦合为代价。例如,假设您在整个应用程序中使用某些框架提供的对象关系映射系统来与数据库进行交互,并完成缓存系统集成。也许以后您需要切换到非关系型数据存储,现在使用它的所有内容都会受到影响。

你现在的混乱并非来自什么你使用,但在那里你使用它(可能几乎无处不在后端)。如果呈现页面的代码从不获取其呈现的数据,那么您的处境会好得多。

假设您想在页面上添加一些小部件,这需要额外的脚本和资源才能正常工作。如果您使用的是框架,则可以问“它如何让我为此添加依赖项到页面?” 如果您不是,那么这个问题就更开放了:“我要解决的技术问题应该以某种方式分开?” 这个问题需要更多的经验来回答,但是这里有一些提示:

  • 如果明天您将所有静态资源(脚本,图像等)移至单独的服务器,内容交付网络等,或者开始尝试将它们打包在一起以提高性能,将会发生什么情况?
  • 如果您开始将此小部件放置在不同的页面上,或者将其多个实例放置在同一页面上,将会发生什么情况?
  • 您如何开始在不同版本的小部件上执行AB测试?

如果这听起来让人不知所措,那么我建议您现在应该使用一个框架,不是为了您的应用而是为了您自己的个人成长。不一定要从头开始。而是将框架用作课程表,以帮助指导应用程序的发展。

只有两种学习方法。一种是通过反复试验,另一种是通过学习他人的经验。试错法不能消除。从本质上讲,软件开发是一个不断学习的领域,根据定义,不需要执行任何新的或不同的代码。(而不是使用已经编写的代码。)

诀窍是通过在开发过程的每个步骤中主动寻找预先存在的知识(策略,最佳实践以及代码/库/框架),以将其最小化,因此您不会发现自己在不断地重新发明轮子。

而对于应用程序,你正在写,但是,你首先关注的应该是简单地把它用最少的做平凡的工作(这是一种像代码味道,但对于开发过程)。鉴于人类学习的本质,实现高质量的最快方法是从某件事开始。当您可以通过折衷已有的东西来塑造目标时,容易理解目标。

如果您可以接受所编写的大部分代码是一个一次性的学习过程,并且是找到好的设计所必需的,那么这将有助于您不断学习。毕竟,解决问题的挑战使软件开发变得引人入胜,并且如果您正在做的事情值得,那么这一挑战就永远存在(请参见上面的“持续学习”声明)。


5

最重要的是,“杀的事情,重新开始”从来没有一个选项...毕竟,你不是说你有“半打的客户呢?” 考虑到他们现在(大概)“对您的工作完全满意”,您是否已经停下来考虑他们对您的发音有何看法?

这是我喜欢使用的类比:

  • “我的工作是为人们建造房屋,为人们建立企业等等。” 我的工作是制造“那些不可能微小的,过度砂化的沙子”来做有用的工作。(就像房屋建筑商用石膏墙板,瓷砖,混凝土砌块和2x4砌成房屋一样。)

  • 但是,尽管房屋建筑商使用的“钉子”在200年中并没有发生太大变化(除了从“方形”变为“圆形”,然后在气动钉钉机上变得有用),该技术我们使用的方法千变万化,有时会发生非常深刻的变化。(“就这样。”)

  • “尽管如此,每间房子,一旦建成,将永远-后可以进来。” 你不能驱逐他们。一旦建造并移交了钥匙,“它不再是您的房子”。现在就是现在,它将持续很长时间。

如今,我的主要业务是利用当时存在的“最先进”技术,帮助客户应对十年,二十,三十或更早之前构建的软件。我记得) –并且今天仍在使用(!)。


3

确保某种东西是未来的证明几乎是不可能的。不过,检查应用程序是否可扩展并不难。您只需要为该应用编写一些性能测试,并查看它可以处理多少个客户端。编写测试无疑将使您的应用程序更具前瞻性,因为在对应用程序进行更多更改后,您将能够评估其表现。

在wrt框架中,我不会太担心性能/可伸缩性。这是您可以轻松检查并最有可能解决的问题。更大的问题是安全性。Web框架通常可以帮助您编写适当的身份验证代码,Cookie,CSRF保护等。尤其是,由于您经验不足,因此请专注于该领域。


3

我开始写有关学习框架的评论,但最终变成了看起来更像答案的东西,就在这里。

不知道任何框架似乎是一个问题。基本上,在任何webdev作业中,您都需要使用某些框架。学习另一种框架,你知道后一个是不是那个什么大不了的,但学习的第一个可能需要一段时间-这就是为什么雇主会在意这一点。避免使用框架可能表示此处未发明综合症,这是不切实际的方法。

了解您的第一个框架的主要要点是学习通用语言,也许只是尝试学习在同行中流行的东西。您可以尝试修改用框架编写的一些简单项目。在您不知道的框架中从头开始项目是一种非常无效的学习方法。

现在,您的实际问题是关于一个特定项目并将其移植到框架中的。为此,答案似乎是:取决于情况,我们无法真正告诉您。但是,将内容移植到您不知道的框架几乎肯定是个坏主意,因为您甚至不知道它是否有意义。因此,似乎您应该保持现状,并且一旦知道并喜欢某种框架,就在某个时候重新考虑这个决定。其他答案包含有关做出此类决定时应寻找的内容的要点。


2

本文在2.5年前的Hacker News上引起了很多关注:编写易于删除而不易于扩展的代码。这种观点可能会或可能不会帮助您处理当前的代码库,但是在将来,它可以帮助防止由于完美主义/过度设计而产生的挫败感。

如果我们将“代码行”视为“花费的行”,那么当我们删除代码行时,我们将降低维护成本。除了构建可重复使用的软件,我们还应尝试构建一次性软件。

我不需要告诉您删除代码比编写代码更有趣。

(强调我的)

文章的Hacker News上线也可能是值得一读。


-1

至于使其成为未来的证明并应用规模和框架原则,这是一个艰巨的任务,我自己可能不必担心,但是如果您必须:

保持代码干净,遵循SOLID,DRY原则> Google。

尽快应用负载均衡器。

站起来至少两个Web服务器,在代码中处理负载平衡方案。

最后但并非最不重要的一点是,与LAMP相比,用于处理100万用户的堆栈更好,但是我敢肯定它是完全可行的。

案例和要点,请参见:https : //stackoverflow.com/questions/1276/how-big-can-a-mysql-database-get-before-performance-starts-to-degrade 该点是有效的,但10gb是微不足道的作为测试对象。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.