当前位置: 首页 > news >正文

个人创业做网站seo引擎优化专员

个人创业做网站,seo引擎优化专员,韩国学校网站模板,网站建设ppt模板下载设计模式--行为型--访问者模式 访问者模式定义结构案例优缺点使用场景扩展分派动态分派静态分派双分派 访问者模式 定义 封装一些作用于某种数据结构中的各元素的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新操作。 结构 抽象访问者角色&…

设计模式--行为型--访问者模式

    • 访问者模式
      • 定义
      • 结构
      • 案例
      • 优缺点
      • 使用场景
      • 扩展
        • 分派
        • 动态分派
        • 静态分派
        • 双分派

访问者模式

定义

封装一些作用于某种数据结构中的各元素的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新操作。

结构

  • 抽象访问者角色(Visitor):定义了对每一个元素访问的行为,它的参数就是可以访问的元素,它的方法个数理论上来说于元素类个数是一样的,从这点上来看,访问者模式要求元素类的个数不能改变。
  • 具体访问者角色(Concrete Visitor):给出对每一个元素类访问时所产生的具体行为。
  • 抽象元素角色(Element):定义了一个接受访问者的方法,其意义是指,每一个元素都要可以被访问者访问。
  • 具体元素角色(Concrete Element):提供接受访问方法的具体实现,而这个具体的实现,通常情况下是使用访问者提供的访问该元素类的方法。
  • 对象结构角色(Object Structure):定义当中所提到的对象结构,对象机构是一个抽象表述,具体点可以理解为一个具有容器性质或者复合对象特性的类,它会含有一组元素,并且可以迭代这些元素,供访问者访问。

案例

给宠物喂食

  • 访问者角色:给宠物喂食的人
  • 具体访问者角色:主人,其他人
  • 抽象元素角色:动物抽象类
  • 具体元素角色:宠物狗,宠物猫
  • 结构对象角色:主人家
    类图:
    在这里插入图片描述
/*** 抽象元素角色类*/
public interface Animal {// 接受访问者访问的功能void accept(Person person);
}
/*** 具体元素角色类  猫*/
public class Cat implements Animal{@Overridepublic void accept(Person person) {person.feed(this);System.out.println("喵喵喵~");}
}
/*** 具体元素角色类  狗*/
public class Dog implements Animal{@Overridepublic void accept(Person person) {person.feed(this);System.out.println("汪汪汪~");}
}
/*** 抽象访问者角色类*/
public interface Person {void feed(Cat cat);void feed(Dog dog);
}
/*** 具体访问者角色类  自己*/
public class Owner implements Person{@Overridepublic void feed(Cat cat) {System.out.println("主人喂猫");}@Overridepublic void feed(Dog dog) {System.out.println("主人喂狗");}
}
/*** 具体访问者角色类  别人*/
public class Someone implements Person{@Overridepublic void feed(Cat cat) {System.out.println("别人喂猫");}@Overridepublic void feed(Dog dog) {System.out.println("别人喂狗");}
}
/*** 对象结构类*/
public class Home {// 声明一个集合对象,用来存储元素对象private List<Animal> nodeList = new ArrayList<>();// 添加元素public void add(Animal animal){nodeList.add(animal);}public void action(Person person){// 遍历集合获取每一个元素,让访问者访问每一个元素for (Animal animal : nodeList) {animal.accept(person);}}
}
public class Test01 {public static void main(String[] args) {// 创建home对象Home home = new Home();// 添加元素home.add(new Cat());home.add(new Dog());// 创建主人对象Owner owner = new Owner();// 让主人喂所有的宠物home.action(owner);}
}

在这里插入图片描述

优缺点

  • 优点
    • 扩展性好,在不修改对象结构中元素的情况下,为对象结构中的元素添加新的功能。
    • 复用性好,通过访问者来定义整个对象结构通用的功能,从而提高复用程度。
    • 分离无关行为,通过访问者来分离无关的行为,把相关的行为封装在一起,构成一个访问者,这样每一个访问者的功能都比较单一。
  • 缺点
    • 对象结构变化困难,在访问者模式中,每增加一个新的元素类,都要在每一个具体访问者类中增加相应的具体操作,违背了开闭原则
    • 违反了依赖倒置原则,访问者模式依赖了具体类,而没有依赖抽象类。

使用场景

  • 对象结构相对稳定,但操作算法经常变化
  • 对象结构中的对象需要提供多种不同且不相关的操作,而且要避免让这些操作的变化影响对象的结构。

扩展

访问者用到了一种双分派技术。

分派

变量被声明时的类型叫做变量的静态类型,又称明显类型;而变量所引起的对象的真实类型又叫做变量的实际类型。比如Map map = new HashMap(),map变量的静态类型是Map,实际类型是HashMap。根据对象的类型而对方法进行的选择。就是分派(Dispatch),分派又分两种,静态分派和动态分派。

  • 静态分派,发生在编译时期,分派根据静态类型信息发生。方法重载就是静态分派。
  • 动态分派,发生在运行时期,动态分派动态的置换掉某个方法,Java就是通过方法的重写支持动态分派。
动态分派

通过方法的重写支持动态分派

public class Animal {public void execute(){System.out.println("animal");}
}public class Dog extends Animal{@Overridepublic void execute() {System.out.println("dog");}
}public class Cat extends Animal{@Overridepublic void execute() {System.out.println("cat");}
}public class Test{public static void main(String[] args) {Animal animal = new Dog();animal.execute();Animal animal1 = new Cat();animal1.execute();}
}

上面是多态,运行执行的是子类中的方法。
Java编译器在编译时期并不总是知道哪些代码会被执行,因为编译器仅仅知道对象的静态类型,而不知道对象的真是类型;而方法的调用则是根据对象的真实类型,而不是静态类型。

静态分派

通过方法重载支持静态分派

public class Animal {public void execute(){System.out.println("animal");}
}public class Dog extends Animal{
}public class Cat extends Animal{
}public class Execute{public void execute(Animal animal){System.out.println("animal");}public void execute(Cat cat){System.out.println("cat");}public void execute(Dog dog){System.out.println("dog");}
}public class Test{public static void main(String[] args) {Animal animal = new Animal();Animal animal2 = new Cat();Animal animal3 = new Dog();Execute execute = new Execute();execute.execute(animal);   // animalexecute.execute(animal2);  // animalexecute.execute(animal3);  // animal}
}

重载方法的分派是根据静态类型进行的,这个分派过程在编译时期就完成了。

双分派

在选择一个方法的时候,不仅仅要根据消息接收者的运行时区别,还要根据参数的运行时区别

public class Animal {public void accept(Execute execute){execute.execute(this);}
}public class Dog extends Animal{public void accept(Execute execute) {execute.execute(this);}
}public class Cat extends Animal{public void accept(Execute execute) {execute.execute(this);}
}public class Execute{public void execute(Animal animal){System.out.println("animal");}public void execute(Cat cat){System.out.println("cat");}public void execute(Dog dog){System.out.println("dog");}
}public class Test{public static void main(String[] args) {Animal animal = new Animal();Animal animal2 = new Cat();Animal animal3 = new Dog();Execute execute = new Execute();animal.accept(execute);  // animalanimal2.accept(execute); // catanimal3.accept(execute); // dog}
}

上面代码中,客户端将Execute对象作为参数传递给Animal类型的变量调用的方法,这里完成第一次分派,这里是方法重写,所以是动态分派,也就是执行实际类型中的方法,同时也是将自己this作为参数传递进去,这里就完成了第二次分派,这里的Execute类中有多个重载的方法,而传递进行的是this,就是具体的实际类型的对象。
双分派实现动态绑定的本质,就是在重载方法委派的前面加上了继承体系中覆盖的环节,由于覆盖是动态的,所以重载就是动态的了。

http://www.hkea.cn/news/108098/

相关文章:

  • 可以做试卷的网站英语怎么说seo关键词排名优化系统源码
  • 网站怎么设置支付功能企业网站的主要类型有
  • 成都圣都装饰装修公司北京搜索优化排名公司
  • 境外建设网站贴吧互联网域名注册查询
  • 广州建站工作室淘客推广怎么做
  • 中国最大的网站建设公司百度广告联盟点击一次多少钱
  • wordpress单页主题营销seo手机关键词网址
  • dedecms做电影网站韩国最新新闻
  • 哪个网站做废旧好如何在百度上发布自己的广告
  • 网站表单及商品列表详情模板如何搭建自己的网站
  • 网站域名登记证明百度高级搜索怎么用
  • 国外网站在国内做镜像站点网站搭建费用
  • 网站后台如何添加关键词软件开发公司
  • 手机做网站的网站windows优化大师卸载不了
  • 万网速成网站有哪些 功能自己的网站怎么推广
  • 邯郸哪有做网站的河南百度推广公司
  • 我是做环保类产品注册哪些浏览量大的网站推销自己的产品比较好呢西安网站seo优化公司
  • 网页传奇游戏排行昆明网络推广优化
  • 商城模板网站模板网站软文是什么
  • 校园网站推广方案怎么做网站排名推广工具
  • 深圳罗湖企业网站建设报价网络媒体发稿平台
  • 用别人公司域名做网站线下推广的渠道和方法
  • php mysql的网站开发外贸推广平台
  • 济南网站建设认可搜点网络能百度指数有三个功能模块
  • 网上商城网站建设意义在线代理浏览网页
  • 网站图片切换代码百度下载并安装最新版
  • 微信公众平台号申请注册入口杭州seo公司
  • 本周实时热点新闻事件seo文章代写一篇多少钱
  • 旺店通app手机企业版下载网站seo如何优化
  • 宝山区建设用地事务所网站网络公司有哪些