POC 的力量






4.42/5 (6投票s)
创建 POC 作为您下一次冒险的第一步的重要性
引言
什么是POC?POC是概念验证 (Proof of Concept),简单来说,就是将一个想法变成现实的尝试。
对于软件开发人员来说,这通常意味着有一个新的库或工具看起来能让你的生活更轻松。或者你的老板/首席架构师告诉你,必须创建一个前所未有的新功能。在你可能没有功能规格文档,没见过这个库,甚至不知道如何拼写它,你就踏上了新的冒险之旅。
一般来说,除非你能提前阻止这个需求,否则正在开发的新小部件很可能注定失败。告诉你的上级,你需要指定天数来确定你被要求做的事情的可行性。冷静地解释说,你将创建一个新项目,仅在必要时使用最佳实践。这将确定潜在的陷阱和痛点,并最终提供项目成功或失败的见解。
同行和同行评审
运气好的话,没有人会期望你是个奇迹创造者,你的同行会在关键时刻帮助你。但请务必不要过度依赖他们,否则会显得你在期望他们为你工作。这只会让你声誉不佳。
在良好的软件开发中,同行评审很重要,但在这种特定情况下,通常应忽略对最佳实践的批评。在此原型期间,应尽量减少最佳实践,因为它们通常耗时且对当前问题没有好处。重点需要放在可行性、可靠性、可重复性、可扩展性以及我遗漏的任何其他 "-ibility" 上,并帮助找出潜在问题。请记住,你的同行可能正在帮助你开发这个小部件,或者至少在将来维护它,如果你试图蒙骗他们,你可能会后悔。
文档
在规定的时间结束时,你必须有一份文档,这份文档可以是一份精美的报告,也可以是用记事本写的,其中包含你所做工作的解释。这是必须的。如果你只给你的老板做口头演示,他可能会质疑你真正做了什么,并且很可能再也不会让你做POC,或者更糟——盲目地继续前进。口头演示也可能导致关键信息的丢失。
为了让这个过程更轻松,请打开记事本,在你想到的时候记下问题/疑虑。记录所有问题和解决方案。这可以帮助你以后,所以不要写过于隐晦以至于你无法理解的笔记,也不要写得过于详细以至于失去焦点。请记住,你正在创建的是一个原型。
你生成的文档将为你提供一个立足点,并决定是否继续进行,或者在某些情况下,请求额外的时间。如果决策者决定继续进行,而事情进展得非常糟糕,它也可以用作一种“自我保护”。
背景
那么,我为什么要告诉你这些你可能已经知道的事情?也许当我讲述我在一个项目中遇到的可怕经历时,你会更清楚。
在我开始这个项目的前几个月,高层决定需要一个新的.NET Web服务,以便为未来扩展做准备。这项任务交给了一位经验丰富的开发人员。他决定使用WCF作为Web服务,并使用Entity Framework来访问数据库。在某个环节,有人决定创建新的DTO对象,并通过Web服务公开。
为了辅助新对象的创建,开发了一个单独的项目来自动生成类。它旨在消耗EF的基于XML的EDMX文件,并生成带有额外CRUD方法的类。服务器端和客户端都创建了一组类。客户端类旨在内部使用,并提供相当于EF的额外缓存功能。像大多数代码生成一样,总会有事情不按计划进行的时候。在这种情况下,需要手动修改生成的代码才能使其编译。每次对生成器进行更改并且需要重新生成文件时,都必须进行手动修改。我认为我不需要再说更多了。
项目进行得很顺利之后,我接到了第一个任务,生成一些SDK示例来展示如何使用新的Web服务。这似乎是一项足够简单的任务,可以让我练练手。令我恐惧的是,Visual Studio无法生成代理对象。WCF服务进行了一些自定义,导致它不再工作。经过无数小时的反复试验,最终在自定义安全实现中找到了问题并提供了修复。回到当前任务,我能够创建代理对象并开始编写一些基本的CRUD示例。我很快发现,我最可能期望使用的搜索方法并不存在。此外,我被告知我需要在Web服务中作为部分类编写一些自定义方法,而其他方法可以添加到生成的代码中。在对生成器进行新的添加之后,文件又需要手动编辑了。
最终,大约有50个类,每个类大约有10个生成的方法,仍然缺少很多方法。在每个类的10个方法中,大多数都要求我不断地从Web服务请求数据,因为它不允许我在检索子对象或父对象的同时检索孙子对象。
过了一段时间,我接到了我的下一个任务——使用另一个公司的框架,将我们新的Web服务与该公司的产品集成。太好了,这看起来像是一个轻松的投球,但事实证明我错了。该产品和框架是用Java编写的。这是我第二次被迫做这种可怕的任务,我大概知道需要做什么,并开始慢慢地用头撞墙,以便麻痹自己,为接下来的事情做好准备。我遇到了通常的数据类型问题,特别是日期/时间字段以及代理创建问题。这些与我发现的一个问题相比显得微不足道,而我被告知我必须解决它。
问题是,Java要求在实例化客户端代理时必须提供Web服务的WSDL。为什么?我不确定,但确实是必需的。另一家公司的框架无法保留客户端代理的引用并每次都重新使用它。这意味着客户端代理必须再次从IIS下载WSDL。IIS默认情况下不会保留WSDL的时间超过需要,并且会在一段时间后将其丢弃。这通常不是问题,但在这种情况下,IIS创建WSDL平均需要5分钟。是的,没错,5分钟。像大多数人一样,如果某件事花费的时间超过10秒,我就认为它坏了。
学到的教训
本节将简要概述,尽管不完整,一些我吸取的教训。
POC
如果我们审视上面的故事,创建几个POC将能够识别出几个令人担忧的领域。
手动编辑:更好的解决方案可能是创建类,然后放弃未来的重新生成。这通常被称为“90%规则”。如果我能完成90%的繁琐任务,那么我只需要手动完成10%的定制工作,从而节省大量时间。手动修改也只掌握在开发人员的脑海中。
检查生成的代码,其中50%是不必要的,因为它涉及查找值,而不需要CRUD。删除这些方法甚至类将大大减少IIS重新生成WSDL的时间。
WCF和Java并不总是能很好地协同工作。像ASMX这样更成熟的旧技术可能是一个更好的选择。
试图重新创建另一个库的功能,例如缓存,将导致无休止的痛苦和挫败感。如果你真的需要它,只需构建满足你即时需求的东西,而不要试图复制别人花费数月才开发出来的东西。
同行
在文章开头,我提到需要让同行参与进来。看看这个特定项目中的一些问题,同行可能会就正在开发的内容发表意见。当然,这只有在你拥有一个连贯的团队,而不是像独狼或孤立的开发人员那样,他们不了解正在开发的内容时才有效。至少在向需求方展示你的发现之前,让他们参与进来。
规格
理解业务需求和产品发展方向的愿景可以帮助你了解如何开发项目。理解需要Web服务来发展业务很重要,但知道我们唯一可预见的客户是基于Java的则更为重要。由于Web服务仅用于快速将数据导入系统,而没有真正的业务逻辑,因此应该考虑其他基于Java的技术。也可以讨论拥有2个Web服务的可能性。
我的POC
当我开始着手这个项目并看到所有当前的问题时,我决定在业余时间创建一个POC,目的是分享它并引发一些关于如何继续进行的讨论。在接下来的几天里,发生了一些事件,让我重新评估是否分享我的想法。我毫不怀疑它们是不受欢迎的,并会引起强烈反对。你也应该考虑这一点,以及是否要求POC;它不值得你丢掉工作,所以请运用你的判断力。
凭借这几天学到的知识,并且知道一些高层概念可以应用于其他现实场景;我决定继续进行POC,以充实我个人的知识。我的POC远远超出了我通常会产生的范围。我还融入了一些我一直听到、读到或感兴趣学习的想法。最后,我清理了代码,使其值得发布。
我设定了以下目标,以便提供与原始项目相同的环境。
- 自动生成新的业务对象,但无需解析EDMX文件的XML
- 后代可用性,如果需要
- DTO和EDMX对象之间的灵活数据转换
- 改进的搜索功能
- 减少IIS创建WSDL的时间
以下内容不予考虑
- 客户端缓存
- 互操作性
- 通过指标测试进行性能分析
关注点
EntityServiceTests
包含LambdaHelper
– 此类用于*PurchaseOrderHeaderTests.cs*,提供了一种消除通常用于类属性名称的string
的方法。Lambda表达式也称为流畅技术。- 生成的类提供对其他类的引用,创建表示对象的键的能力,以及查找不限制搜索条件的函数。
AdventureWorksEntityModel
– 是一个独立的DLL,用于通过Entity Framework与数据库通信。它包含*EntityObject.cs*,它为任何类型的对象提供基本的CRUD操作,以及搜索任何字段和检索相关数据的功能。- Web服务仅包含4个CRUD方法。这将有助于WSDL的重新生成。
ServerRepository
基于泛型,允许未来的类工作。AdventureWorksModel
包含一个用于映射的文件夹。这些类负责通过开源项目AutoMapper在EF模型和自定义模型之间转换数据。我应该指出,我使用的是该项目的基本形式。有关更多信息,请参阅网站。- 使用我基于Microsoft框架创建的库执行“解析Entity Framework EDMX文件”。
- 代码生成使用Microsoft T4技术完成,该技术内置于Visual Studio 2008/2010中,并附带附加库“T4 Toolbox”。更多信息可以在以下网站找到
Using the Code
安装T4 Toolbox后,打开解决方案,生成EdmxLibrary
,然后修改“代码生成”项目中*EdmxLibrary.dll*的路径。每当您保存*Driver.tt*文件或右键单击它并选择“Run Custom Tool”时,生成器就会接管并生成所有模型和映射类。然后可以将这些文件复制到AdventureWorksModel
中使用。如果您不想安装T4 Toolbox,我将生成的代码留在了目录中供您使用。
可以将文件直接输出到项目,但我选择不这样做。T4 Toolkit会在创建新文件之前删除它创建的所有内容。如果您将自定义代码放入类的Shell中,这将会引起问题。如果你想要这个功能,那么我建议根据需要手动创建Shell。此外,在生成文件后,Visual Studio会一直锁定*EdmxLibrary.dll*,从而阻止其再次编译。出于这个原因,我选择在“Configuration Manager”中默认将其从构建过程中删除。
此时,您可以构建解决方案,运行提供的单元测试用例,并逐步调试代码以查看有趣的点。
我应该指出,这个项目始于几年前,我后来忘记了我生产的一些东西。我已将其更新为Visual Studio 2010,将测试移至Microsoft Test而不是NUnit,并验证了通用功能。我认为这段代码是我一直想写的文章的重要组成部分。
最终想法
我希望我能够提供一些关于进行概念验证 (POC) 的优势的见解,并展示各种技术中的一些实际示例,并向您敞开心扉探索构建软件的新选择?通过探索和构建,我相信你可以成为一名更好的开发者。
希望你的下一次冒险是愉快的。