编码时如何通过分析克服瘫痪?


37

当我开始一个新项目时,我经常会立即开始考虑实现的细节。“我要在哪里放置DataBaseHandler?我应该如何使用它?要使用它的类应该从某些Abstract超类中扩展。发送请求和解析数据的方法?”

我最终停滞了很长时间,因为我想为可扩展性和可重用性编写代码。但是我觉得几乎不可能过去思考如何实现完美。

然后,如果我只想说“拧紧它,就完成它!”,我很快就会碰壁,因为我的代码没有组织好,混合了抽象级别,等等。

您有什么技术/方法来启动一个新项目,同时建立一个可以很好地扩展的逻辑/模块化结构?

- -编辑- -

好吧,这已经是很难接受答案的问题类型了,但是希望获得更多反馈,看看是否有共识。TDD听起来真的很酷,坦率地说,我一直在意欲加快使用JUnit等的速度。与此同时,TDD的拥护者如何看待这一事实,即与TDD有关的合理点解决了我的问题?特别的问题是,TDD似乎并没有真正解决设计问题。当然,我同意TDD将帮助我定义我想做什么,然后我可以逐步研究如何做,但是有许多不同的总体设计模式/结构可以全部通过单元测试。就是这样:它测试单个UNITS。我想我有点困惑...我不知道。也许我'

谢谢!


2
退后一步,拿起笔和纸,勾勒出更大的画面。这将帮助您以更结构化的方式设计实现,而不会在细节上迷失自我……
Darknight,2011年

这是一个很好的问题。这也是我一直犯的陷阱。
Corv1nus 2011年

Answers:


16

我建议使用Test-Driven-Development,这需要一些时间来适应,尤其是在使用诸如eclipse之类的良好IDE时,但是优势很大。

基本上,您要做的是在编写代码本身之前将测试写入代码。因此,您不得不从如何使用代码的角度来查看代码,这意味着您的界面会随着您实现的更多方案而发展。

另一个特点是,您以很小的块来实现(随着您在技术和编程方面的经验越丰富,它们就会变得越大),因此每次您都必须将精力集中在非常小的和定义明确的问题上。

而且,由于您首先编写了一个测试,然后才实施,所以您面前的测试失败了。因此,如果您像大多数程序员一样,就不会对疯狂的分析感到迷恋,因为您会认为:“我需要使此测试有效”。

一个简短的Java示例:
说我想开发一个程序,该程序可以从db读取和写入消息。

因此,从第一个明确定义的动作开始,我需要一个数据库:

@Test
public void testDB() {
  DB db = DbConnector.getDB(address);
  assertNotNull(db);
}

好的,所以在这里我看到我需要实现DbConnector.getDB类,以便它返回数据库,直到此测试失败。我去做...

不,我添加我想做的下一件事,从数据库加载消息:

@Test
public void testDB() {
  DB db = DbConnector.getDB(address);
  assertNotNull(db);
  String message = db.fetchMessage(key);
  assertEquals("hello world", message);
}

现在,我向数据库添加了另一个小功能,该功能是获取一条消息,然后执行该功能,完成后,我每次都会继续使用一个功能,直到出现类似这样的情况:

@Test
public void testDB() {
  DB db = DbConnector.getDB(address);
  assertNotNull(db);
  String message = db.fetchMessage(key);
  assertEquals("hello world", message);
  message = "foo bar";
  db.storeMessage(message);
  message = db.fetchMessage();
  assertEquals("foo bar", message);
}

这似乎是一个非常简单的示例,但这也适用于更复杂的任务。我知道一开始非常耗时,但是随着您习惯它,您会发现它实际上要高效得多。对于一种方法,您可以避免分析引起的瘫痪,而对于另一种方法,您可以获得更健壮的代码,这些代码通常具有较少的错误并经过较少的迭代。


4
和TDD迫使你重构了很多,所以你进入持续重构,这将有助于通过搞砸代码的砖墙打破,就像一个工作模式programmers.stackexchange.com/questions/86364/...提及。
畏缩

在这种情况下,我实际上发现TDD的测试优先方面是一个障碍。如果我在设计界面本身时遇到足够的麻烦,那么设计测试将变得更容易或更明显吗?在开始设计某些东西的那一刻,重构负担太高了。我不知道其他人如何处理。
史蒂文·埃弗斯

1
@SnOrfus,对。当您拥有模块并希望专注于什么与如何时,TDD效果很好。但是这些模块可能以多种方式组织。通过TDD并没有真正弄清它们如何组合在一起,将使用哪种结构。
LuxuryMode 2011年

5
嗯,这听起来像是TDD迷。....用笔和纸勾勒出建筑的轮廓怎么了?还是我过时了,还不够“时髦”?……
Darknight,2011年

1
笔和纸(或白板)很好。勾勒出总体计划,大局。如果它不能放在一张纸上,那就太复杂了。一旦你已经得到了大图片的计划,你可以得到忙着BDD,嘲讽等
多纳尔研究员

10

这发生在我身上,所以我养成了接受(和拥抱)持续重构思维的习惯。我做了可能可行的最简单的事情,然后整理,整理,解耦,测试并继续。

这并不是说没有太多的计划在进行,但是它发生得非常快,并且经常是在废料或我的脑海中涂鸦。总而言之,有时我将这个小流程称为“小迭代”,因为它们每次需要5-20分钟,而从经验来看,需要2-3分钟才能完成我的工作(显然,这取决于我的工作)。

附带说明:我已经以不同的写作形式(包括报告,论文和技术写作)辅导了许多人,这与我让他们写东西以克服作家的障碍一样。“只要将页面上出现的与您的主题相关的任何内容都脱口而出即可。然后我们将其弄清楚,并将其全部分成几段,并检查流程。如果需要,我们甚至将其重写。”


1
+1提及写作。我刚从编码中采用了频繁的重构方法,并将其应用于写作。对我来说效果很好。
ZsoltTörök

2

一些可行的方法:

  • 确定您要解决的核心问题-您要做的事情的核心是什么?只需实现这一点,并只需最少的支持代码即可使其运行。一旦它使您满意,就可以迭代地建立起来,在每个步骤中毫不留情地进行重构。
  • 查看其他编程范例是否对您有用。尽管具有所有优点,但是面向对象的程序设计并不能解决所有问题,并非所有程序员的大脑都能以这种方式工作。选择一种(纯粹的)功能语言;编写一些程序代码;深入到硬件级别,并做一些C甚至汇编程序;等等。几种语言可能会引起您的注意(假设您当前使用的是C ++ / Java / C#/ VB / ...):Haskell,ML,Lisp(多种方言可供选择),Erlang,Prolog, Smalltalk,Javascript(如果不尝试使它表现得像Java一样,而是采用其闭包特性),C,Pascal,awk,也许还有十几种。关键功能是它们需要与您现在使用的非常不同。这不是您要在一个有很多风险的大项目上要做的事情,
  • 使用完全不同的设计方法。看看是否可以从其他角度进行设计。我认为您通常是通过布局课程来开始设计的。从数据结构开始如何变化?还是先设计UI,在设计任何功能之前先按原样绘制输入表单?

1

对于许多设计决策而言,这可能有助于进行“尖峰”,这是一项短暂的,有时间限制的研究工作,您可以通过编码为一次性原型来探索某些架构或设计选项。例如,您可以探索某些开源库的使用或如何组织类和接口。他们的关键是保持简短,以便在第一种方法不能令人满意时尝试另一种方法,并希望您能在练习中获得足够的知识,以便更好地做出体系结构决策或证明概念。练习本身涉及立即编码,这有助于摆脱“ writers block”,而不必太早地承诺“ git'er done”。

之后,使用Asaf提到的TDD或BDD方法来推进项目的实施是有益的。


我同意+1。计划放弃第一次尝试。将其视为学习经验。在我想坚持第七个之前,我已经丢掉了多达六个。
Mike Dunlavey

1

您将不需要它,因此一开始不要考虑太多。

花更多的时间来定义,理解目标和问题。

“可扩展性和可重用性”是编写良好的软件程序的生命周期的自然结果。


0

我假设我们正在研究一个中等规模的项目。
我将从画图板开始。在执行此操作之前,应准备好功能要求和非功能要求。首先,您需要提出软件架构,即查看适合您需求的任何架构模式。
一旦决定了架构的外观,就应该进行底层设计,即查看所有实体,类和功能。 。在这里,您将再次尝试确定适合的设计模式。在此过程中,您将知道基类是什么以及所需的接口,
然后可以构建框架并运行一些快速测试以查看是否满足您所有的非功能性要求
然后,我将按照@Asaf的建议进行测试驱动开发。

请记住,尽管在设计和架构上花费了很多时间,但是如果需要的话,总是愿意重新审视架构。


0

我认为这是一个很好的问题,对任何人都无济于事。我确实认为,这种麻痹是您所在领域变得越来越胜任的自然产物。就是说,以下是我可以提供的一些帮助,但不能解决问题:

  • 将您原始的项目放在一边,并在丑陋的版本上工作。这是您告诉自己的版本:该代码不应该很漂亮。实际上,告诉自己,不允许进行重大的重构和重新格式化。让它完全没有组织,让自己摆脱良好编码的束缚。b。它只是必须工作。C。当我抛出所有其他问题时,我对问题空间的了解总是让我感到惊讶。我还得到一些小窍门,这些小窍门通常可以帮助我以更开明的方式来进行正确的设计。

  • 在没有计算机的情况下,在项目上留出相当大的时间。尝试概念化您真正要完成的工作,并寻找超越OO /设计模式疯狂的魔术禅。


0

具体表达您的想法:写下/打下,画出或以其他方式表达。这将帮助您在需要时重新审视自己的想法;它将阻止您转圈;帮助您更清晰地思考。

每当我看到自己无所事事,无所不在地思考某事时,我便将它们打出来,这有助于我清晰地思考。


0

我通常从头开始,创建尽可能简单的原型并开始运行。使用原型对幸福路径测试用例进行反向工程,用测试用例驱动接口,然后考虑签订前/后合同以帮助扩大测试范围。

在完全理解问题之前,不必担心抽象,优化或验证。

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.