ASP.NET Routing介绍

开发 后端
这里介绍ASP.NET Routing中最令人摸不着头脑的设计-RouteBase类,下面你将看到微软是怎么搞笑的。

您觉得ASP.NET Routing中最令人摸不着头脑的设计是什么?我认为是RouteBase类:

  1. public abstract class RouteBase  
  2. {  
  3. protected RouteBase() { }  
  4. public abstract RouteData GetRouteData(HttpContextBase httpContext);  
  5. public abstract VirtualPathData GetVirtualPath(  
  6. RequestContext requestContext,  
  7. RouteValueDictionary values);  
  8. }  

它为什么是一个没有任何实现的抽象类,而不是一个接口(如下)?

  1. public interface IRoute  
  2. {  
  3. RouteData GetRouteData(HttpContextBase httpContext);  
  4. VirtualPathData GetVirtualPath(  
  5. RequestContext requestContext,  
  6. RouteValueDictionary values);  
  7. }  

这样做难道不更漂亮一些吗?这样代码中都可以使用IRoute类型,避免RouteBase这种令人反感的命名出现(个人感觉,不知道有没有同意的群众)。退一步说,命名上的“美感”是小事……但是抽象类在.NET平台中就产生了一个非常严重的限制:一个类无法继承多个基类。因此,在.NET平台上总是更倾向于使用接口,而不是抽象类。

但是接口里不可以有任何实现,那么可复用的功能又放在哪里比较合适呢?《Framework Design Guildlines》告诉我们:在一个类库中,***为接口定义一个默认实现,这样也是开发人员进行“扩展”的一个“参考”。也就是说,如果真有什么需要复用的实现,我们完全可以这么做:

  1. public abstract class RouteBase : IRoute  
  2. {   
  3. // reusable implementations  
  4. }  
  5.  
  6. public class Route : RouteBase  
  7. {  
  8. // concrete implementations  
  9. }  

事实上,.NET平台上有许多类库也遵循了这个做法。一个典型的做法便是ASP.NET AJAX框架的Extender模型:

  1. public interface IExtenderControl {   
  2. }  
  3.  
  4. public abstract class ExtenderControl : Control, IExtenderControl {   
  5. }  

甚至在ASP.NET AJAX Control Tookit项目中,还有更进一步的扩展:

  1. public abstract class ExtenderControlBase : ExtenderControl {   
  2. }  
  3.  
  4. public class AnimationExtenderControlBase : ExtenderControlBase {   
  5. }  
  6.  
  7. public class AutoCompleteExtender : AnimationExtenderControlBase {   
  8. }  

看来微软在项目团队内部推广《Framework Design Guidelines》还不够彻底。

在.NET平台下,一个没有任何实现的,纯粹的抽象类可谓有百害而无一利。我很怀疑写这段代码的人刚从C++切换到C#——但是ASP.NET Routing中其实也有接口(如IRouteConstraint),为什么作者自己没有意识到,也没有人提出不同意见呢?微软开发团队应该有着严格的Code Review过程,怎么会让这样的代码正式发布?要知道一个接口一旦公开,就不可以删除了。也就是说,微软很难弥补这个错误。

如果是方法名不好,或者职责有些不明确,这样还可以在旧方法上添加ObsoleteAttribute(这样编译器便会提示用户这个方法已经过期),并且将旧方法的调用委托给新的实现。例如:

  1. public abstract class CodeDomProvider : Component  
  2. {  
  3. [Obsolete(  
  4. "Callers should not use the ICodeCompiler interface and should  
  5. instead use the methods directly on the CodeDomProvider class.  
  6. Those inheriting from CodeDomProvider must still implement this  
  7. interface, and should exclude this warning or also obsolete this  
  8. method.")]  
  9. public abstract ICodeCompiler CreateCompiler();  
  10.  
  11. [Obsolete(  
  12. "Callers should not use the ICodeParser interface and should  
  13. instead use the methods directly on the CodeDomProvider class.  
  14. Those inheriting from CodeDomProvider must still implement this  
  15. interface, and should exclude this warning or also obsolete this  
  16. method.")]  
  17. public virtual ICodeParser CreateParser();  
  18.  
  19. ...  

可是,现在的问题是一个“类”,而这个类已经无处不在了,例如在RouteData中有一个属性Route,它便是RouteBase类型——如果将其修改为IRoute接口,那么至少也需要项目重新编译之后才能够“升级”。而作为一个公开类库,尤其是.NET这种成熟框架来说,应该做到“无痛”才对。

这次微软真搞笑了。以上介绍ASP.NET Routing。

原文出处博客园,作者赵劼

【编辑推荐】

  1. ASP.NET控件学习总结
  2. 有关ASP.NET MVC框架的一些基础知识
  3. 再谈ASP.NET缓存机制:开发效率与优化的平衡
  4. 如何避免ASP.NET缓存占用系统资源
  5. 点评一下ASP.NET的WEB控件
责任编辑:佚名 来源: 博客园
相关推荐

2009-07-21 15:11:14

ASP.NET Rou

2014-08-26 09:22:40

ASP.NET MVCRouting

2009-08-21 10:51:55

ASP.NET Rou解析URL

2009-03-12 10:42:38

RoutingIgnoreRouteASP.NET

2009-07-22 16:05:34

ASP.NET AJA

2009-07-29 17:23:17

ASP.NET表单

2009-07-29 10:02:49

ASP.NET上传

2009-07-21 10:40:36

ASP.NET Pro

2009-07-23 14:17:41

2009-07-29 17:26:39

ASP.NET页面

2009-09-10 14:02:08

LINQ ASP.NE

2009-07-27 17:00:29

ASP.NET主机

2009-07-20 16:12:21

ASP.NET Fra

2009-07-29 09:14:36

ASP.NET网站

2009-10-15 14:50:34

ASP.NET Rou

2009-08-19 11:39:38

ASP.NET Rou

2009-10-26 15:55:43

URL Routing

2009-08-03 17:35:07

ASP.NET WebASP.NET编程工具

2009-03-09 13:46:31

RoutingWebASP.NET

2009-07-29 10:35:51

ASP.NET缓存
点赞
收藏

51CTO技术栈公众号