返回首页

! 简介
本文包含世界s最琐碎无用的Windows Workflow Foundation(WF)的应用程序,以及一些WF本身的背景。该软件的怪胎秀的目的是揭露WF新人如何与NET 3.0这个令人​​兴奋的新的部分开始的基本知识。它没有得到任何复杂的情况下,当然不包含任何WF的最佳做法。它只是告诉你如何把一个最小的WF的应用程序。如果你有更现实的需要和要求,您可以使用此代码作为一个真正的发展的出发地点。
,我会承认这里(纽约市),现在(2006年11月),我绝不是一个WF的专家。我m关于永丰,真的非常兴奋,并一直在阅读关于它在我的空闲时间玩了。本文纯粹是书面的兴奋的技术,所以我希望,兴奋眼前一亮,有助于让你兴奋过。
在这篇文章中所示的应用程序是一个优秀图书开始使用演示应用程序的突变绋基要的Windows Workflow Foundation的?佛法舒克拉和鲍勃施密特。我极力推荐这本书,如果你想获得认真地学习WF。您可能还需要检查MSDN上由Don Box和佛法舒克拉。
,跆拳道是WF的?
在我们进入建设WF应用程序,让锟s花点时间掌握背后WF的总体思路。 WF Windows Workflow Foundation的代表。这是一个子系统,它提供了一个用于创建和执行基于工作流的应用程序运行时的。NET Framework 3.0。锟s漂亮的营销潺潺,但究竟是什么意思?好问题??/ P>
从一个非常高层次的角度来看,WF允许您创建程序可以保存到后备存储时,他们无效,然后在必要时恢复。你可以声明一个基于XML的语言被称为扩展应用程序标记语言(XAML)的总体方案流和负载/您的XAML工作流在运行时执行。表示你的应用程序锟s在一种标记语言的一般逻辑流程简化了开发过程很大,特别是因为它在创建软件的图形设计工具的使用打开了新的可能性。我为什么会使用WF?
许多应用程序的性质反应。他们围坐在一起的时间无限期等待期间发生的事情(也许是在某个目录中创建的文件)。当外部刺激到应用程序获取忙于处理传入的数据。与这种常见的情况问题是性能和可扩展性有很大影响的事实,而应用程序是等待外部输入,它消耗的处理时间从任何线程上运行。
WF提供了一个解决该问题。由于在WF工作流作为一个对象树表示,支持序列化/反序列化这些对象,WF的工作流内置支持保存到从数据库加载。我不锟t的意思,只是由应用程序操纵的数据保存,我的意思是,program本身是保存??。
应用程序的状态是有效立蔷薇??和低温冷冻投入,可以这么说。当谈到时间,恢复工作流处理(即外部刺激到达)锟绔蔷薇??工作流程是解冻,并继续正常执行。请记住,工作流可以在不同的计算机恢复,千里之遥,从那里被冻结,15个月后。这在性能和可扩展性方面带来了巨大的收益,因为工作流程是不绑定到一个特定的线程,进程,甚至电脑。
锟s我锟m要对WF提供的介绍材料。我没锟t解释几乎所有的WF是所有关于。如果你有兴趣在WF的更彻底,更周到的解释,我建议你读了这本书前面提到的(锟绋基要的Windows Workflow Foundation的??现在,让我们锟s发挥一些WF代码
世界锟s愚蠢的WF的应用
应用程序的I锟m这里呈现给你问他/她的名字的用户,等待用户键入它在,然后打印锟绐ello,用户名!??到控制台。很明显,这个应用程序是唯一感兴趣的,因为它使用Windows Workflow Foundation来执行它的魔力。我试图保持尽可能简单和最小的WF的使用,只是让锟s容易看到如何设立一个应用程序使用WF的。
有参与此应用程序的两个组件:FirstWFLibrary.DLL??该程序集包含用于执行打印输出到控制台任务,并获得用户锟s名称的自定义WF活动。FirstWFApp.EXE??这个大会是一个控制台应用程序加载WF WorkflowRuntime的活动,并提出在FirstWFLibrary使用。
的两个组件中的每一个都包含两片的拼图:
FirstWFLibrary.DLL自定义活动??在WF工作流工作的基本单位是一个"活动"。 WF的应用程序中的所有自定义活动Activity基类派生并重写其受保护的执行方法,以提供自己的执行逻辑。命名空间映射??为了能够在XAML中使用自定义活动,我们需要提供一种方式来告诉XAML分析器在这些阶级存在的命名空间(S)。这是通过应用属性大会,我们稍后将看到的。
FirstWFApp.EXE工作流宣言"吗?在这个应用程序?工作流程需要阅读的使用者锟s名称和显示回给他/她是在XAML中表示。在本次大会的XAML文件使用FirstWFLibrary大会宣布自定义活动。请注意,它不要求工作流在XAML中声明。宣布他们在其他格式,如C#代码,这是完全可能。我选择了在XAML中的工作流程,因为它锟s更有趣的方式来表达对这个应用程序。 :)工作流运行时主机??的最后一块拼图是一个类加载WF运行时,配置它,然后告诉它开始运行。在此应用程序的EntryPoint类需要护理这项工作。
本文的其余部分检查上面列出的应用程序的每个部分。自定义活动
如前所述,此演示应用程序有三个任务来执行。首先,它必须显示在控制台窗口中,要求他/她的名字的用户的消息。然后,它必须等待用户输入他们的姓名,然后按Enter。最后,它显示另一条消息给用户,其中包括他们的名字。
这些任务都表示为一个单独的活动派生类。这些类的实例将执行实际工作所必需的程序执行。首先,让我们锟s初始提示是如何显示到控制台/ / /公升; summarygt;/ / /要求用户提供他们的姓名。/ / / 这个类是完美示范了如何创建一个可以包含在WF工作流的活动。它从System.Workflow.ComponentModel.Activity类继承并覆盖Execute方法来提供自定义活动执行逻辑。由于这项活动是逻辑上完成后,写一条消息到控制台的,它返回ActivityExecutionStatus.Closed告知这是WF运行时。
你可能会奇怪,为什么一个活动会从Execute方法返回,如果还没有完成执行。还记得前面对我提到,WF的工作流可以passivated??,并存储在数据库中,直到它需要继续执行?那么,活动锟sExecute方法将返回ActivityExecutionStatus.Executing如果它不能完成直到最终到达外部输入。
事实上,世界下一步锟s愚蠢的WF的应用需要一个时间的推移,才可以继续处理无限期。这可能需要用户3秒或3天类型在他/她的名字。在这段时间内的工作流程将没有处理。如果这是一个不太愚蠢WF的应用程序,我们可能会决定钝化的工作流程,直到用户名终于来临,在这一点,我们将恢复工作流程,让它继续。我们锟r个人不这样做,在这里,但这个活动显示如何设置一个bookmark使WF运行时可以通知活动时,输入已经抵达
/ / /公升;??summarygt;/ / /代表阅读的文本一行从控制台的活动。/ / / 在ReadConsoleLine锟sExecute方法"锟bookmark??是建立和方法立即返回控制权交还给WF运行时。但是,它的回报??代码>执行??让WF运行时知道它不应该去处理任何其他活动。当用户输入的最后到达,ReadConsoleLine锟sProcessQueueItemAvailable和CloseActivity事件处理方法将被调用。这些方法的第一个用户锟s名称存储在一个私有变量。另一种方法是清理和关闭的活动,使WF运行时可以继续处理其他活动。
最后一个活动是负责打印出问候用户与他/她的名字,。这个活动有一个依赖项属性称为用户名。正如我们稍后将看到,这个属性绑定到ReadConsoleLine活动收到的输入值。数据绑定是建立在这些对象的XAML声明。我们l升该很快,但现在让我们锟s看到GreetUser活动/ / /公升。summarygt;/ / /打印用户的问候。/ / / 为了使用我们的自定义在XAML中的活动,我们需要提供的XAML解析器的方式来知道什么CLR命名空间的类居住,因为XAML是一种XML语言,我们需要提供关联的CLR任意XML命名空间(基本上,一个URI)命名空间。这是可以做到在任何项目中的代码文件,但我只是为了传统的AssemblyInfo.cs创建。这里s该文件的内容:使用System.Workflow.ComponentModel.Serialization;/ /这个属性使得它可以在XAML中使用自定义活动。[大会:XmlnsDefinition(quot; http://FirstWFLibraryquot;,"FirstWFLibraryquot;)]工作流宣言"
现在,我们需要执行我们的程序逻辑的自定义活动,其命名空间映射,我们可以创建这些类型的实例。在本演示中,我们将在XAML中创建它们。看作只是一个通用的对象实例化的标记语言XAML的。它允许你配置的对象和表达它们之间的层次关系,很容易。
这里是世界的XAML声明锟s愚蠢的工作流程:
LT; WF:SequenceActivity XMLNS ="; http://FirstWFLibraryquot"; 的xmlns:X ="; http://schemas.microsoft.com/winfx/2006/xamlquot"; XMLNS:WF ="; http://schemas.microsoft.com/winfx/2006/xaml/workflowquot"; GT; 0; LT; PromptForUserName / GT; LT; ReadConsoleLine x:名称="; getUserNamequot / GT; LT; GreetUser用户名="{WF:ActivityBind名称= getUserName,路径的inputText}"/ GT;LT; / WF:SequenceActivitygt;
在工作流的根活动是一个SequenceActivity对象,这是在WF框架提供了一个类。这是一个CompositeActivity派生类,在他们被声明的顺序执行其子活动,只执行一个子活动完成后,以前的儿童活动。
根活动中包含的XML命名空间映射。默认XML命名空间映射到在上一节中的文章XmlnsDefinition属性指定的URI。这使我们可以参考我们的自定义活动类型没有任何命名空间前缀。
的另一个兴趣点是ReadConsoleLine GreetUser活动之间的关系。后者的UserName属性绑定到前的inputText财产。这种绑定允许从一个活动转移到另一个控制台中键入的文本。一个属性,是一项有约束力的的目标,它必须是一个"依赖项属性。"正如我们在"自定义活动"一节中所看到的,是多一点,比只是一个普通的属性创建一个依赖项属性的代码,但相依性属性,可以在使用方式,不能正常属性。你可以阅读有关SDK中的这些差异,如果你关心。工作流运行时主机
您可以承载多种方式WF运行时,但这个演示只是使用一个普通的香草控制台应用程序。有几个步骤,您必须遵循以获得WF运行时,运行在您的AppDomain。下面的方法是世界s愚蠢的WF的应用程序主机WF运行时(这种方法,当然是在一个类中,):
公共静态无效的主要(){ / /创建一个WorkflowRuntime实例,将执行和协调 / /我们的工作流程的所有活动。 (WorkflowRuntime的WorkflowRuntime的新的WorkflowRuntime()) {  0;/ /告诉工作流运行时,在哪里可以找到我们的自定义活动类型。& #160; TypeProvider typeProvider =新TypeProvider(WorkflowRuntime的); typeProvider.AddAssemblyReference("FirstWFLibrary.dllquot;); workflowRuntime.AddService(typeProvider);  ; / /激活工作流运行时。 workflowRuntime.StartRuntime(); / /加载的XAML文件,其中包含了我们的简单的工作流的宣言 / /创建它的一个实例。一旦它被加载,启动工作流 / /所以,在它的活动会执行。 WorkflowInstance workflowInstance; (XmlTextReader的XmlReader的= 新的XmlTextReader的(@ quot; .. \ .. \ HelloUserWorkflow.xamlquot;)) { workflowInstance = workflowRuntime.CreateWorkflow(XmlReader的); workflowInstance.Start();  60;} / / ReadConsoleLine活动使用quot; bookmarkquot;表明,它必须 / /等待外部输入,才可以完成。在这种情况下, / /外部输入到控制台窗口中输入用户的名称。 字符串的用户名=(); workflowInstance.EnqueueItem("; getUserNamequot",用户名,NULL,NULL); / /暂停,使这里的工作流程可以显示的问候语。 (); / /拆毁所有的工作流程服务和运行时。 / /(这可能是多余的,因为"运行"对象是在 / /使用的块)。 workflowRuntime.StopRuntime(); }}
我锟m不会解释该方法行线,因为它的评论不够好。一点利益,我会提的是,一旦Work​​flowInstance启动时,该方法然后调用Console.ReadLine用户锟s名称。一旦检索的名称是,它摆上锟绞etUserName??流队列R​​eadConsoleLine活动,这是创建的。这是一个提供的工作流程,使其恢复处理外部输入的例子。一旦用户s名称到工作流队列,ReadConsoleLine活动将有回调方法调用,它可以执行完。结论
本文展示了如何创建一个应用程序使用Windows Workflow Foundation的。希望它让你感觉像世界锟s愚蠢的WF的应用值得它的名字,也是您了解WF的基本知识,以及如何在应用程序中使用它。
正如我前面提到的,这个应用程序没有在所有需要使用WF的权力,但它确实传达所涉及的基本概念。它显示了如何WF工作流的活动树,如何将这些活动可以使用锟bookmarks的概念??表示应继续处理外部刺激发生后,工作流可以在XAML中声明,以及如何主机WF的工作流运行时。一路上,我提到WF的工作流可以钝化和恢复,它提供了一个强有力的手段改善应用程序的锟s可扩展性和性能。

回答

评论会员:sohair崎 时间:2011/12/07
请我开发一个基于Web的图书流通系统
我想用窗口的工作流程顺序,对检查出的书
部分子ID和书ID可以输入参数,我如何可以读取和更新的数据库,在Windows工作流
我应使用seqential工作流程库或Web servic

我使用Visual Studio 2005的请我在哪里可以找到有关顺序工作流程和asp.net的信息,使工作流读取和更新图书流通数据库

感谢
评论会员:霍华德理查兹 时间:2011/12/07
一个很好的文章,介绍工作流程。不过,我可以添加一个忠告有关MS WF任何CPians

我开始看工作流程去年,当第一个细节开始出现,然后3 / 4月再次测试版出来的时候。
我是一个大风扇在一般意义上的工作流程,但与永丰打三个月后,我放弃了。
我的警告是:WF(工作流)是复杂的。非常非常复杂。
由于非常复杂的功能(如暂停,多线程,依赖属性等)的编程模型和工作的理解是极其复杂的。
除非你是非常精通。NET中,我会建议您避开。简单的例子,通常隐藏前夕在于,当试图做一些简单的真正复杂的工作流程。

这样的一个例子是在运行的工作流实例发送一个简单的信息从一个应用程序(无论是ASP或WinForms)所涉及的工作。看到这篇文章(3点),说明所涉及的工作



当你认为应用和工作流(而全,自足的工作流程)之间的相互作用是关键,那么你会看到多少工作(一)参与了解这一切,(b)在什么实际的编码。
我还发现,一些简单的事情,你可能期望有没有直接的支持,如果您尝试子类永丰你进入境界的超级复杂。
例如,您可能希望它的生命周期的某些阶段,一个人被分配一个工作流程。服务台WF的例子会是一个很好的例子。 WF的叶的开发,因为几乎是无限多的方式来做到这一点。记住,有没有"查询"功能的工作流,可以说

从workflowinstances'SELECT * [someproperty] = [somevalue]'

因此,合乎逻辑的做法是建立一个数据库表来跟踪我创建的工作流。我想子类StateActivity然后分配工作流程,并添加代码,将更新数据库中说谁的任务被分配到。我的上帝,是复杂的,最终我放弃了。子类的代码是不是能够看到工作流实例的依赖属性!


"霍华德
评论会员:bluerocketgo 时间:2011/12/07
只要我两毛钱。许多我所看到的例子上迄今为止关于永丰互联网正在试图使用一个试图用坦克杀死一只蚂蚁。 WF是一个应用层次的概念 - 微软已经向前迈进了一步,并体现在一个框架 - 为开发人员提供一个概念性的(而且在某些方面是有形的),而无需重新创建框架构建应用程序的方式。

我认为有太多的情况下,我们的许多开发人员(包括我自己)陷入炒作背后的技术,不给过多考虑了任务。
技术的适用性
熊与WF的心灵 - 虽然它有很高的学习曲线,它应该不会阻止你,如果你心目中的任务是适合它 - 其实你会把时间可以多值得努力。
评论会员:bluerocketgo 时间:2011/12/07
只要我两毛钱。许多我所看到的例子上迄今为止关于永丰互联网正在试图使用一个试图用坦克杀死一只蚂蚁。 WF是一个应用层次的概念 - 微软已经向前迈进了一步,并体现在一个框架 - 为开发人员提供一个概念性的(而且在某些方面是有形的),而无需重新创建框架构建应用程序的方式。

我认为有太多的情况下,我们的许多开发人员(包括我自己)陷入炒作背后的技术,不给过多考虑了任务。
技术的适用性
熊与WF的心灵 - 虽然它有很高的学习曲线,它应该不会阻止你,如果你心目中的任务是适合它 - 其实你会把时间可以多值得努力。
评论会员:James_Lin 时间:2011/12/07
,我认为微软的工作流的版本是很难使用
使用Oracle的BPEL(工作流程)后,我发现了它的方法更容易使用。你的设计和部署到应用服务器,不需要编码。微软需要一个应用服务器,可以做同样的。
评论会员:cesar_boucas 时间:2011/12/07
以看看在BizTalk。
WF是为开发人员。

"去!"
评论会员:马克西姆Astafev 时间:2011/12/07
James_Lin写道:微软需要一个应用服务器,可以做同样的。

我觉得...工作流可以在AppDomain中运行,而不是把某种数据库中的所有DLL /代码和数据库运行UR代码!
"意见"是没有权利也没有错,我不能改变你的意见,我可以,但是,改变什么影响你的意见。" - 大卫克罗
没关系 - 我自己的愚蠢,是每一个"问题"的根源 - 混合欢呼声中,
{A}
VC论坛的质量保证: -
支持小组
评论会员:乔什-史密斯 时间:2011/12/07
您好!乔希

在您的文章的开头,你说,工作流的任务,这是没有绑定到任何特定的线程,进程甚至计算机。不幸的是,我想念你的例子在这个问题。您的活动,生活在一个过程中,我不能仅仅停留和在另一台机器上重新启动。

你介意给简要介绍了如何设计一个工作流程,可满足这一要求。如何在这种情况下开始工作流运行时呢?还是会在一个新的文章,摘要的结果呢?
我想开始,收集一些数据,并暂停一台机器上,然后通过电子邮件发送和在收件人的机器恢复,应用程序会产生一个真正的WOW效应,并强调的WF的想法。
想想下面的工作流程的一个例子:
1。你让用户把3个问题。
2。用户冻结申请,并通过电子邮件发送给他的朋友
3。他的朋友恢复的工作流程和看到的问题。他回答其中2个,冻结工作流程,并将其发送回
4。用户恢复工作流程和看到的统计数据(即3回答问题2)

如何创建业务逻辑的午餐启动使用WF()?在这里,你甚至会线使用的工作流基础(WF)使用的Windows Communication Foundation(WCF)的

我真的很感激,如果你可以扩展过程中的独立性问题,你的文章。

总之感谢很多为一个很好的介绍了这个有趣的技术。

评论会员:马克西姆Astafev 时间:2011/12/07
您好,马克西姆

我很高兴我的文章激起你的兴趣在WF。反馈。

我只提及事实WF应用程序线程和进程作为"背景资料"有关的技术敏捷。我的示例应用程序过于简单化,让钝化和恢复显示。包括将击败的目的,它被"世界上最愚蠢的WF的应用。"

工作流钝化和(反)序列的内在支持的主题是过于涉及在留言板的评论解释。正如你所提到的,它需要一个单独的文章。幸运的是,迪诺埃斯波西托已经 {S0}

享受!

乔希:

评论会员:peterchen 时间:2011/12/07
你是右。由于你的文章我会仔细看看有这项技术。
所以,再一次感谢了很多有价值的文章和链接。多数民众赞成正是我想知道什么。
评论会员:乔什-史密斯 时间:2011/12/07
这是一个很好的引进使用世界自然基金会 - 谢谢你

我仍然乌苏雷约的动机:它似乎更像一个ecercise你必须做什么来保存应用程序的状态(在托管环境中或许可以得到解决通用 - 但也许出奇的大快照)




!开发人员,开发人员,开发人员,开发人员,开发人员,开发人员,Velopers,Develprs,开发
我们是一个搞砸了大功能失调性精神病幸福的家庭 - 一些更拧紧,别人更多的快乐,但每个人的精神病CP的联合风险投资的定义{ BR}
评论会员:peterchen 时间:2011/12/07
感谢peterchen。与创建一个新技术的介绍性文章的问题,例如应用程序已经足够简单,只是解释的基础,但它永远不会传达的广度和该技术的适用性。还有很多,以上只是我提出的东西的白表。它不仅仅是一种方法来保存应用程序的状态,它的设计和创建应用程序的一种方式。这是一个宣告您的应用程序的流量在一种标记语言,甚至特定于域的语言方式。这远远超过我在文章中解释,但我不想超载的文章,介绍"什么是WF的"材料。

乔希:

评论会员:乔什-史密斯 时间:2011/12/07
这是不打算批评你的文章,只是作为一般的观察。
(也许*提示永丰....){ BR什么可以做的一篇文章提示*}
你的文章肯定WF是一个想法,以及如何切实上手(这是海事组织最重要的部分)。我仍然不知道为什么我应该这样做 - 但是这部分是因为我是一个勒德

!开发人员,开发人员,开发人员,开发人员,开发人员,开发人员,Velopers,Develprs,开发
我们是一个搞砸了大功能失调性精神病幸福的家庭 - 一些更拧紧,别人更多的快乐,但每个人的精神病CP的联合风险投资的定义{ A7的BR} {}
评论会员:马克克利夫顿 时间:2011/12/07
peterchen写道:也许*提示提示*永丰....{ BR什么可以做的文章}
这将是一个有趣的文章,但我不是"有。"我仍然非常在WF初学者和与所涉及的概念拼杀。也许,如果我用WF的工作足够长的时间,我要创造一个这样的文章所必需的经验/角度。在那之前,我们能做的就是希望的人有经验/角度决定首先把它写! {S0}

乔希:

评论会员:乔什-史密斯 时间:2011/12/07
peterchen写道:"我仍然不知道为什么我应该做的

关于MS的工作流引擎的有趣的事情是,它保持状态,但它这样做在一个"过程"的背景下。因此,而不是代码的过程(如从工作秩序计费应收账款的步骤),您构建的工作流(图形,我想补充)。现在的工作流引擎管理工作流程的状态,所以你没有,也逻辑 - 决策点等,其中可以包括定时事件(例如,如果质量保证尚未批准的工作范围内
15天,找出原因)。
而最有趣的事情,我在MSDN事件永丰证明中所看到的是,你可以改变的工作流程,使所有的应用程序。现在,他们如何能做到这一点,如果你改变一些与工作流程的当前状态交互,我没有问这个问题。但它是非常有用的。但出于某种原因,微软认为会有很多独立软件开发商提供了大量的"工作流程片段"。想起我的Web服务和BPEL及类似的承诺 - 所有这些计算机彼此之间的沟通和服务。我个人认为微软是吸烟的东西时,他们认为我们将看到的工作流程片段。因为,总体上来看,工作流,它是专为您的业务流程。如何写出一些一般性的proceses,很好,我想你可以把一些可定制的模板,但我无法想象任何一个ISV的主要收入来源。

另一件事,有趣的是,它似乎WF可以不仅为"时间的业务流程",而且还作为一个简单的脚本工具使用。例如,我在我的Interacx系统中使用的工作流程仅仅作为一个共同的,可重复步骤的脚本机制,如加载视图,控件绑定到视图,创建一个沙箱,管理事务日志,处理用户事件等,我,认为WF是可扩展的,因此,例如,你可以写插件,增加了工作流程,再次我做我自己的系统的东西。我不这样做,我的系统是管理国家,所以它不是一个真正的业务流程的工作流引擎。
{S3}

马克
在CountryPeople百里香是出了名的不可能。 - DavidCrow
没有任何借口不评论你的代码。 - 约翰西蒙斯/取缔程序员
的人说,他们将重构自己的代码后,使"好"的不理解重构,也不是艺术和工艺编程。 - 乔什 - 史密斯

{S4}的
乔希:

{五}

马克


在CountryPeople百里香是出了名的不可能。 - DavidCrow
没有任何借口不评论你的代码。 - 约翰西蒙斯/取缔程序员
的人说,他们将重构自己的代码后,使"好"的不理解重构,也不是艺术和工艺编程。 - 乔什 - 史密斯





{七}


谢谢! {S0}

乔希:










{五}

{五}

马克
在CountryPeople百里香是出了名的不可能。 - DavidCrow
没有任何借口不评论你的代码。 - 约翰西蒙斯/取缔程序员
的人说,他们将重构自己的代码后,使"好"的不理解重构,也不是艺术和工艺编程。 - 乔什 - 史密斯

谢谢!


{S0}



乔希:

{五}

马克
在CountryPeople百里香是出了名的不可能。 - DavidCrow
没有任何借口不评论你的代码。 - 约翰西蒙斯/取缔程序员
的人说,他们将重构自己的代码后,使"好"的不理解重构,也不是艺术和工艺编程。 - 乔什 - 史密斯



{S4}的

乔希: