设计界面:预测所需的方法,训练自己并处理想到的代码

时间:2010-03-13 02:04:42

标签: interface

  

是:按合同设计:预测   需要的方法,训练自己   并处理想到的代码

我喜欢按合同设计的想法(至少,据我所知,校长)。我相信这意味着在开始实现实际代码之前首先定义接口,对吧?

然而,根据我有限的经验(现在3个OOP年),我通常无法抗拒很早就开始编码的冲动,原因如下:

  1. 因为我的有限经验告诉我,我无法预测界面中需要哪些方法,所以我不妨马上开始编码。
  2. 或者因为我太急于不先写出整个界面。
  3. 或者当我尝试它的时候,我仍然最终实现了一些代码,因为我担心我可能会忘记这个或那个令人讨厌的代码,当我设计接口时会想到这些代码。
  4. 如你所见,尤其是最后两点,这会导致一种非常无序的做事方式。任务混乱了。我应该在设计接口和实际编码之间划清界限。

    如果你和我不一样,是一个优秀/纪律严明的策划者,如上所述,你是怎么做的:

    1. ...知道你需要的大部分方法吗?特别是如果它是实现您不熟悉的东西的组件。
    2. ...抵制立刻开始编码的冲动?
    3. ...处理设计界面时想到的代码?
    4. 更新
      谢谢你到目前为止的答案。有价值的见解!而......我的立场得到了纠正;我似乎误解了合同设计的想法。为清楚起见,我实际上的意思是:“在实现实际组件之前提出接口方法”。

      我想到的另一件事与第1点有关:

      1. b)您如何知道您需要的大部分组件。在开始实际编码之前,你如何充实这些东西?
      2. 为了论证,让我说我是MVC模式的新手,我想实现这样的组件/架构。一种天真的方法是想到:

        • 前控制器
        • 一些抽象动作控制器
        • 一些抽象的视图

        ......完成它,可以这么说。

        但是,更熟悉MVC模式,我现在知道它也有意义:

        • 请求对象
        • 路由器
        • 调度员
        • 响应对象
        • 查看助手
        • 等。
        • 等。

        如果你将这个想法映射到一些你想要开发的全新组件,那么你还没有经验;你是如何在没有实际编码的情况下提出这些额外组件的,并且通过这种方式调整这些想法?你怎么能预先了解一些组件应该是多么精细?这是一个训练自己彻底思考的问题吗?或者是否善于抽象思考?

3 个答案:

答案 0 :(得分:2)

按合同设计!=基于界面的设计

虽然我认为接口的使用通常被称为软件合同(各种合同),但存在差异。话虽这么说,我想我明白你在哪里提出这个问题并对此有所了解。我正在设计一个新项目大约2个星期,最近我对接口有了一些相同的想法。

unable to predict what methods I will be needing 

接受这样的事实,即您(或几乎)将在第一次完全没有正确接口。说实话,试图设计一个界面来解释所有情况而不进行锻炼可能会失败。而是将接口定义为具有非常特定的目的,并且最初只提供满足该目的所需的最基本的方法。作为示例,您可能有一个接口定义对象,另一个接口定义对象上的一组简单原始操作。随着项目的成熟,您可以添加其他方法,因为它们被识别以便于获取/搜索操作。请记住,随着设计的完善,您可以添加到界面中;这通常适用于开发目的,因为界面通常在生产之前不会被版本化。

urge to start coding right away

通过实施一些代码和单元测试来练习它可能会很好。这有助于识别整体方法中的弱点。这样做的诀窍就是只做足够的事情来识别问题,而不是做一个镀金的狗屎屋(对不起,如果这冒犯了任何人,但这是一个常见的短语)。我建议将其视为原型代码,不要在没有经过深思熟虑的情况下将其用于生产。

deal with code that comes to mind when you are designing the interfaces

老实说,这取决于具体情况。某个地方的代码段文件可能适用于此。一般来说,我只是使用便利贴来捕捉思想或想法与任何特定代码,因为我还没有写任何东西(值得注意)。偶尔我会继续开始实现我打算用于生产的课程。

更新回复: 我不认为这个问题有任何一个答案。老实说,我认为它归结为作为软件开发人员/工程师的经验,并知道你最终想要做什么/解决什么。例如,如果没有一些重要的设计帮助,我当然不会指望没有实际经验的大学新生从头开始设计应用程序。大多数情况下,我认为如果你不理解你试图解决的问题那么你很可能会试图设计错误的解决方案。

我的直觉是,您对所使用的技术和/或要解决的问题的了解越少,您就越容易接受您的重构将更加重要。老实说,我认为如果你觉得你可以设计一个完整的应用程序而不重构任何东西那么你可能不应该是设计应用程序的人。然而,重构的重要性是个问题。

答案 1 :(得分:2)

Mark Brackett对TDD提出了一个很好的观点。

然而,我在这样做时发现,我有更难的时间来实现我应该实施的单元测试。这可能主要是由于你正在努力解决的经验不足。所以这就是我处理它的方式:

  1. 严格从纸上开始(此时我甚至都没有打开电脑)。绘制我认为我需要的类/模块,并考虑它们如何交互这给我提供了我需要实现的类和方法。如果我对某些事情不熟悉,我会在此时发现它并可以调查以找出答案。

  2. 经过一段时间的素描后,我要么对我需要做的事情有所了解,要么完全陷入困境,而不是尝试一些东西。这是我开始编码的时候。过了一会儿,我可能会发现我需要改变设计中的一些东西。这不是问题,我有重构的力量!

  3. 在草图绘制过程中(或者在编写完全不相关的代码片段时),我还想出了一些代码解决方案来处理那些唠叨我的事情。如果我已经有了代码所在的文件,我会在注释和TODO标签中的某些伪代码中快速编写它,并在我的记事本上记下它。如果它更复杂或者还没有地方可去,我只会在我的记事本上记下整个伪代码。那时我可以放下这个想法继续我正在做的事情。关键是我有一个纸质记事本,我可以跟踪我需要做的所有事情以及我所做的事情(我已经实现了我的想法)。 (打字和缩进代码只是为了让计算机上的快速创意变得烦人)

答案 2 :(得分:1)

嗯......我对Design By Contract的看法与你的不相符。 DbC更多的是定义除方法签名之外的交互的“其他”方面(这是大多数编程语言强制执行的)。因此,您可以定义“不变量”(总是正确的事物,例如Stack.Count >= 0)或“前置条件”(执行一段代码必须为真的事物,例如Stack.Pop requires Stack.Count > 0 )等等。

话虽如此 - 我建议您研究测试(或行为)驱动设计(TDD或BDD)。它建议编写单元测试不仅要测试代码,还要驱动你的设计。因此,它解决了你的3点:

  

预先知道你需要的大多数方法吗?

没必要。在有需要它的测试(客户端代码)之前,不要编写方法。

  

让自己不要立即抵制开始编码的冲动?

没必要。只需开始编写规范(作为单元测试)而不是实际代码。然后填写实际代码以满足规范。

  

处理设计接口时想到的代码?

编写显示缺失功能的单元测试。您可以立即通过,也可以保留实际代码以供日后使用 - 失败的单元测试将强制您在某个时刻编写代码。

我不是TDD的专家,我也不认为自己是一名从业者。然而,其中有许多有价值的想法。你应该研究它,尝试一下,看看它是否有助于你自己组织。