4.11 Visitor(访问者)

【返回目录】

有句成语叫“对症下药”,就是说对于不同的情况要有不同的行之有效的措施才行,俗话所说的“见人说人话,见鬼说鬼话”其实也是这个意思。

想象一下这样一个场景,我们每个人都是Person类的一个实例对象,而人食五谷杂粮,哪有不生病的道理,对于自身出现的疾病(假设是抛了个异常),我们应该怎样处理呢?假设让你来设计这样一个系统,你会如何设计呢?显然,按照常理来理解,自身的问题当然就是自己解决了,增加一个方法就行了。然而人有不同,有男人有女人,男女之间又有差异,例如:男人可能患前列腺炎而女人压根儿就没有前列腺;另外,似乎从没听说过男人会得乳腺癌而这确实女人问之色变的魔鬼。假设我们再把这些差异扩大化,你就会发现,按照前面提到的办法设计出来的系统会变得越来越难以理解和操作。另外,这也会增加各个类的复杂性,类会变得更加庞大和难以维护。

而现实世界又是如何处理这个问题的呢?医生的职业应运而生。专业化的医生可以对不同病人的病情做出相应的判断和处理,病人挂号看病时就会找到可以处理自己病情的医生,然后把自己的病情一一介绍给医生,必要时把自身对象也传递给医生,往手术台上那么一躺,任由医生动刀。所以人类社会能够得以进步,很大一个原因就是各个领域的专业化分工,很难想象这是怎样一种感受:如果有一天某人得了阑尾炎去医院就诊,护士把他推进一间病房并扔给他一套工具,冷冰冰的说:“你自己解决吧,动作快点儿,后面人还排着呢!”

说起来感觉挺血腥的,不过这就是我们要介绍的访问者模式:

   1: using System;
   2:  
   3: namespace Autumoon.DesignPatterns.Visitor
   4: {
   5:     abstract public class Doctor
   6:     {
   7:         abstract public void OperateToMan(MalePatient malePatient);
   8:         abstract public void OperateToWoman(FemalePatient femalePatient);
   9:     }
  10:  
  11:     public class ConcreteDoctor : Doctor
  12:     {
  13:         override public void OperateToMan(MalePatient malePatient)
  14:         {
  15:             Console.WriteLine("This is operation for man's prostatitis.");
  16:         }
  17:  
  18:         override public void OperateToWoman(FemalePatient femalePatient)
  19:         {
  20:             Console.WriteLine("This is operation for woman's ovarian cancer.");
  21:         }
  22:     }
  23:  
  24:     abstract public class Patient
  25:     {
  26:         abstract public void Accept(Doctor doctor);
  27:     }
  28:  
  29:     public class FemalePatient : Patient
  30:     {
  31:         public Doctor CurrentDoctor { get; set; }
  32:  
  33:         override public void Accept(Doctor doctor)
  34:         {
  35:             this.CurrentDoctor = doctor;
  36:         }
  37:  
  38:         public void Operation()
  39:         {
  40:             this.CurrentDoctor.OperateToWoman(this);
  41:         }
  42:     }
  43:  
  44:     public class MalePatient : Patient
  45:     {
  46:         public Doctor CurrentDoctor { get; set; }
  47:  
  48:         override public void Accept(Doctor doctor)
  49:         {
  50:             this.CurrentDoctor = doctor;
  51:         }
  52:  
  53:         public void Operation()
  54:         {
  55:             this.CurrentDoctor.OperateToMan(this);
  56:         }
  57:     }
  58: }

病来如山倒,刻不容缓啊,健康才是福,在此《简明设计模式——C#版》结局篇的最后,我衷心祝愿所有的朋友们,身体健康,家庭幸福,事业有成!

   1: static void Main(string[] args)
   2: {
   3:     #region Visitor
   4:     FemalePatient femalePatient = new FemalePatient();
   5:     MalePatient malePatient = new MalePatient();
   6:     ConcreteDoctor doctor = new ConcreteDoctor();
   7:  
   8:     femalePatient.Accept(doctor);
   9:     femalePatient.Operation();
  10:  
  11:     malePatient.Accept(doctor);
  12:     malePatient.Operation();
  13:     #endregion
  14:  
  15:     Console.ReadLine();
  16: }

Doctor

posted @ 2008-02-24 23:11  麦机长  阅读(1401)  评论(1编辑  收藏  举报