当我知道自己会做错的时候,我该如何构建某个东西?

11

背景

我有一个个人项目,已经尝试构建了大约5年。它本质上是一个在线游戏 - 一个Web应用程序。它不是“赚钱”的东西,只是我真的想要构建的东西,因此很难找到资金来雇用熟练的团队。

多年来我已经建立了两个完全功能的原型,在概念/用户测试方面都成功了,但从架构角度来看却是惨败的;代码一团糟,无法维护或进一步开发,必须被放弃。

我花费了好几年的时间获取构建客户端所需的技能 - 它是富/状态性且相当复杂的。我将自己的职业生涯和学习与这一开发领域保持一致。我终于到了可以构建一个合理架构、复杂的客户端的地步,可以增长并且不需要在6个月内被抛弃。在这方面有很多工作要做,但至少我知道我可以做到,并且做得相当不错。后端则另当别论。

到目前为止,我已经使用各种组合的PHP、SQL、Ruby、CouchDB、MongoDB、FriendlyORM、NodeJS等重建了后端至少11次。我通常在发现自己的方法存在一些巨大缺陷并重新开始之前没有走很远:从RPC到REST,从关系型到文档驱动。我非常清楚过早优化是万恶之源,但应用程序非常依赖于快速移动、高度动态数据。RESTful API设计、扩展、分片、缓存、认证、复制 - 我对这些都没有太多经验,也不可能很快变得相当熟练。这需要多年的学习和经验。

找一个这个领域的专家更有意义,但没有资金,我觉得我需要成功部署另一个原型才能吸引到合适的人。所以,我只能尽我所能去构建它。

问题

假设不管我如何构建它,后端架构都会出现问题并需要重建,那么在构建“足够”的内容以继续开发客户端应用程序方面,最佳的方法是什么?即使很糟糕,是否有一种方式可以“拼凑”一个JSON web服务呢?使用Ruby和Sinatra还是MongoDB?Django?是否有一些现成的Web服务构建器可以使用?由于没有演示层 - 只有数据,因此不需要完整的全栈Web框架。任何建议将不胜感激。

@Franky-D: “我非常清楚优化是万恶之源”的原因是什么? - Aryabhatta
也许他的意思是“过早”的优化? - FrustratedWithFormsDesigner
@Franky-D 过早的优化是万恶之源 - 请参见http://c2.com/cgi/wiki?PrematureOptimization - Péter Török
2
@Franky-D,好问题 - 我发现自己在复杂个人项目方面也处于同样的情况。然而,作为一名曾经参与过许多大型企业应用开发的顾问,我的建议是:明确你的需求。如果你在开发过程中遇到了问题,很可能有一个需求可以回答它或者应该回答它。如果你有明确的需求,你就有了在开始投资之前评估产品和提案的手段。糟糕的需求会导致你所经历的试错。 - johnny g
你在服务器端遇到了哪些具体问题?你如何知道你需要扩展、分片、缓存等方案呢? - Andy White
@Moron,FrustratedWithFormsDesigner,Péter Török:谢谢,这是一种排版错误,已经修复。@johnny g:好建议。比起坐下来定义适当的需求,更容易陷入编码中。我想我在这方面有点懒。@Andy White:客户端是一个Flex应用程序,通过大量快速变化的数据进行导航。系统中的每个移动都会改变它。以前的原型版本过于频繁地访问数据库 - 即使只有相对较少的用户(+-900)。 - Franky-D
7个回答

7

首先,通过编写干净、模块化的代码来降低程序运行速度。

如果代码具有模块化,您可以替换一两个层级而无需丢弃整个程序。

尽管Web服务(包括REST)提供了模块化,但要小心它们的速度问题;例如,每次连接都存在大量开销。


8
先让它跑起来,然后使其正确,最后让它变快。按照这个顺序进行。 - Wayne Conrad
韦恩可能比我说得更好。 :-) - Dean J

5
构建这样一个庞大而复杂的应用程序,特别是一个存在许多相互依赖、特定于状态的条件和需要使用不兼容语言的客户端-服务器分离的应用程序,无论你采用何种方式,都是令人望而却步的。根据我在其他类似项目中的经验,无论你多么小心谨慎,第一次尝试都注定会失败。关键是要将失败视为通往成功的必然步骤,不要在构建应用程序时过于纠结每一个小细节。
首要任务应该是尽可能少地编写代码,只需简单地实现你想要的效果,即使非常粗略,以便看到整个应用程序的组成部分。如果你可以将大问题分解成一系列小问题来解决,你可能会在其中一个元素上取得成功,这可以激励你去解决更大或不同的问题。
一种有用的策略是保持应用程序的各个元素之间松散耦合,避免除了严格要求的情况下产生相互依赖,这样你就可以在不引起连锁反应的情况下替换或改进整体的某些部分。例如,你的网络代码可以能够在客户端和服务器之间传输状态更改,而不用关心状态本身的性质,但你的状态管理代码不必关心状态如何传输,只需要知道它们将被传输。

理解应用程序的整体架构非常有用,这样您就不会迷失在代码中。从高层次的角度来看,您可能希望熟悉基本的设计模式,这些模式可以帮助您将一堆难以理解的代码组织成简单、模块化且易于构建的东西。

关于框架和编程语言,我建议尽量避免频繁切换。虽然探索新语言以了解其特性是否有助于解决特定问题是很有教育意义的,但如果你坚持使用一个语言,即使有时可能很难实现某些功能,你也会更加高效,从而改进你的方法以更好地适应该语言。虽然Haskell可能更适合某些问题,但即使是普通的PHP,在足够的决心下也可以做到完全相同的事情。

有一种诱惑是尝试新事物,扩大工作范围以使其“正确完成”,在想到新功能时进行构建,但为了控制项目,您必须保持纪律,避免这些昂贵和分散注意力的活动,这些活动往往只是幻想或过早考虑到项目的整体状态。

针对您的问题,建议在您最熟悉的框架中构建,并在较小的增量中生成有用的结果。也许这是客户端显示引擎、网络组件或后端状态转换,但无论如何,您应该将其处于“足够好”的状态以开始附加其他组件。解决十个小问题可能会很繁琐和耗时,但比解决一个巨大的问题要容易得多。

3

您无需构建任何类型的Web后端即可开始原型设计客户端应用程序。只需使客户端应用程序调用返回虚拟数据的存根函数即可。


艾尔威克所暗示的更重要的一点是模块化设计。如果将项目划分为明确定义的部分并完全定义它们之间的接口,那么您的项目就成为了一系列“构建块”。 如果您需要重新构造后端,则只需重新制作单个“块”,只要它符合相同的接口,其他组件甚至不必知道任何内容已更改。在小组件上重新工作或重新编写代码要容易得多。 - bta

2

我的观点:过分强调技术,而忽视了坐下来做适当设计的重要性。

  1. 从高层次设计开始。
  2. 确定涉及的不同主要部分。花费一些时间进行第1步和第2步。
  3. 查看可用的现成组件,以帮助快速实现不同的部分。考虑到您以后可能会将这些组件替换为其他东西(包括您自己的解决方案)。
  4. 重新审视第1步和第2步。
  5. 选择一个或两个部分,并开始编写涉及的工作原型代码。
  6. 在完成前期工作后,从第1步重新开始,并查看已更改的内容,以便相应地进行补偿。

2
约翰尼·G在对您最初提出的问题的评论中几乎完美地回答了它。您描述的情况甚至发生在财富500强公司身上,信不信由你。在每三个月选择和抛弃最新和最酷的技术之前,您需要彻底计划您正在尝试构建/完成项目的内容。
我认为这篇来自《连线》杂志的文章,“学会放手”,讲述了《公爵等待太久》失败的原因,将比我更好地解释这一点。

http://www.wired.com/magazine/2009/12/fail_duke_nukem/

(无论如何,这也是一篇相当有趣/有启发性的阅读材料)

0
如果你的项目很糟糕,没有人使用它,那么优化它有什么意义呢? 先让一个端到端的版本运行起来,我相信你会发现很多其他你还没有考虑过的问题,这些问题可能更加重要。

0

我发现完成个人项目只有一种方法。

先聪明地编写代码,后规划。开发原型,但设计时要确保任何单个部件都可以被替换为另一个部件。

例如,如果您选择的语言是Ruby,请构建具有明确定义接口的类,您永远不会破坏它。关注每个函数“做”的正确事情,而不是真正关心它如何实现。

然后,回到以模块化方式构建的原型,并逐个修复其中的一个部分。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接