经历现实与虚幻的两难

原创 2003年08月15日 14:23:00

经历现实与虚幻的两难

            —一个.Net事件机制实例

    今天,发薪日。刚过去的三十天里,我把二十天都献给了公司,以公司为家,让新婚的老婆独守空闺,现在盘算着为她买点东西、陪她看场电影、吃个饭什么的,好补偿一下。谁知临下班时,一个晴天霹雳让人欲哭无泪。公司高层开完会就发了通知,告诉我们这个开发小组,因为项目延期,上个月的薪水和奖金大家就都别领了。本来兄弟们最盼望的就是今天了,可是现在……。哎,该怎么办?暗自忿忿还是据理力争,婉言提醒还是直述胸臆,这真是一个难题。在对这件事的态度上,组员们产生了分歧。一部分认为应该找代表和公司交涉,以维护我们的权益;另一部分则认为不应该和公司闹不和,还是“忍辱负重,苟且偷生”方为上策。

    由于一些因素(项目延期),一个类型(公司)发生了一件事(扣发薪水和奖金),另一些类型(主战派、主和派)在得知这件事后,采取了一些行动(维护权利和忍辱负重)。

    在CLR中存在事件模型,可以模拟上面的事件。事件在计算机程序中是非常有用的,甚至可以说是是举目所及,概莫能外。

事件的产生

    为了完成产生事件的类型,我们需要的“东西”有:

    1、一个存放事件相关信息的类型
    2、一个委托类型和一个事件
    3、在一个方法内部,“事件”发生了
    4、一个发出事件已发生的通知的方法,我称之为“警报器”

    上面的“东西”都位于SoftwareComplany类型。

    1、事件信息类型应该继承自System.EventArgs类型,在命名风格上,建议在该类型名的末尾加EventArgs,表示该类型是一个事件信息类型。

public class DecisionMakingEventArgs : System.EventArgs
{
      private readonly System.String causation, result;       
      public DecisionMakingEventArgs(System.String causation,System.String result)
      {
            this.causation = causation;
            this.result = result;
      }
}

2、委托类型的命名,推荐以EventHandler结尾。该类型有两个参数:发出事件通知的对象、事件信息类型;而事件其实就是委托的实例。

public delegate void DecisionMakingEventHandler (System.Object source, DecisionMakingEventArgs mEventArgs);
public event DecisionMakingEventHandler DmMsg;

3、在下面的方法内,“事件”发生了。

public void Conference(System.String causation,System.String result)
{
      DecisionMakingEventArgs e =new DecisionMakingEventArgs(causation, result);
      //下达会议决策
      OnDmMsg(e);
}

4、“警报器”方法。在这个方法内,首先查看是否有类型“订阅”了该事件。如果有,就通知这些“订阅”事件的类型。

private void OnDmMsg(DecisionMakingEventArgs e)
{
      //查看是否有类型“订阅”了该事件
      if(DmMsg != null)
      {
           //发出警报
            DmMsg(this, e)
      }
}

事件的订阅

    ProgrammerEmployee类型和FinanceEmployee类型都“订阅”了DmMsg事件,但在对该事件的“态度”上,两个类型是完全不一样的。

    懒惰、高傲、怀疑一切的程序员们要维护自己的权益,和公司斗争到底,如果公司一味“咄咄相逼”,那宁为玉碎,不为瓦全;勤奋、卑微、永远相信上级,但“笑厣如花”的财务人员却要检讨自己,并任由公司“宰割”。哎,女人啊,你的名字是弱者。

public class ProgrammerEmployee
{
      public ProgrammerEmployee(SoftwareComplany sc)
      {
           sc. DmMsg += new SoftwareComplany(PEMsg);
      }

      private void PEMsg(System.Object source,
                   DecisionMakingEventArgs e)
      {
            System.Console.WriteLine(“壮志饥餐胡虏肉,笑谈渴饮匈奴血”);
      }
}

public class FinanceEmployee
{
      public FinanceEmployee(SoftwareComplany sc)
      {
           sc. DmMsg += new SoftwareComplany(FEMsg);
      }

      private void FEMsg(System.Object source,
                  DecisionMakingEventArgs e)
      {
            System.Console.WriteLine(“新样靓妆,艳溢香融,羞杀蕊珠宫女”);
      }
}

完整的代码

//公司类型
public class SoftwareComplany
{
//事件信息类型
public class DecisionMakingEventArgs : System.EventArgs
{
//相关信息字段
            private readonly System.String causation, result;
            public DecisionMakingEventArgs(System.String causation,System.String result)
           {
                 this.causation = causation;
                 this.result = result;
           }
//委托原型
public delegate void DecisionMakingEventHandler(System.Object source, DecisionMakingEventArgs mEventArgs);
//定义事件
public event DecisionMakingEventHandler DmMsg;
//每月例会
//公司体制不健全,所以会议纪要从来不记录时间
public void Conference(System.String causation,System.String result)
{
      DecisionMakingEventArgs e = new DecisionMakingEventArgs(causation, result);                
//警报器
                 OnDmMsg(e);
}

private void OnDmMsg(DecisionMakingEventArgs e)
{
                 //查看是否有类型“订阅”了该事件
                 if(DmMsg != null)
                 {
                       //发出警报
                       DmMsg(this, e)
                 }
}
}
}

public class ProgrammerEmployee
{
      public ProgrammerEmployee(SoftwareComplany sc)
      {
           sc. DmMsg += new SoftwareComplany(PEMsg);
      }

      private void PEMsg(System.Object source, DecisionMakingEventArgs e)
      {
           //恨不能“食其肉,寝其皮”
            System.Console.WriteLine(“壮志饥餐胡虏肉,
笑谈渴饮匈奴血”);
      }
}

public class FinanceEmployee
{
      public FinanceEmployee(SoftwareComplany sc)
      {
           sc. DmMsg += new SoftwareComplany(FEMsg);
      }

      private void FEMsg(System.Object source, DecisionMakingEventArgs e)
      {
           //小样
            System.Console.WriteLine(“新样靓妆,艳溢香融,羞杀蕊珠宫女”);
      }
}

public class app
{
      public static void Main(System.String[] args)
      {
            SoftwareComplany sc = new SoftwareComplany();
            ProgrammerEmployee pe = new ProgrammerEmployee();
            FinanceEmployee fe = new FinanceEmployee();
           //开会
           sc. Conference(“项目延期”, “扣发薪金”)
      }
}

吹毛求疵

    世间有太多吹毛求疵的人了,在项目开发中,差不多每一个人都是这样的。程序员一方面希望客户能充分了解自身的需求,另一方面又希望自己的程序能“Do more with less”(不知道借用时下流行的广告词是不是涉嫌侵权)。当然,我们不但无法对客户的素质有所要求,还得提心吊胆的把他们好好供着、伺候着,谁叫他们是我们的衣食父母呢。所以,如果碰上的客户清楚的了解自己需要些什么,那并不是我们的素质高,而且不论我们怎样的修行,都无法对此产生一丁点的裨益,碰上这样的客户,我们应该感谢上帝,感谢真主阿拉,感谢我佛慈悲,感谢所有能感谢的人,不过千万不要“感谢”自己。而“程序”是我们吃饭的家伙,把它玩的越蕴贴,你的希望就越能实现。所以,如果真的碰上了上面所说的那种客户,与其花时间感谢过来感谢过去的,不如多花点时间来把玩自己的程序,这样才对的起那样的客户嘛(也说不定圣明的上帝万能的真主看到你这样的“虔诚”,会让你多遇上几个这样的客户哦)!

看得更清楚一点

    发布事件的类型把订阅信息存放在哪里的,这点从表面上看,应该是DmMsg中,但其实CLR隐藏了一些东西—一个私有的字段,该字段是一个委托类型的实例,可以把它看成是链表,用以存储相关类型的订阅信息,DmMsg就是使用该字段存储相关订阅信息。CLR允许程序员显示定义该字段,虽然会多出一部分代码,但带来的效果(提升性能)却值得这样做。

//定义委托
public delegate void DecisionMakingEventHandler(System.Object source, DecisionMakingEventArgs mEventArgs);
//显式定义链表
private DecisionMakingEventHandler dmDelegate;
//定义事件,但事件注册和事件注销都需要显示定义
public event DecisionMakingEventHandler DmMsg
{
      //事件注册
      add
      {
            dmDelegate = (DecisionMakingEventHandler)
                             System.Delegate.Combine(dmDelegate, value);
      }
      //事件注销
      remove
      {
            dmDelegate = (DecisionMakingEventHandler)                             System.Delegate.Remove(dmDelegate, value);
      }
}

    做改动的地方还有OnDmMsg方法,警报改由链表字段发出而已“dmDelegate(this, e)”。这样,新版本的事件就完成了。

 

真实

    本文水平不会高到哪里去,但看过之后对.Net的事件还是应该能有一番认识吧。

参考书籍

l Jeffrey Richter著《Applied Microsoft .Net Framework Programming》,Microsoft Press出版

2 余秋雨著《千年一叹》,作家出版社出版

 

华丽的虚幻与平庸的现实

习惯一个人在黑暗中成长,没有方向,只是晃荡~~~~~   喜欢看着夜色在城市里蔓延,滋生出的霓虹是醉汉带着欲望的眼,难寐,倚着竹榻,冷笑点燃了寂寞,我一口一口~~~~~曾几何时,还会有思念潮水般吞噬我...
  • zhujin_jin
  • zhujin_jin
  • 2009年05月18日 19:32
  • 211

商业WIFI的虚幻与现实

功夫在诗外,玩好商业wifi不在wifi本身,在于搞明白它到底映射的是何种生态。 近两年,挟资本的力量,各民办方在大张旗鼓的跑马圈地,你圈商户,他圈公交,你圈机场,他圈高铁,你圈商场,他圈候车室,弱...
  • bingyu9875
  • bingyu9875
  • 2016年03月08日 17:03
  • 386

现实与理想的辩证关系

理想虽与幻想只有一字之差,但在本质上却天壤之别。理想不是空想,理想最大的特征是脚踏实地,理想实现的最基本要求是不允许在浮躁与幻想中浪费生命。幻想的动力来自于对物质的迷恋的对自己的认知不足,而理想的动力...
  • TonyABu
  • TonyABu
  • 2015年09月21日 20:47
  • 1388

梦想和现实之间的那段距离,叫做行动

The distance between your dreams and reality is called action. 梦想和现实之间的那段距离,叫做行动。 原文载于:爱词霸英语学习网-每日一...
  • bigheadsheep
  • bigheadsheep
  • 2013年12月23日 08:45
  • 1993

虚幻4Component

UNITY与虚幻都在用组件的模式,组件模式有很多优点: 重用:打个比方我们要组装一辆车,每一个组件就好像一个基础零件,类似于汽车中的轮胎,方向盘,记录仪,车身等,这些基础组件可以重用,Actor就可...
  • lqpgfz
  • lqpgfz
  • 2018年01月13日 12:31
  • 57

逻辑(面试)题目中的陷阱

2007年05月20日 23:18:00 [原文地址:关于逻辑学的文章zz ]正如充满正义感的人无法容忍犯罪的发生,富于美感的人不能包容丑陋和瑕疵一样,一个逻辑严谨的人是没办法忍受哪怕一点点逻...
  • softart
  • softart
  • 2007年10月27日 20:35
  • 436

Unity和虚幻的比较

很多人从Unity开始转向虚幻4了,我目前则相反。 前端总结的Unity和Unreal 4的一些优缺点,自己做的图标。就先放这里了。 其实,作为引擎,各有优缺。就是工具,放你手里怎么用了。 若...
  • cartzhang
  • cartzhang
  • 2015年11月10日 10:23
  • 9706

男人与女人,理想与现实,感性与理性

一直以来,笔者一直认为“男人”等价于“现实”、“理性”,而“女人”等价于“理想”、“感性”。 后来慢慢发现,这个观点是某种缺乏思考的论断。   古代战事频繁,男人往往成为战争的机器,长年在外征战...
  • it1988888
  • it1988888
  • 2012年09月10日 00:46
  • 1665

虚幻4 - ARPG实战教程(第一季)

以ARPG项目为实例,以深入浅出的方式,讲解虚幻4引擎各个模块的实际用法、开发思路,以及相关知识拓展。...
  • Neil3D
  • Neil3D
  • 2016年04月14日 14:47
  • 8193

现实与理想(中国台湾大学彭明辉)

人生最困难的课题,莫过于现实与理想间的矛盾:我们希望有很高的收入和社会地位,让身边的每一个人羡慕、敬佩,甚至于连父母脸上都有光彩;但是,我们又不想要成­为金钱的奴隶,「赢得全世界却赔上自己」。汽车后面...
  • yanzhenbo1
  • yanzhenbo1
  • 2016年12月09日 13:43
  • 742
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:经历现实与虚幻的两难
举报原因:
原因补充:

(最多只允许输入30个字)