ASP.NET入门随想之多态、接口与委托

asp.net

    曾几何时,我们居住的陆地沉睡在海底,大陆也紧密的联系在一起,千百年过去了七大洲的地壳板块在缓缓移动,喜马拉雅山在慢慢增高,世界在变,唯一不变的是变化。

  ■ 软件开发的悖论 - 把变化变成计划

  在软件开发活动的过程中,常被一个悖论所缠绕:不写码就搞不清该做什么;搞不清做什么又不知道该如何写码。

  人的思维是很随意的东西,不同的人,或同一个人的不同阶段,对同一件事情的看法都会有差异,可谓是远看成岭侧成峰,远近高低各不同。随意再加上变化,常常引起项目流产或工期大大拖延。

  之所以会有软件工程,是因为想尽量挽救我们那白白死去的脑细胞和消逝的人民币。CIM/ISO官僚,每一个环节都要进行所谓科学管理与评估,质量差就返工,争取每一种构造活动只进行一次。难度在于开发活动很难定量计算,所谓评估常就是大家一起到酒桌上拼拼,一些活动初期的错误在后续无限放大;商业驱动的RUP有些瞎子摸象,要求用最短的时间拼出爱因斯坦粗糙的第一张凳子交给用户,得到确认后在此基础上不断循环改造,一直到用户满意的第N张为止,需要大量的用户参与,可是用户不是软件工程师,要他们来把握复杂的活动计划,难为他们。总之两者都有缺陷,修正错误和迭代开发是必然,所以软件架构设计伊始就要考虑适应需求变化,力将变化带来的影响减少到最小。 OO开发范式大致为:划分对象→抽象类→将类组织成为层次化结构(继承和合成) →用类与实例进行设计和实现几个阶段。在这个过程,合理使用OO语言的一些特性将影响软件对需求变化的适应力,其使用熟练度往往成为评价软件开发人员的标杆。

  ■ 尽可能远离switch - 多态与抽象类

  OO思想的基础在于把具备状态和方法的对象看作系统组成的基本粒子,用粒子之间的相互作用(或通讯)来描述系统的行为。通常方法在在某个类的作用域中定义方法接口和实现,并用于修改类的状态,如:泰坦尼克.移动(方向),这时方法是类的配角,为类服务,即类的方法。

  类的方法可能会有多种形态,只要签名(返回值和参数列表)不同,我们可以通过方法重载来达到概念(方法名)统一,如:泰坦尼克.移动(方向)与泰坦尼克.移动(方向,水流),这两种状况的实现不一样,但作为类的使用者概念而言,都是泰坦尼克在移动。而在面向过程时代,方法的多态往往是由switch语句来负责处理。

  结构化语言初行之时,非结构化语言被猛烈攻击的焦点居然集中在一条语句--goto身上,说它破坏了程序的组织结构,仿佛它就是万恶之源;与之类似的是,十几年后OO语言风行之始,人们同样找到一条语句大肆抨击,称它为僵化的毒药,它就是switch语句。switch语句是典型的结构化编程思想,众多模块的公共属性被映射到标志变量值域上的一点,简单地排列在一块,如下例:

switch (船类型){
 case "商船"
  商船的移动计算方法; Break;
 case "战船"
  战船的移动计算方法; Break;
}

  上例中,switch语句的问题在于它谋杀了众多船类移动计算方法之间的结构本质,缺乏对相似方法应有的抽象。后果是随处可见它那臃肿的身影。一旦需求变动,我们就不得不四处搜寻,一一修正。

  在这里移动方法实际上是船类系的公共方法。作为类系的使用者,他必然希望象重载一样做到概念(方法名)统一,而通过方法的签名来区分是商船还是战船在移动,所以我们调整如下:

void 控制移动(船类 ship){
 ship.移动;
 ……
}

战船 俾斯麦 = new战船();
商船 泰坦尼克 = new商船();
控制移动(俾斯麦);
控制移动(泰坦尼克);

  在控制移动(泰坦尼克)方法中,我们用商船的移动方法替换了ship.移动方法,其实这就是《随想六》提到的里氏替换原则,即子类型可以替换基型。类系方法的多态是由上传(upcast)机制来实现,如图7-1。与重载一样,由OO语言自动完成。


  上传机制有一个很直观的好处,如果船基类又临时增加赛船子类, 我们在不修改已有代码的前提下轻松完成对原有软件的扩展,即"开放-封闭"原则(Open-Closed Principle)。如增加以下代码并不影响控制移动方法:

  赛船 麦哲伦 = new赛船();
  控制移动(麦哲伦);

  只所以功能扩展不影响控制移动方法,是因为控制移动方法只依赖于船类系的基类。如果把一个类系的公共方法集中起来,定义成抽象类(abstract),其它类只与抽象类发生依赖关系,只要抽象类的方法接口不变,其继承子类的内部调整不影响外界的使用,最大程度达到外界与这个类系的架构(这时指依赖关系)稳定。作为一个抽象类,它具备两个重要特征:一是方法只有接口定义没有实现,二是子类(非抽象类继承)必须实现抽象类的所有方法。抽象类不能实例化,也没有必要实例化,就一空架子折腾啥呀。

  ■ 我是主角 - 接口与委托

  OO思想一般强调类为主角,方法是类的配角,尤其抽象类系,基类与所有子类是强耦合关系,它要是倒下了,人心就散了,队伍就难带了。一旦抽象类需要变动(增删改类系的公共方法),就对一个软件架构的影响程度而言,不亚于俄罗斯对乌克兰天然气涨价给欧洲带来的振憾,有可能带来多米诺骨牌效应。 当方法不仅仅只是一个而是多个类系的公共行为的抽象时,我们就必须把配角方法升格为主角,让它来支配相关类系,做法是将公共方法接口独立出来,单独定义成接口(interface),然后由相关类系一一实现,这时我们可以把其称为方法的类。所有外界与其关系不再建立在抽象类而是建立在接口之上,如图7-2。在定义接口的时候,注意不要让其过度臃肿,一个类对另外一个类的依赖性应当是建立在最小接口上。复杂的接口可以通过接口的多重继承或委托来分离。


  之所以一步步地把方法从配角升格为主角,是因为我们希望将需求中不稳定的成分隔离出来,用相对稳定的成分作为框架来构造系统。而一般概念的生存周期要远远大于特殊概念,如:职位>总裁>方兴东,所以要依赖于抽象而不要依赖于具体,即依赖倒置原则(Dependence Inversion Principle),前面谈到的"开放-封闭"原则是其外延。

  此外尽管方法从配角变为主角,其实现还是在该类的作用域中。有时方法更出格,委托类除了定义方法签名和通知其开工消息外,对方法的实现完全失去控制,它甚至到上台以后才知道今天的主角究竟是谁。这就是委托(delegate)机制。实质是类直接引用另一个类的方法,只要委托方法与受托方法接口一致,目的是彻底将方法的接口与实现分离。

class 商船{
 //委托类
 private int 动力;
 private delegate int 阻力计算委托(); //定义委托 public void 移动(阻力计算委托 阻力){
  int 作用力 = 动力 -阻力();
  ……
 }
}
class Test{
 //受托类
 private int 风阻力计算(){……};
 static void main(){
  商船 泰坦尼克;
  泰坦尼克.移动(new阻力计算委托(风阻力计算)) //委托实例
 }
}

  委托可以这么理解,上例中商船类为委托方张三,Test类为受托方李律师,张三(商船类)称我要告王五(阻力计算委托),李律师胸脯一拍:没问题,这事我按民事诉讼程序(风阻力计算方法)来办。

时间: 2024-12-08 14:37:23

ASP.NET入门随想之多态、接口与委托的相关文章

ASP.NET入门随想之抽象的力量

 ? ASP.NET入门随想之抽象的力量 小 时看过一故事:三书生欲进京赶考,问一老僧三人前景如何,老僧端坐如山,最后缓缓伸出一指.于是三书生路上争论不休,不明老僧指哪一人会黄榜题名,不料后 来三人同时高中,高兴之余,不禁对老僧的权威起了疑心.三人衣锦返乡后,追问老僧,老僧及端坐如山,缓缓曰:一指表示三人皆中,三人立马晕倒. ■ASP的编程思想 -写八股文 MS在java技术的冲击下匆忙推出ASP技术.要不是因为WinServer操作系统的霸主地位,粗陋的ASP不太可能在OO推行二十几年.C++

ASP.NET入门随想六之大航海家

asp.net 多隆云:我和韦春花的关系是很纯洁的:网易称其和迷蝶女友的关系是培训双向选择制:杨振宁言<易经>思想阻碍了中国近代科学的发展:逻辑学家论:概念间的关系有五种,即同一.包含.交叉.分离.互斥.而康托尔却认为:关系是有序偶. ■ 我要懒+笨 - 程序设计的终极目标 前不久社区里出现题为<这样的程序员是否算是一个合格的程序员?>的热贴,楼主言一手下编码花时间比别人多但代码规范健壮,设问这样的程序员是否可以留用且如何用?顿时掀起一片哗然,展开在中国这个特定的环境下何为程序设计

ASP.NET入门随想之明明白白我的心

asp.net 有一群说着同样语言的人,计划修一座高耸入云的高塔直达天庭,以证明族群团结的力量,塔很快就初具规模.这下可惊动天庭的神,他想这人和神都成邻居了,还怎么去统治人类?于是便施魔法扰乱人们的语言,使他们无法沟通,于是高塔再也无法继续修建. ■ 明明白白我的心 - 人机交互(Human-Computer Interaction) 博客园里有一篇<给妈妈写程序>感人肺腑,说的是作者常常为了指导50出头的妈妈完成COPY之类的操作耗尽心思,最后为其定做一个只需点击两下的程序,由此推出UI设计

ASP.NET入门随想之服务器控件模型

asp.net|服务器|控件 他迷上了珍珠奶茶.说实话,以前他一直觉得珍珠奶茶挺蠢的,真不知道是那一个天才的点子,居然把粉圆和泡沫红茶搅和在一起,还加上一根那么滑稽的超大吸管:妹妹刚迷上珍珠奶茶的时候,他还挺嗤之以鼻的呢.但这天以后,他几乎天天都会去买一杯珍珠奶茶,愈喝愈觉得珍珠奶茶的风味很特别,的确满好喝的.知道他迷上珍珠奶茶,妹妹还笑他:"早跟你说好喝你不信,男生就是迟钝." -- 管家琪<珍珠奶茶的诱惑> ■ 面向对象的粉圆 - 服务器控件模型 XHTML的一个重要目

ASP.NET入门随想之代言人

asp.net 本报讯 著名品牌服务器控件(Control)携手奥运冠军客户端HTML标签作为形象代言人,新形象以"极速体验"为主题,既诠释了服务器控件本身强大的信息处理能力,也表现客户端HTML标签希望用灵动和亲切来证明自己的决心与态度. ■ 内与外 - property与attribute 近日Google发布除英文外的唯一名称--谷歌,中国用户一片哗然, 暂且不论这个谷歌是不是比胡弋更合适,但Google想借此阐述产品内涵,取悦中国用户之心路人皆知:今年WEB2.0引无数风投竞折

ASP.NET入门随想之检票的老太太

asp.net 德国足协告诫那些可能前往德国观看2006年世界杯赛的球迷要提防假票,不要从非代理商和票贩子手中购票.世界杯门票都是高科技产品,门票被植入微芯片,只有通过合法途径取得门票的球迷才能入场.假票现象在近些年的足球大赛上泛滥成灾,德国足协希望能通过宣传避免世界杯球迷成为其受害者. ■ 验明正身 - 数据有效性 世界杯万人瞩目但门票有限,所以有人造假有人买假,安联球场的大门前站几位检票员必不可少,而我们的程序有时也一样.当你接到一个累积数年的数据表时,发现单单联系电话都有23种格式时,你是

ASP.NET编程入门随想之宽容(修改版)

asp.net|编程 相关文章:ASP.NET编程入门随想之宽容 古老的山谷村民生活富足,守旧老人维护着经典和秩序.一位不满现状的漂泊者却宣称外面有更好的世界在等着大家,并鼓动村民跟随前往.但守旧老人的威严和律法的神圣压制了村民的躁动,漂泊者也被处死.一天灾难降临山谷.尽管守旧老人依然试图维护经受村民的求生欲望挑战的律法.但暴动还是发生,老人们被击败,新的道路和新的生活被村民找到.怀着感恩之心,后人把以前的漂泊者奉为先知,尽管他早已尸骨无存. -- 房龙<宽容•序言> ■ 宽容 – W3C 的

ASP编程入门进阶(十四):Browser &amp;amp; Linkin

编程 一.Browser Capabilities组件 该组件最主要的作用是:提取识别客户端浏览器的版本信息. 其原理是这样的:当客户端浏览器向服务器发送页面请求时,同时会自动发送一个User Agent HTTP标题,而该标题是一个声明浏览器及其版本的 ASCII 字符串.而Browser Capabilities组件就将User Agent映射到在文件Browscap.ini中所注明的浏览器 , 并通过BrowserType对象的属性来识别客户浏览器. 若该对象在 browscap.ini

ASP编程入门进阶(一) 安装配置服务器

编程|服务器|服务器 申明:asp编程入门进阶系列文章COPY自http://www.cnbruce.com/blog/ 部分运行代码请到该站进行在线测试ASP编程入门进阶(一):安装配置服务器 鉴于ASP脚本语言是在服务器端IIS或PWS中解释和运行,并可动态生成普通的HTML网页,然后再传送到客户端供浏览的这一特点.我们要在本机上进行调试,那就要求我们的个人电脑具有服务器的功能. 不要看到"服务器"三个字就感到担心:我的机子配置这么底,性能这么差,是不是不能配啊.放心!配个服务器,