设计模式(22)----- 访问者模式

概念:

在访问者模式(Visitor Pattern)中,我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作。

意图:

主要将数据结构与数据操作分离。

主要解决:

稳定的数据结构和易变的操作耦合问题。

优点:

  1. 符合单一职责原则。
  2. 优秀的扩展性。
  3. 灵活性。

缺点:

  1. 具体元素对访问者公布细节,违反了迪米特原则。
  2. 具体元素变更比较困难。
  3. 违反了依赖倒置原则,依赖了具体类,没有依赖抽象。

实现类图
在这里插入图片描述

访问者模式包含以下主要角色。

抽象访问者(Visitor)角色: 定义一个访问具体元素的接口,为每个具体元素类对应一个访问操作,该操作中的参数类型标识了被访问的具体元素。

public abstract class 电影
{
    abstract public void accept(顾客 n);
    abstract public void 播放电影();
}

具体访问者(ConcreteVisitor)角色: 实现抽象访问者角色中声明的各个访问操作,确定访问者访问一个元素时该做什么。

using System;

public class 爱国片 : 电影
{
    public override void accept(顾客 n)
    {
        n.看电影(this);
    }

    public override void 播放电影()
    {
        Console.WriteLine("电影院播放爱国片电影!");
    }
}
using System;

public class 爱情片 : 电影
{
    public override void accept(顾客 n)
    {
        n.看电影(this);
    }

    public override void 播放电影()
    {
        Console.WriteLine("电影院播放爱情片电影!");
    }
}

抽象元素(Element)角色: 声明一个包含接受操作 accept() 的接口,被接受的访问者对象作为 accept() 方法的参数。

public abstract class 顾客
{
    abstract public void 看电影(爱国片 m);
    abstract public void 看电影(爱情片 m);
}

具体元素(ConcreteElement)角色: 实现抽象元素角色提供的 accept() 操作。

using System;

public class 老人 : 顾客
{
    public override void 看电影(爱国片 m)
    {
        Console.Write("老人看: ");
        m.播放电影();
    }

    public override void 看电影(爱情片 m)
    {
        Console.Write("老人看: ");
        m.播放电影();
    }
}
using System;

public class 学生 : 顾客
{
    public override void 看电影(爱国片 m)
    {
        Console.Write("学生看: ");
        m.播放电影();
    }

    public override void 看电影(爱情片 m)
    {
        Console.Write("学生看: ");
        m.播放电影();
    }
}

对象结构(Object Structure)角色: 是一个包含元素角色的容器,提供让访问者对象遍历容器中的所有元素的方法。

using System.Collections.Generic;

class 电影库
{
    private List<电影> list = new List<电影>();
    //观看当前电影库里所有的电影
    public void accept(顾客 m)
    {
        foreach (电影 n in list)
        {
            n.accept(m);
        }
    }
    //添加方法
    public void add(电影 m)
    {
        list.Add(m);
    }
}

测试:

using System;

class Program
{
    static void Main(string[] args)
    {
        电影库 m = new 电影库();
        m.add(new 爱国片());
        m.add(new 爱情片());

        顾客 n = new 老人();
        m.accept(n);
        Console.WriteLine(" ");
        n = new 学生();
        n.看电影(new 爱国片());

        Console.Read();
    }
}

输出示例
在这里插入图片描述
设计模式------首页

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值