设计模式第19篇:访问者模式

一.访问者模式介绍

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

二.访问者模式代码用例

  此处以购物车为例来说明,比如不同的商品有不同的结算方式,如果将商品的结算逻辑方法放在商品对象内部,则商品参加打折活动时又需要更改商品类,并且商品种类时非常多的,此时程序将变得不可维护。访问者模式就是解决这个问题,将每个商品的结算逻辑抽取出来,放在访问者(Visitor)类中,商品类中只需有接收访问者的方法accept(Visitor visitor)即可。

  1.商品类接口(抽象类也行,此处用接口)

interface ItemElement {

         int accept(ShoppingCartVisitor visitor);
}    

  2.商品类实例Book、Fruit

class Book implements ItemElement {

    private int price;
    private String isbnNumber;

    public Book(int cost, String isbn){
        this.price=cost;
        this.isbnNumber=isbn;
    }

    public int getPrice() {
        return price;
    }

    public String getIsbnNumber() {
        return isbnNumber;
    }

    @Override
    public int accept(ShoppingCartVisitor visitor) {
        return visitor.visit(this);
    }

}

class Fruit implements ItemElement {

    private int pricePerKg;
    private int weight;
    private String name;

    public Fruit(int priceKg, int wt, String nm){
        this.pricePerKg=priceKg;
        this.weight=wt;
        this.name = nm;
    }

    public int getPricePerKg() {
        return pricePerKg;
    }

    public int getWeight() {
        return weight;
    }

    public String getName(){
        return this.name;
    }

    @Override
    public int accept(ShoppingCartVisitor visitor) {
        return visitor.visit(this);
    }

}

  3.访问者接口ShoppingCarVisitor

interface ShoppingCartVisitor {

    int visit(Book book);
    int visit(Fruit fruit);
}

  4.访问者接口实现ShoppingCarVisitorImpl

class ShoppingCartVisitorImpl implements ShoppingCartVisitor {

    @Override
    public int visit(Book book) {
        int cost=0;
        //apply 5$ discount if book price is greater than 50
        if(book.getPrice() > 50){
            cost = book.getPrice()-5;
        }else cost = book.getPrice();
        System.out.println("Book ISBN::"+book.getIsbnNumber() + " cost ="+cost);
        return cost;
    }

    @Override
    public int visit(Fruit fruit) {
        int cost = fruit.getPricePerKg()*fruit.getWeight();
        System.out.println(fruit.getName() + " cost = "+cost);
        return cost;
    }

}

  5.测试

public class ShoppingCartClient {

    public static void main(String[] args) {
        ItemElement[] items = new ItemElement[]{new Book(20, "1234"),new Book(100, "5678"),
                new Fruit(10, 2, "Banana"), new Fruit(5, 5, "Apple")};

        int total = calculatePrice(items);
        System.out.println("Total Cost = "+total);
    }

    private static int calculatePrice(ItemElement[] items) {
        ShoppingCartVisitor visitor = new ShoppingCartVisitorImpl();
        int sum=0;
        for(ItemElement item : items){
            sum = sum + item.accept(visitor);
        }
        return sum;
    }

}

三.访问者模式使用场景及优缺点

场景:1.对象结构比较稳定,但经常需要在此对象结构上定义新的操作。

   2.需要对一个对象结构中的对象进行很多不同的且不相关的操作,而需要避免这些操作“污染”这些对象的类,也不希望在增加新操作时修改这些类。

优点:

   1.使得数据结构和作用于结构上的操作解耦,使得操作集合可以独立变化。

      2.添加新的操作或者说访问者会非常容易。

      3.将对各个元素的一组操作集中在一个访问者类当中。

      4.使得类层次结构不改变的情况下,可以针对各个层次做出不同的操作,而不影响类层次结构的完整性。

      5.可以跨越类层次结构,访问不同层次的元素类,做出相应的操作。

缺点:

      1.增加新的元素会非常困难。

   2.实现起来比较复杂,会增加系统的复杂性。

   3.破坏封装,如果将访问行为放在各个元素中,则可以不暴露元素的内部结构和状态,但使用访问者模式的时候,为了让访问者能获取到所关心的信息,元素类不得不暴露出一些内部的状态和结构。

适用性:

     1.数据结构稳定,作用于数据结构的操作经常变化的时候。

     2.当一个数据结构中,一些元素类需要负责与其不相关的操作的时候,为了将这些操作分离出去,以减少这些元素类的职责时,可以使用访问者模式。

     3.有时在对数据结构上的元素进行操作的时候,需要区分具体的类型,这时使用访问者模式可以针对不同的类型,在访问者类中定义不同的操作,从而去除掉类型判断。

原文地址:https://www.cnblogs.com/quxiangxiangtiange/p/10305500.html

时间: 2024-10-23 11:47:45

设计模式第19篇:访问者模式的相关文章

(19)访问者模式

(19)访问者模式 定义:封装某些作用于某种数据结构中各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作. 类型:行为类模式 类图: 访问者模式可能是行为类模式中最复杂的一种模式了,但是这不能成为我们不去掌握它的理由.我们首先来看一个简单的例子,代码如下: class A { public void method1(){ System.out.println("我是A"); } public void method2(B b){ b.showA(this); }

Java设计模式(十一)访问者模式 中介者模式

(二十一)访问者模式 对已存在的类进行扩展,通常需要增加方法,但是如果需要的行为与现有的对象模型不一致,或者无法修改现有代码.在这种情况下,不更改类的层次结构,就无法扩展该层次结构的行为.如果运用了访问者模式,就可以支持开发人员扩展该类层次结构的行为. 和解释器模式一样,访问者模式通常是基于合成模式的. 访问者模式在不改变类层次结构的前提下,对该层次结构进行扩展. interface Visitor{ public void visit(VisiSubject sub); } interface

设计模式23:Visitor 访问者模式(行为型模式)

Visitor 访问者模式(行为型模式) 动机(Motivation)在软件构造过程中,由于需求的改变,某些类层次结构中常常需要增加新的行为(方法),如果直接在基类中做这样的修改,将会给子类带来繁重的变更负担,甚至破坏原有设计. 如果在不变更类层次结构的前提下,在运行时更加需要透明地为类层次结构上的各个类活动添加新的操作,从而避免上述问题? 意图(Intent) 表示一个作用于某种对象结构中各元素的操作.它可以在不改变各元素的类的前提下定义作用于这些元素的新操作.——<设计模式>GoF 示例代

设计模式学习总结(21) 访问者模式

本系列主要记录设计模式的意图是什么,它要解决一个什么问题,什么时候可以使用它:它是如何解决的,掌握它的结构图,记住它的关键代码:能够想到至少两个它的应用实例,一个生活中的,一个软件中的:这个模式的优缺点是什么,其有哪些使用场景,在使用时要注意什么. 尊重作者,转载请注明晔阳的Bloghttp://blog.csdn.net/hacke2 21.访问者模式 意图:主要讲数据结构与数据操作分离 主要解决:稳定的数据结构和易变的操作耦合问题 什么时候使用:与类本不相关的,为了避免这个污染 ,使用访问者

设计模式(十七)访问者模式(Visitor)-行为型

访问者模式Visitor 访问者模式(Visitor Pattern)是GoF提出的23种设计模式中的一种,属于行为模式.据<大话设计模式>中说算是最复杂也是最难以理解的一种模式了. 定义(源于GoF<Design Pattern>):表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作. 从定义可以看出结构对象是使用访问者模式必备条件,而且这个结构对象必须存在遍历自身各个对象的方法.这便类似于Java语言当中的collection

大战设计模式【24】—— 访问者模式

访问者模式(Visitor) 设计模式使用的例子https://github.com/LinkinStars/DesignPatternsAllExample 一.定义 提供一个作用于某对象结构中的各元素的操作表示,它使得可以在不改变各元素的类的前提下定义作用于这些元素的新操作. 二.结构 Visitor(抽象访问者):抽象访问者为对象结构中每一个具体元素类ConcreteElement声明一个访问操作, 从这个操作的名称或参数类型可以清楚知道需要访问的具体元素的类型,具体访问者则需要实现这些操

大话设计模式读书笔记--23.访问者模式

定义 访问者模式定义: 表示一个作用于某对象结构中的各元素的操作,它使你在不改变各元素的类的前提下,定义作用于这些元素的新操作 把数据结构, 和作用于数据结构上的操作,分离 模式结构 代码实现 场景: 男人和女人谈恋爱,男人的状态和女人的状态 代码实现:点击下载 特点和使用场景 优点:很容易增加新的操作 缺点: 使增加新的数据结构变得困难 使用场景: 数据结构相对稳定的系统

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

一.定义 访问者模式:表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用与这些元素的新操作. 解释:一个对象,如果它的元素是固定的,那么可以使用访问者模式定义它们的操作,使得操作可以自由的增加或者减少而不影响系统的其它部分. 二.UML类图及基本代码 基本代码: abstract class Visitor { public abstract void VisitConcreteElementA(ConcreteElementA concreteElement

设计模式第四篇-工厂模式

一.引言 园子里有关设计模式的文章可以说数不胜数,之前也看过很多,但是其实理解都不深入,时间一长就忘了.最好是记录下来,总结中加深印象,这里也给刚开始进行开发的同学提个建议,不要因为自己写的不好而不去写,谁都是从菜鸟开始的,不断的总结才能将知识消化成自己的. 现在开始今天的学习. 工厂模式是设计模式中很重要的一个模式,其中有简单工厂模式(并不能算一个模式),工厂模式,抽象工厂模式. 工厂模式,从名字可以看出,这是一个创建型的模式,是用来创建对象.我们从简单工厂模式开始 二.简单工厂模式 简单工厂