最佳实践 – 编码之前的devise

我很好奇你怎么想? (我的意思是一种思维方式),关于你的图书馆,系统,框架等的devise架构,然后开始编码。

最近我发现自己感到痛苦,几乎每一次我都想从头开始。

我之前做过devise,在纸上绘制了一些scheme,并想象它会如何工作,但也许我做的是错误的方式?

例如,你如何决定你将需要什么界面,或者如何以最好的方式连接所有的东西?

(前一天我有一个问题,我的朋友问我一个图书馆,我刚刚做了什么,而不是给他一个文件,我不得不给他3-4个文件,那是因为他们以某种方式连接..但不是在正确的我想:)所以这是我的错误devise..)

我通常对纸/白板上的问题域做足够的分析,以便对问题域有足够的了解,从而开始编写代码。 我很less在纸上绘制实现或类图。 我发现实现更好的devise的一个关键技术是不要过分依赖你编写的代码。 如果我不喜欢它,我删除,重命名,移动和洗牌,直到它expression一个足够好的解决scheme,我试图解决。 听起来很容易? 一点也不! 但是用好的“编码”工具,实际上编写代码并不是主要的工作。 写一些,重构,删除,再写一次…

好的devise几乎从来没有开始好。 它发展到好的。 接受这一点,可以轻松工作,而不会感到沮丧,为什么devise不“完美”。 为了这个过程的工作,你必须拥有良好的devise技能。 重要的是,即使是优秀的devise师也不会在第一时间做对。

很多时候,我以为我在开始的时候就了解问题领域,但是我没有。 然后我回到白板上,和别人交谈,或者如果我意识到自己对这个问题领域的理解还不够清楚,那么可以阅读一下问题领域。 然后我回到代码。

这是一个非常迭代的过程。

在处理程序员如何思考时,一个有趣的问题是他们如何发展他们的思维方式。 就我个人而言,我的思维方式多年来一直在发展,但是一些事件对我开发软件的方式产生了深远的影响。 其中最重要的是与专家devise人员一起devise软件。 没有任何东西比我的优秀devise师花费更多的时间来影响我。 另外一个事件已经影响了我的思维方式,并回顾了我之前写过的软件。

对于一个面向对象的方法,我觉得离开用户界面稍微离开一下是个好主意,并且关注系统中将存在什么实体(对象),以及哪些属性和动作是合适的。

在白板或大张纸上绘图,使用不同的颜色来识别各种特征也是一个好主意。 便利贴也是让您的模型可视化的好方法。

即使我花很多时间仔细考虑devise,我总是会随着时间的推移而改变它。 所以最好记住,当你决定如何logging你的devise时,你的devise将会改变。

我通常会花费大约2到4个小时来完成我的应用程序的devise,然后把它写在笔记本上。

然后我开始编写代码,每当事情变得复杂的时候(因为某些东西不在正确的位置)我重构。 移动一个类到另一个包,或提取方法等等。当“devise”感觉正确的话,我可以继续前进。

这样我就避免了“分析瘫痪”的发生。 很多时候,当我在devise前期结束时,我没有使用一些文物。

所以我采取了这个更“敏捷”的方法。

快速绘制devise,并在运行中“改进”(通过重构)。

当然这对小应用程序是可能的(2-4周长)

我build议你读一下这篇文章:Martin Fowler的devise是死的吗 ? 这是一个有点长,但值得一读。

编辑

额外的链接(略带offtopic) 如何devise一个良好的API和 Joshua Bloch 为什么重要 。 当您有API的受众时,谈论devise的相关性。 总结,尽可能私下开始,并从那里增长。

我主要是从一盒卡片开始,写下我想要build模的领域的概念。 有时我为此使用一个思维导图。

看看利益相关者,他们想要完成什么。 从那里开始非常重要,因为它可以让您正确地确定优先级(即不是最有趣的技术部分,而是最具商业价值的部分)

关于devise的想法大多是在testing中写下来的。 编写代码之前执行它。 从利益相关者最终目标开始,从那里开始工作(时间倒转)。 这确保你专注于什么,而不是如何。 对象之间的交互比对象属性更重要。

另一部分主要在白板上。 目前,小型数码相机是标准设备。

在你需要三个实现之前做一个框架是一个不好的做法。 如果你必须,准备好重大的接口(和实施)的变化。

看到:

虽然不是你的问题的完整答案,但我有时候会find一个项目最简单的方法,就是find一小块独立的function来开始工作,同时也考虑更大的局面。

这样,你就不会在每一分钟的细节上都陷于困境,而且正在努力工作,给自己一个喘息的空间,看清楚你需要做什么。

就像我说的,不是一个答案。

我遵循一个非常松散的Rational Unified Process版本。

首先从视觉文件开始,清楚地说明你正在做什么,你正在做的是谁,或者是关于所提出的方法/algorithm的一些关键细节。 它不需要花哨,甚至可以作为一个简单的系统“一个预测中奖彩票号码的系统,仅供个人使用,基于霍格沃茨学校的最新研究”,对于一个更复杂的系统大约五页,但没有更多。 这不是devise,而更像是一个愿望清单。

然后做一些用例/故事。 这些应该是与外部世界相互作用的简单的自然语言文本描述。 极简主义是这里的关键。 用例的目的是识别所有必需的function和只有所需的function。 我也发现这是大部分创造力发生的地方。

用例可能开始为:

  用户按下“魔术”button。
  系统显示下周的中奖号码。
  用户记下号码。
  用户购买彩票。
  彩票抽奖号码。
  用户要求钱
  彩票支付。

经过很多努力,最终结果如下: –

  用户按下“魔术”button
  系统select下周的数字。
  系统login到彩票系统。
  系统input中奖号码。
  彩票select中奖号码。
  彩票转移到用户帐户的奖金。
  用户花钱。

一旦你完成了你的用例,你可以启动你的开发环境,各种类和相互作用就会落到实处。

它必须是一个平衡。

如果你试图在白板上用大量的图片来devise所有的东西,那么你可能会错过一些细节。

如果您开始盗用系统的一小部分,您可能会忽略“大局”,最终导致糟糕的devise。

当你在看图书馆时,你希望他们尽可能地重新使用。 所以对于最初的devise,想想你可以在你已经知道的图书馆的预期用途中使用的最一般的情况 – 在这个阶段不要担心太多的假设未来的用途,可能永远不会发生。 使用unit testing对devise进行编码,并在学习更多时重构,并找出devise问题。

尽量less把图书馆用户的具体知识放到图书馆本身。 然后,如果运气好的话,你最终会得到一些可重用的东西,并且不会自动地在下一次从头开始。

问题是,当你开始一个新的项目,它往往是新的(现在不是那么明显)。 一般来说,一个人不理解新的东西,除非你是一个非常专业的顾问,一遍又一遍地做同样的事情,这听起来很怪异。

因为你自己制作的系统是新的,所以你的devise和代码在第一次不会是完美的,所以你重新devise和重构代码,直到它准备好。

我更喜欢自下而上的devise。 如果没有应用程序框架,我倾向于先组装或构build它。 一个好的应用程序框架是可移植的和应用程序不可知的,主要是为了解决横切问题。 它通常包含诸如日志logging,exception处理,validation助手,扩展方法等。

从那里,我喜欢用一个很大程度上DDD(域驱动devise)的方法。 如果需要,访问业务用户来构build域模型。 一旦领域模型,和后续的DAL(数据访问层)照顾,我移动到业务逻辑层(BLL)。

我个人试图尽量避免从前端实施,因为它明显不是我的强项。 我热衷于unit testing的一个原因是,我可以专注于核心function,并且能够testing该function而不会跳入过早的界面决策。

打开问题。 将有几乎与海报一样多的答案。 1)看看许多软件工程书籍。 有些人认为devise很好,其余的很简单。 这是一个直言不讳的谎言2)看看如何介入多样的框架是,你最好不得不使用他们的预期的方式,否则你更好地实施你的需求的东西3)devise将需要不断改变任何文字。 你看到句子,但你觉得他们不适合。 所以你重写它。 所以每一个devise都必须考虑到,就像你写下这个devise一样,事情是不一样的。

问候弗里德里希

在做任何像游戏开发这样的重大项目时,我都会尝试仔细地构build我的代码,并从一开始就制作非function性的虚拟函数和类。 从主代码文件中,如果有必要,我把所有的东西都分成了其他模块和子模块中的类。 例如; 我的主代码页将只包含和调用我的主要模块的类初始值设定项。 下面是我现在用Python制作的一个游戏的init.py例子。

来自commonheadersimport*

if arguements.debug: debug.init() try: graphics.init() sound.init() physics.init() input.init() loop.start("scene1") except Exception, e: print "Error!" print e 

这是非常简单和容易理解的,但是我最喜欢的是它在各个主要代码方面给出了非常明确的分离。 如果我对graphics课的某些东西感到沮丧,我可以去声音课或其他的东西上做些其他的事情,让其他的东西完成,并保持一段时间的graphics,直到云通过。 在所有类的init()调用中都有可选的参数,比如graphics的widht / height,但是我通常将它们放在那里,并将它们设置在commonheaders.py文件中或通过命令行开关。

我想尽量不要让我的任何模块超过大约100行,然后再考虑我可以剪切掉哪些模块。 它使得一切都变得更加清洁,当它被拆分时,find你要找的东西要容易得多。 我以前曾经与各种开源项目合作过,在成千上万行中看过单个模块之前,有太多的冗余代码很容易被卸载到帮助函数中。 我在必要的地方使用注释,但是我尽量保持我的代码结构,使得你甚至不需要阅读注释。

我真的很喜欢从一开始就构build了非function性框架,因为它可以很容易地看到还需要做什么以及哪些可以在结构上得到改进。 编写成千上万行代码只是为了找出更好,更实用的方法来完成代码的重构。