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: }
转载请注明出处。版权所有©2022 麦机长,保留所有权利。