基于ASP.NET MVC框架开发Web论坛应用程序


  我想通过本系列文章从头到尾构建一个 完全的ASP.NET MVC论坛 利用程序,最终的 目标是探讨和推进 使用ASP.NET MVC框架构建 利用程序的最佳 实际 。

   1、 简介

   在本篇中,我想先从全局方面介绍一下论坛 利用程序的总体 指标 。在本篇中,我将 探讨一下幸免代码坏滋味的主要性,还将 探讨如何利用软件设计 准则和模式来协助你编写 合适 将来转变的富有弹性的代码 。最终,我还将论证一下为何我 取舍 使用测试驱动开发 模式构建本系列文章中的论坛 利用程序 。

   2、 什么样的软件是好的软件

   我不想仅仅为了构建论坛 利用程序而任意构建此论坛 利用程序 。我的 指标是尽可能构建最棒的论坛 利用程序 。

  这个 指标马上激发这样一个问题:什么样的软件是好的软件?是什么招致一个 利用程序比另一个 利用程序更好一些或更差一些呢?在事先没有一个关于“好软件”的定义之前,我 无奈申明我构建了一个 圆满的论坛 利用程序 。

   因此,下面是我关于“好软件”的定义 。

   3、 好软件是设计得易于 批改的软件

   存在多种缘由可能需求你转变软件:

  1)你可能需求在一个现有软件上增加新的 特色

  2)你可能需求 批改一个现有软件中的 舛误

  3)你可能需求优化现有软件

  4)你可能需求改良现有软件的设计

   普通说来,设计 蹩脚的软件是难于转变的 。有些软件设计得如此 蹩脚, 以致于每个人都胆怯碰一碰它 。我们大家应该都 使用过设计得 蹩脚的软件 。当软件不好时,你很 盼望它 索性走开;甚至假如有机会的话,你可能想从头开始再一次编写这款软件 。

   4、 幸免代码坏滋味

   Robert和Micah Martin把 蹩脚的软件 部分 形容为代码坏滋味 。下列代码坏滋味 象征着此软件的书写是相当 蹩脚的:

  1)僵化性(Rigidity)—僵化的软件是这样的软件,当你在某个位置作一 改变时即要求对系统作出相应的一系列的更改 。

  2) 懦弱性(Fragility)— 懦弱的软件是这样的软件,你在某个位置作一 改变时即打断另外多处的 畸形运行 。

  3) 毋庸要的复杂性— 毋庸要的复杂软件是指 适度设计的软件,其 目标是为了 解决任何可能的转变 。

  4) 毋庸要的 反复— 毋庸要的 反复软件中包括大量的 反复性代码 。

  5) 艰涩性— 艰涩的软件是指难于 了解的软件 。

   【 留神】上述这些代码滋味在Micah和Robert Martin的 驰名《Agile Principles,Patterns,and Practices in C#》中得到 充足的 形容 。在此,强烈 提议读者读一下这本书 。

   留神,上述这些代码滋味都与全部的代码转变 有关联 。每一个这些代码滋味都将阻碍代码的转变 。

   5、 软件设计 准则

   遵照良好的软件设计 准则,将有助于编写软件易于适应 将来更改的软件 。软件设计 准则有若干,也不尽 雷同 。例如,Cunningham和Cunningham Wiki 形容面向对象设计的11个 准则:

  http://c2.com/cgi/wiki?PrinciplesOfObjectOrientedDesign 。

   其中提到的面向对象设计的前五个 准则与Robert Martin及他的儿子Micah Martin编著的《Agile Principles,Patterns,and Practices in C#》中所主张的软件设计 准则是 统一的 。此外,Robert Martin还在Object Mentor开发的博客上 探讨了这些 准则:

  http://www.objectmentor.com/resources/publishedArticles.html 。

   此外,我还发现有另外两本书中也提供了有关软件设计 准则的极其有用的信息 。第一本是Eric Freeman,Elisabeth Freeman, Kathy Sierra, Bert Bates编著的《Head First Design Patterns》;第二本是Brett McLaughlin,Gary Pollice和David West编著的《Head First Object-Oriented Analysis and Design》 。 只管这些书所 探讨的 准则与Robert Martin的提法并不十分 雷同,然而它们却十分相近 。

   不过 实在的状况是,上述全部这些针对软件设计 准则铺开 探讨的资源都源自Robert Martin的工作 。Robert Martin并不是全部 准则的 创造者,然而他确实是第一个把这些 准则收集到一同的人 。下面列出这些软件设计 准则:

  SRP—单一责任 准则

  OCP—开关 准则

  LSP—Liskov替换 准则

  ISP—接口隔离 准则

  DIP—依赖倒置 准则

  上述这个 准则的 集中正好对应于缩略词SOLID 。

   下面的软件设计 准则列表来自于《Head First Design Patterns》一书:

  封装 变迁

  多用组合少用继承

  基于接口而不是基于实现编程

  在交互的对象间 奋力实现松耦合

  类应该为了 扩大而开放,然而为了 批改而关闭

  依赖于 形象,而不要依赖于具体类

  仅仅对你的朋友交谈

  不调用我,我们会调用你

  一个类应该仅有一个转变的理由

   固然,上述 准则中间也存在许多的重叠之处 。例如,“单一责任” 准则与后面的“一个类应该仅有一个转变的理由”这一 准则是相 统一的 。然而,它们所强调的重点还是有所不同 。更多的细节在此不便赘述 。

  全部这些设计 准则的真正动机在于, 奋力构建出 可以适应 变迁的软件 。上述 准则分别关于不同的 准则进行相应的 阐述,最终 目标也不过是为了 缔造出 可以经得起 工夫测试的软件 。

  6、 软件设计模式

   软件设计模式 形容的是 利用软件设计 准则所遵照的策略的问题 。换句话说,一个软件设计 准则是一个好的 思维,而一个软件设计模式是你用于实现这种好的 思维的工具 。

   软件设计模式的 思维最初源于书籍《Design Patterns: Elements of Reusable Object-Oriented Software》 。正是这本书为其它许多 形容软件设计模式书的创作带去灵感 。

   例如,另一本书《The Head First Design Pattern》就以一种更易于 了解的 模式向人们介绍了GOF所著的书(即上面的那本《Design Patterns: Elements of Reusable Object-Oriented Software》)中所引入的设计模式 。这本书中总共 详尽介绍了下列14种软件设计模式:

  Strategy

  Observer

  Decorator

  Factory

  Singleton

  Command

  Adaptor

  Fa?ade

  Template

  Iterator

  Composite

  State

  Proxy

  Compound

   另一本在软件设计模式方面较有影响的书是Martin Fowler的《Patterns of Enterprise Application Architecture》 。这本书还 占有一个公司网站,其中列举了本书中所介绍的模式 。此网站的网址是:http://www.martinfowler.com/eaaCatalog/ 。

   软件设计模式提供应你依照模式的 模式构建你的代码,从而使之更富于适应 将来的弹性 批改 。例如,当构建本文中的论坛 利用程序时,我们就 使用了一种名字为Repository的软件设计模式进行设计 。Eric Evans,在他的 著述《Domain-Driven Design》中这样 形容Repository模式:

   一个REPOSITORY把某 品种型的全部对象 形容为一个概念的 集中(通常是 模仿的) 。其行为 类似于一个 集中,然而 存在更 详尽的 支撑 查问的 威力 。于是, 相符相应类型的对象 可以被增加或删除,而位于此REPOSITORY背后的系统则 可以从数据库中增加或删除它们 。

   依据Evans的解释,Repository模式的一个主要的 长处是,它 可以协助你实现“ 利用程序和域设计与存储技术,多种数据库策略,甚至是多个数据源中间的解耦 。”换句话说,Repository模式 可以使你的 利用程序免于因数据库 拜访 模式的不同而再一次加以转变 。

  为了使我们的论坛 利用程序从某一种特定的存储技术中独立出去,我们将在系统中引入上述Repository模式 。 因此,最终的此论坛 利用程序的设计将 可以 支撑我们 可以在不同的数据 拜访技术(例如LINQ to SQL,Entity Framework或NHibernate)中间切换 。

   7、 测试驱动开发

   我打算 使用测试驱动开发 准则构建本文中的MVC论坛 利用程序 。更具体地说是,在我编写任何 利用程序代码之前,我将首先编写一个 利用程序代码的单元测试 。

   测试驱动开发将会基于下列原由于你带来更高 品质的代码:

  (1)为你的代码编写测试 可以提供应你一个适应于 将来可能转变的安全网 。

  (2)为你的代码编写测试迫使你书写松耦合的代码 。

  (3)在正式书写你的代码前为你的代码编写测试将迫使你从一个消费者的角度来 视察自己书写的代码 。

   让我们更 详尽地 综合上述每种 特色的 长处 。

   首先,单元测试提供你一个适应于 将来可能转变的安全网 。这是Michael Feathers在他的 著述《Working Effectively with Legacy Code》一再强调的一个观点 。事实上,他把遗留代码定义为“ 方便地编码而不进行测试” 。

   当你的 利用程序代码被单元测试所 遮蔽时,你 可以 批改该代码而 毋庸 担心此 改变会你的代码既有的 性能 。单元测试有助于使你的代码进行更安全的重构 。假如你 可以重构,那么,你 可以 使用软件设计模式 批改你的代码,这将产生更好的适应 将来 批改的代码 。

   其次,遵照测试驱动开发将迫使你 使用一种特定的 模式书写代码 。可测试的代码将趋于招致松耦合的代码 。单元测试 可以在各自孤立的代码单元中执行一个测试 。为了构建你的 利用程序以便使之可测试,你需求 使用一种可孤立的组件 模式来构建 利用程序 。

   一个类与另一个类中间是松耦合的是指,当你转变第一个类时 毋庸转变另一个类 。测试驱动开发 时常迫使你编写松耦合的代码,由于松耦合代码是经得起转变的 。

   最终,依照测试先行的 模式书写代码将迫使你从一个消费者的角度来 视察自己书写的代码 。通过首先编写测试的 模式书写代码,会使你站在一个 将来的有可能 使用你的代码的开发者的角度进行工作 。既然编写测试迫使你考量另一个开发者( 兴许是 将来的你自己)如何 使用你的代码,那么,你最终编写的代码应该是设计得更好的代码 。

   8、 莫图眼前之利益 更宜立足于 深远

   使用测试驱动开发 准则构建软件在软件开发之初要求开发者付出更多的 奋力 。 只管编写测试需求 花费 定然的 工夫;然而,其 思维是,最初构建单元测试所要求付出的 奋力将会在 将来 获得 丰富的回报 。

   存在两种 模式 可以使你成为一名开发者 。你 可以成长为一个牛仔,也有可能成长为一个工匠 。一个牛仔 可以马上开始编码 。也便是说,一个牛仔 可以以很快的速度构建一个软件 利用程序 。然而,作为一个牛仔,其问题在于软件必须要进行长 工夫的 保护 。

  一个工匠则是很有 忍耐性的 。一个工匠总会精雕细琢地开发一款软件 。一个工匠总是十分 细心地构建单元测试,并使之涵盖一个 利用程序中全部的代码 。 因此,一个工匠要 花费更长的 工夫 威力 缔造 顺利一款 利用程序 。然而,此 利用程序在 缔造后,却是易于后期的 保护—更易于 批改 舛误且更易于把新 特色增加到 利用程序中 。

   9、 总结

   总之,我们的最终 指标是构建一个MVC论坛 利用程序,此程序 可以经得起长 工夫的测试 。它应该是不只现在良好地工作,还应该在 将来 接续工作— 即便是当有人需求对该 利用程序进行更改之时 。

  我想利用微软ASP.NET MVC框架开发此论坛 利用程序 。缘由在于,这个框架 可以使我更方便地编写程序的测试代码 。而另一方面,ASP.NET MVC框架 本身就从设计之初提供了对测试驱动开发的最 忠诚的 支撑 。