绑定子类的泛型基类.docx

  1. 1、本文档共5页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
绑定子类的泛型基类,反模式? 这次总结一个个人认为的反模式: 绑定子类的泛型层基类”,这个模式在一些著名的框架中 也见到过,如果 CSLA、BlogEngine 。我自己在原来的写的框架中,也用到过。 当然了,个人认为是反模式,各们同仁并不一定这样认为,仁者见仁,智者见智了。不过我 好几次都是受尽折磨,所以决定写出来给大家分享下心得。 模式介绍 层基类是MF提出的一个基本模式,详见:《 Layer Supertype 》。这种模式在经典的 层次型架构设计的实现中,是极其重要的。我相信, 大家一般在做三层架构时,不可能不给 出基类的。至少我没见过。:) ?NET2.0推出后,带来了新的语言特性:《 泛型》。它实现了类型的运行时多态,是一种 强大的语言特性。 今天要说的主题正是基于 LayerSupertype ,并结合了泛型技术而实现的,同样,它还有 一个重要的约定: 泛型的类型参数必须是最终的子类 。看如下一个例子: 1 public abstract class EntityBaseT 01 where T : En tityBaseT 02 { 03 public int Id { get; set; } 04 //sth else important 05 } 06 public class User : EntityBaseUser 07 { 08 public string Name { get; set; } 09 } 10 public class Article : EntityBaseArticle 11 { 12 public string Title { get; set; } 13} En tityBase 作为所有实体类的基类,提供了统一的实体模板、约定和一些通用的基础实现。 基于这个基类的代码重用,使得子类的代码非常简单。这里和普通继承、普通泛型的不同点 在于父类在运行时绑定了具体子类的类型。 设计原理 为什么要这样设计?基类为什么不直接使用非泛型的基类呢?这是为了在基类实现的通用 方法中,能够以强类型的方式直接访问最终的子类。用上面的类举个例子,如果你使用 ActiveRecord 模式”那么要是使用非泛型的基类,你可能会在EntityBase 中加入方法: 但是,使用泛型基类绑定具体的子类后,我们会这样写代码: 1 User user = User.GetByld(id); 也就是说,这是一种更加类型安全的 API,用起来会很方便。 再举一个例子:由于泛型基类运行时绑定了不同的子类, 使得它本身的静态字段绑定到最终 的子类中的。例如上文中的例子, EntityBaseArticle 禾口 EntityBaseUser 其实是 不同的两个运行时类型。 这样,当我在EntityBaseT 内声明的静态字段是绑定到各子类 中的。如:我在 En tityBaseT 中声明了静态字段: public abstract class En tityBaseT { private static reado nly stri ng TypeName = typeof(T).Name; } 那么这个字段并不是为所有子类共享, 而是User.TypeName 和Article.TypeName 的值 不同,分别是User”和“Article。‘同样的功能,如果你要使用非泛型的基类,由于所有类 型共享一个运行时基类, 你需要考虑为在基类中为每个具体的类型存储对应的值, 例如,使 用一个字典存储: 1 public abstract class EntityBase 2 { 3 private static read only Dicti on aryType, string〉_allTypeNames = new Dicti on aryType, stri ng(); 4 public static string TypeName(Type concreteType) 5 { 6 return _allTypeNames[concreteType]; 7 } 8 } 这样的API用起来,是不是很不易用呢? 上面只是举了些最简单的例子, 实际上,由于使用了绑定具体子类的泛型基类, 还会有很多 地方的设计变得更简单了,在此不再一一列举。 带来的问题 使用这种模式,缺点是显而易见的: 不能直接使用基类进行统一的处理 继续上面的例子,这样的设计,使得我们不能对所有的实体进行统一的处理。由于 User和 Article的基类其实是两个不同的运行时类型, 所以我不能把它们转换为同一个 实体”类型。 如: EntityBase a = new Article。; a = new User(); 我甚至都不可能用到抽象的 En t

文档评论(0)

136****3783 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档