代码之家  ›  专栏  ›  技术社区  ›  Decent Dabbler

设计接口:预测所需的方法,约束自己,处理想到的代码[关闭]

  •  4
  • Decent Dabbler  · 技术社区  · 15 年前

    是: 按合同设计:预测 需要的方法,约束自己 并处理脑海中出现的代码

    我很喜欢按合同设计的想法(至少在我了解委托人的情况下)。我相信这意味着在开始实现实际的代码之前,首先要定义接口,对吗?

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

    1. 因为我有限的经验告诉我,我无法预测在接口中需要什么方法,所以我最好马上开始编码。
    2. 或者因为我太不耐烦了,不能先写出整个接口。
    3. 或者,当我尝试它的时候,我仍然会最终实现一些代码,因为我担心我可能会忘记当我设计接口时会想到的这个或那个不重要的代码。

    如你所见,尤其是最后两点,这会导致一种非常混乱的做事方式。任务混淆了。我应该在设计接口和实际编码之间画一条清晰的线。

    如果你不像我,是一个好的/训练有素的计划员,如上所述,你如何:

    1. …你对大多数预先需要的方法都很了解吗?尤其是当组件实现了你还不熟悉的东西时。
    2. …抵制马上开始编码的冲动?
    3. …处理在设计接口时想到的代码?

    更新:
    谢谢你的回答。有价值的见解!而且…我坚持改正;我似乎误解了合同设计的概念。为了清楚起见,我实际上的意思是:“在实现实际的组件之前提出接口方法”。

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

    1. b)您如何知道您将需要的大部分组件。在开始实际编码之前,如何充实这些内容?

    为了便于讨论,假设我是MVC模式的新手,我想实现这样的组件/体系结构。一个幼稚的方法是考虑:

    • 前控制器
    • 抽象动作控制器
    • 一些抽象的观点

    …可以这么说,就这么办吧。

    但是,更熟悉MVC模式,我知道现在也有必要:

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

    如果你将这个想法映射到你想要开发的全新的组件上,而你还没有开发的经验;你如何在不实际编码的情况下开发出这些额外的组件,并以这种方式扼杀这些想法?您如何预先知道一些组件应该有多细粒度?这是一个训练自己彻底思考的问题吗?或者这是一个善于抽象思考的问题?

    3 回复  |  直到 9 年前
        1
  •  2
  •   Ken Henderson    15 年前

    按合同设计!=基于接口的设计

    尽管我同意,界面的使用在软件中通常被称为契约(某种程度上),但还是有区别的。尽管如此,我想我理解你的问题所在,并对此有一些想法。我正在设计一个新的项目,大约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
    

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

    更新的响应: 我认为这个问题没有一个答案。老实说,我认为这归根结底是作为一个软件开发人员/工程师的经验,并且知道你最终想要做什么/解决什么。例如,我当然不会期望一个刚从大学毕业、没有实际经验的人在没有重大设计帮助的情况下从头开始设计应用程序。大多数情况下,我认为如果你不理解你正在试图解决的问题,那么你很可能会在设计错误的解决方案时转动你的轮子。

    我的直觉是,您越不了解正在使用的技术和/或要解决的问题,就越容易接受重构将更重要。我也真诚地认为,如果你觉得你可以设计一个完整的应用程序而不需要重构任何东西,那么你就不应该是设计应用程序的人。不过,重构有多重要还是个问题。

        2
  •  2
  •   NomeN    15 年前

    马克·布拉克特在TDD上有很好的表现。

    然而,我发现在这样做的时候,我有一个更困难的时间来完成我应该实现的单元测试。这可能主要是由于你所面临的经验不足的问题。所以我是这样处理的:

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

    2. 在画了一会儿草图之后,我要么对我需要做的事情有了一个很好的了解,要么完全陷入困境而不去尝试一些零碎的东西。这是我开始编码的时候。过了一会儿,我可能会发现我的设计中需要改变一些东西。这不是问题,我有重构的能力!

    3. 在绘制草图(或者编写完全不相关的代码片段)的过程中,我还为困扰我的事情想出了代码解决方案。如果我已经有了代码所在的文件,我会在注释和todo标记中快速地用一些伪代码写它,并在记事本上记下它。如果它更复杂或者还没有地方可去,我就把整个伪代码记在记事本上。在那一点上,我可以放弃这个想法,继续我正在做的事情。重点是我有一个纸记事本,上面记录着我需要做的每件事和我已经做过的事情(我把我实现的想法交叉起来)。(打字和缩进代码只是为了让计算机上的快速想法烦人)

        3
  •  1
  •   Mark Brackett    15 年前

    嗯……我的想法是 Design By Contract 不太适合你的。DBC更多的是定义交互的“其他”方面,而不是方法签名(这是大多数编程语言所强制的)。所以,你定义了诸如“不变量”(总是正确的事物,例如 Stack.Count >= 0 )或“前提条件”(执行一段代码时必须满足的条件,例如 Stack.Pop requires Stack.Count > 0 )等。

    也就是说,我建议您研究测试(或行为)驱动设计(TDD或BDD)。它建议编写单元测试不仅是为了测试代码,而且是为了驱动设计。因此,它解决了您的3个问题:

    你对大多数前期需要的方法都很了解吗?

    没必要。直到有一个需要方法的测试(客户机代码)时,才编写方法。

    防止自己抵制马上开始编码的冲动?

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

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

    编写一个显示缺失功能的单元测试。您可以现在就让它通过,也可以将实际的代码留给以后使用——失败的单元测试将迫使您在某个时刻编写代码。

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

    推荐文章