博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式 之 访问者模式
阅读量:6506 次
发布时间:2019-06-24

本文共 5435 字,大约阅读时间需要 18 分钟。

hot3.png

设计模式 之 访问者模式

概念

核心理念:将数据结构与算法分离。

使用场景:数据结构不变动,算法经常变动。

  • 1、一个Visitor类存放被访问的对象,访问者主要处理具体算法与行为。
// 访问者public interface Visitor {      // Subject 是被访问的对象    public void visit(Subject sub);  }/** 具体访问者处理具体算法 */
  • 2、被访问的对象,也就是数据结构。
// 被访问的对象public interface Subject {      // 接收访问者访问    public void accept(Visitor visitor); } // 具体实现public class MySubject implements Subject {      @Override      public void accept(Visitor visitor) {          // 让访问者访问自己        visitor.visit(this);      }  }

代码场景

不同的顾客对商品持有不同的意见。 顾客A、顾客B买衣服裤子,商店上架各种衣服和裤子。

代码

Goods

/** * 商品抽象类 * @author GaoYuan * @date 2018/11/11 上午8:38 */public abstract class Goods {    /** 商品名字 */    public String goodsName;    /** 商品价格 */    public int price;    public void setGoodsName(String goodsName){        this.goodsName = goodsName;    }    public void setPrice(int price){        this.price = price;    }    /** 接收访问的方法 */    public abstract void accept(Visitor visitor);}

上衣

/** * 衣服 * @author GaoYuan * @date 2018/11/11 上午8:41 */public class Clothes extends Goods{    /** 颜色 */    private String color;    public Clothes(String goodsName, int price, String color){        setGoodsName(goodsName);        setPrice(price);        this.color = color;    }    public String getColor() {        return color;    }    @Override    public void accept(Visitor visitor) {        visitor.visit(this);    }}

裤子

/** * 裤子 * @author GaoYuan * @date 2018/11/11 上午8:41 */public class Trousers extends Goods{    /** 长度 */    private int length;    public Trousers(String goodsName, int price, int length){        setGoodsName(goodsName);        setPrice(price);        this.length = length;    }    public int getLength() {        return length;    }    @Override    public void accept(Visitor visitor) {        visitor.visit(this);    }}

管理所有商品对象

/** * 店面 * @author GaoYuan * @date 2018/11/11 上午8:53 */public class Shop {    private List
goodsList = new ArrayList<>(); /** 添加 */ public void add(Goods goods){ goodsList.add(goods); } /** 商家询问顾客看中哪件 */ public void askAnswer(Visitor visitor){ for(Goods goods:goodsList){ // 商品挨个接收访问者访问 goods.accept(visitor); } }}

访问者接口

/** * 访问者接口 * @author GaoYuan * @date 2018/11/11 上午8:33 */public interface Visitor {    /** 访问商品 */    void visit(Goods goods);}

具体访问者

/** * 男生买衣服裤子 * @author GaoYuan * @date 2018/11/11 上午8:50 */public class ManVisitor implements Visitor{    @Override    public void visit(Goods goods) {        if(goods instanceof Clothes){            if(((Clothes)goods).price > 100){                System.out.println("[ManVisitor]->" + ((Clothes)goods).goodsName + ":太贵了,不买");            }else if("red".equals(((Clothes)goods).getColor())){                System.out.println("[ManVisitor]->" + ((Clothes)goods).goodsName + ":红色太丑了,不买");            }else{                System.out.println("[ManVisitor]->" + ((Clothes)goods).goodsName + ":价格颜色都能接收,买了");            }        }else if(goods instanceof Trousers){            if(((Trousers)goods).price > 100){                System.out.println("[ManVisitor]->" + ((Trousers)goods).goodsName + ":太贵了,不买");            }else if(((Trousers)goods).getLength() > 20){                System.out.println("[ManVisitor]->" + ((Trousers)goods).goodsName + ":太长了,不买");            }else if(((Trousers)goods).getLength() < 10){                System.out.println("[ManVisitor]->" + ((Trousers)goods).goodsName + ":太短了,不买");            }else{                System.out.println("[ManVisitor]->" + ((Trousers)goods).goodsName + ":价格长度都合适,买了");            }        }    }}/** * 女生买衣服裤子 * @author GaoYuan * @date 2018/11/11 上午8:50 */public class WomanVisitor implements Visitor{    @Override    public void visit(Goods goods) {        if(goods instanceof Clothes){            if(((Clothes)goods).price > 500){                System.out.println("[WomanVisitor]->" + ((Clothes)goods).goodsName + ":太贵了,不买");            }else{                System.out.println("[WomanVisitor]->" + ((Clothes)goods).goodsName + ":什么颜色都能接收,买了");            }        }else if(goods instanceof Trousers){            if(((Trousers)goods).price > 500){                System.out.println("[WomanVisitor]->" + ((Trousers)goods).goodsName + ":太贵了,不买");            }else if(((Trousers)goods).getLength() > 8){                System.out.println("[WomanVisitor]->" + ((Trousers)goods).goodsName + ":太长了,不买");            }else{                System.out.println("[WomanVisitor]->" + ((Trousers)goods).goodsName + ":裤子越短约好,买了");            }        }    }}

测试类

public static void main(String[] args){    Shop shop = new Shop();    shop.add(new Clothes("限量版风衣",200, "black"));    shop.add(new Clothes("披风",50, "red"));    shop.add(new Clothes("衬衫",70, "blue"));    shop.add(new Trousers("牛仔裤", 150, 18));    shop.add(new Trousers("喇叭裤", 80, 24));    shop.add(new Trousers("超短裤", 60, 5));    // 询问男人    shop.askAnswer(new ManVisitor());    // 询问女人    shop.askAnswer(new WomanVisitor());}

结果输出

[ManVisitor]->限量版风衣:太贵了,不买[ManVisitor]->披风:红色太丑了,不买[ManVisitor]->衬衫:价格颜色都能接收,买了[ManVisitor]->牛仔裤:太贵了,不买[ManVisitor]->喇叭裤:太长了,不买[ManVisitor]->超短裤:太短了,不买[WomanVisitor]->限量版风衣:什么颜色都能接收,买了[WomanVisitor]->披风:什么颜色都能接收,买了[WomanVisitor]->衬衫:什么颜色都能接收,买了[WomanVisitor]->牛仔裤:太长了,不买[WomanVisitor]->喇叭裤:太长了,不买[WomanVisitor]->超短裤:裤子越短约好,买了

优缺点

优点

  • 将数据结构与算法解耦
  • 增加操作很容易(增加访问者);

缺点

  • 数据结构不易于扩展。
  • 类变多了,也变复杂了,理解上不太直观。

码云

博客

欢迎关注我的个人微信订阅号:(据说这个头像程序猿专用)

输入图片说明

转载于:https://my.oschina.net/gmarshal/blog/2876986

你可能感兴趣的文章
[java]递归读取目录及其子目录文件
查看>>
C#的扩展方法解析
查看>>
delphi type
查看>>
查找被程序占用端口并关闭
查看>>
Windows下Composer使用问题
查看>>
Shiro基于组织机构的登录验证
查看>>
【分享】高手Java核心技术学习笔记
查看>>
windows下安装redis以及redis扩展,设置redis为windows自启服务
查看>>
颜色模式
查看>>
倒立三角打印
查看>>
passwd命令--Linux命令应用大词典729个命令解读
查看>>
Java 系列文章
查看>>
我的友情链接
查看>>
Linux中的find(-atime、-ctime、-mtime)指令分析
查看>>
使用MDT2013部署Win8系统之九-通过MDT部署捕获系统镜像
查看>>
Virbox Compiler-以安全为核心目标的编译器
查看>>
SnappyData Tutorial
查看>>
我的友情链接
查看>>
AJAX即时编辑网页中的数据
查看>>
我的友情链接
查看>>