`
sun201200204
  • 浏览: 294461 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

关于23种设计模式的有趣见解 --- VISITOR

    博客分类:
  • java
阅读更多
好久没发贴了。现在大家都在讨论设计模式,今天也来火一把:)
就把http://www.jdon.com上看到的有个《关于23种设计模式的有趣见解》解答一下,请大家拍砖。
先从VISITOR开始吧:

VISITOR—情人节到了,要给每个MM送一束鲜花和一张卡片,可是每个MM送的花都要针对她个人的特点,每张卡片也要根据个人的特点来挑,我一个人哪搞得清楚,还是找花店老板和礼品店老板做一下Visitor,让花店老板根据MM的特点选一束花,让礼品店老板也根据每个人特点选一张卡,这样就轻松多了;
       
访问者模式:访问者模式的目的是封装一些施加于某种数据结构元素之上的操作。一旦这些操作需要修改的话,接受这个操作的数据结构可以保持不变。访问者模式适用于数据结构相对未定的系统,它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由的演化。访问者模式使得增加新的操作变的很容易,就是增加一个新的访问者类。访问者模式将有关的行为集中到一个访问者对象中,而不是分散到一个个的节点类中。当使用访问者模式时,要将尽可能多的对象浏览逻辑放在访问者类中,而不是放到它的子类中。访问者模式可以跨过几个类的等级结构访问属于不同的等级结构的成员类。

先上代码:
先实现美女类,用四大美女来模拟。
package com.test.girl;

public interface Girl {
	void flow();
	void card();
}

package com.test.girl;

public class XiShi implements Girl {

	@Override
	public void card() {
		System.out.println("credit card");
	}

	@Override
	public void flow() {
		System.out.println("rose");
	}
}

package com.test.girl;

public class DiaoChan implements Girl {

	@Override
	public void card() {
		System.out.println("shop card");
	}

	@Override
	public void flow() {
		System.out.println("peony");
	}

}

package com.test.girl;

public class WangZhaojun implements Girl {

	@Override
	public void card() {
		System.out.println("king card");
	}

	@Override
	public void flow() {
		System.out.println("orchid");
	}
}

package com.test.girl;

public class YangYuhuan implements Girl {

	@Override
	public void card() {
		System.out.println("vip card");
	}

	@Override
	public void flow() {
		System.out.println("plum blossom");
	}
}

下面定义观察者:
package com.test.visitor;

public interface Visitor {
	void visit();
	void add(Object obj);
	void remove(Object obj);
}

这里只实现花店:
package com.test.visitor;

import java.util.ArrayList;
import java.util.List;

import com.test.girl.Girl;

public class Flowor implements Visitor {

	private List<Girl> girls = new ArrayList<Girl>();
	
	@Override
	public void visit() {
		for(Girl g:girls){
			g.flow();
		}
	}
	@Override
	public void add(Object g){
		girls.add((Girl)g);
	}
	@Override
	public void remove(Object g){
		girls.remove((Girl)g);
	}
}

写测试类:
package com.test.visitor;

import com.test.girl.DiaoChan;
import com.test.girl.Girl;
import com.test.girl.WangZhaojun;
import com.test.girl.XiShi;
import com.test.girl.YangYuhuan;

public class VisitorTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Visitor v = new Flowor();
		Girl 西施 = new XiShi();
		Girl 貂蝉 = new DiaoChan();
		Girl 王昭君 = new WangZhaojun();
		Girl 杨玉环 = new YangYuhuan();
		v.add(西施);
		v.add(貂蝉);
		v.add(王昭君);
		v.add(杨玉环);
		
		v.visit();
		System.out.println("+++++++++++");
		v.remove(杨玉环);
		v.visit();
	}
}
分享到:
评论
5 楼 liuyizhang 2010-02-09  
前面观察者模式写的有点问题
4 楼 sun201200204 2010-02-02  
<p>这个模式凭着感觉写出来的,这个应该是观察者模式。写错了。<br>修正一下。<br>1.类图:(摘自:<a href="http://zh.wikipedia.org/wiki/%E8%AE%BF%E9%97%AE%E8%80%85%E6%A8%A1%E5%BC%8F">http://zh.wikipedia.org/wiki/%E8%AE%BF%E9%97%AE%E8%80%85%E6%A8%A1%E5%BC%8F</a>)<br><img src="http://dl.iteye.com/upload/picture/pic/54195/f2f3eef6-a588-3240-bd7e-78f23f2a52d3.png" alt="visitor" width="624" height="502"></p>
<p> </p>
<p>2.DEMO:</p>
<p> </p>
<p>元素角色:定义一个accept操作,它以一个访问者为参数。</p>
<pre name="code" class="java">package com.test.girl;

import com.test.visitor.Visitor;

public interface Girl {
void accept(Visitor visitor);
void flower();
void card();
}</pre>
<p> 下面是具体的元素角色:</p>
<pre name="code" class="java">package com.test.girl;

import com.test.visitor.Visitor;


public class DiaoChan implements Girl {

@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}

/**
* 腊梅
*/
@Override
public void flower() {
System.out.println("winter sweet");
}

@Override
public void card() {
System.out.println("shopping card");
}

}</pre>
<p> </p>
<pre name="code" class="java">package com.test.girl;

import com.test.visitor.Visitor;

public class WangZhaojun implements Girl {

@Override
public void card() {
System.out.println("king card");
}

@Override
public void flower() {
System.out.println("orchid");
}


@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}</pre>
<p> </p>
<pre name="code" class="java">package com.test.girl;

import com.test.visitor.Visitor;

public class XiShi implements Girl {

@Override
public void card() {
System.out.println("credit card");
}

@Override
public void flower() {
System.out.println("rose");
}

@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}</pre>
<p> </p>
<pre name="code" class="java">package com.test.girl;

import com.test.visitor.Visitor;


public class YangYuhuan implements Girl {

@Override
public void card() {
System.out.println("vip card");
}

@Override
public void flower() {
System.out.println("plum blossom");
}

@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}</pre>
<p> 访问者角色(Visitor):为该对象结构中具体元素角色声明一个访问操作接口。该操作接口的名字和参数标识了发送访问请求给具体访问者的具体元素角色。这样访问者就可以通过该元素角色的特定接口直接访问它。</p>
<pre name="code" class="java">package com.test.visitor;

import com.test.girl.DiaoChan;
import com.test.girl.WangZhaojun;
import com.test.girl.XiShi;
import com.test.girl.YangYuhuan;

public interface Visitor {
void visit(DiaoChan diaoChan);
void visit(WangZhaojun wangZhaojun);
void visit(XiShi xiShi);
void visit(YangYuhuan yangYuhuan);
}</pre>
<p> </p>
<p>下面是具体访问者:</p>
<pre name="code" class="java">package com.test.visitor;

import com.test.girl.DiaoChan;
import com.test.girl.WangZhaojun;
import com.test.girl.XiShi;
import com.test.girl.YangYuhuan;

/**
* record every girl's flower.
* @author Dave Li
*
*/
public class FlowerBoss implements Visitor {

@Override
public void visit(DiaoChan diaoChan) {
diaoChan.flower();
}

@Override
public void visit(WangZhaojun wangZhaojun) {
wangZhaojun.flower();
}

@Override
public void visit(XiShi xiShi) {
xiShi.flower();
}

@Override
public void visit(YangYuhuan yangYuhuan) {
yangYuhuan.flower();
}

}</pre>
<p> 对象结构角色(Object Structure):这是使用访问者模式必备的角色。它要具备以下特征:</p>
<p>      1)能枚举它的元素;</p>
<p>      2)可以提供一个高层的接口以允许该访问者访问它的元素;</p>
<p>      3)可以是一个复合(组合模式)或是一个集合,如一个列表或一个无序集合。</p>
<pre name="code" class="java">package com.test.visitor;

import com.test.girl.DiaoChan;
import com.test.girl.Girl;
import com.test.girl.WangZhaojun;
import com.test.girl.XiShi;
import com.test.girl.YangYuhuan;
/*
* 采购鲜花
*/
public class FlowerPurchase {

private Girl[] girls = {new DiaoChan(),
new WangZhaojun(),
new XiShi(),
new YangYuhuan()};

public void purchase(Visitor v){
for(Girl girl:girls){
girl.accept(v);
}
}
}</pre>
<p> </p>
<p>测试类:</p>
<pre name="code" class="java">package com.test.visitor;

public class Test {
public static void main(String[] args) {
FlowerPurchase purchase = new FlowerPurchase();
purchase.purchase(new FlowerBoss());
}
}</pre>
<p> </p>
<p>3.特点:</p>
<p>双重分配:</p>
<p>             purchase.purchase(new FlowerBoss());(给每个具体的角色分派一个具体观察者)。</p>
<p>             visitor.visit(this);具体访问者模式再根据参数的不同来选择方法来执行。</p>
<p> </p>
<p>在两个接口Visitor和Girl中,确保Girl很少变化,也就是说,确保不能老有新的Element元素类型加进来,可以变化的是访问者行为或操作,也就是Visitor的不同子类可以有多种,这样使用访问者模式最方便.</p>
<p>所以这个例子不太合适,花店的顾客是不断变化的,girl也是不断变化的。</p>
<p> </p>
<p>4,适用场合:</p>
<p>《设计模式》一书中给出了访问者模式适用的情况:<br><br>  1) 一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依赖于其具体类的操作。<br><br>  2) 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而你想避免让这些操作“污染”这些对象的类。Visitor使得你可以将相关的操作集中起来定义在一个类中。<br><br>  3) 当该对象结构被很多应用共享时,用Visitor模式让每个应用仅包含需要用到的操作。<br><br>  4) 定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。改变对象结构类需要重定义对所有访问者的接口,这可能需要很大的代价。如果对象结构类经常改变,那么可能还是在这些类中定义这些操作较好。</p>
3 楼 jashawn 2010-01-30  
这明显不是visitor...偏差太大了……你的visitor居然和你要访问的东西是聚合关系。
2 楼 joknm 2010-01-29  
有点适配器的味道。
1 楼 ahuango 2010-01-29  
从代码没看出Vistor 的真谛

相关推荐

    设计模式精解-GoF 23种设计模式解析

    设计模式精解-GoF 23 种设计模式解析附 C++实现源码 目 录 引 言 0.1 设计模式解析(总序) 0.2 设计模式解析后记 0.3 与作者联系 1 创建型模式 1.1 Factory模式 1.2 AbstactFactory模式 1.3 Singleton...

    设计模式C++学习之访问者模式(Visitor)

    设计模式C++学习之访问者模式(Visitor)

    C#设计模式-吕震宇

    设计模式(20)-Visitor Pattern 设计模式(19)-Observer Pattern 设计模式(18)-Command Pattern 设计模式(17)-Chain of Responsibility Pattern 设计模式(16)-Bridge Pattern 设计模式(15)-Facade ...

    设计模式精解-GoF 23种设计模式解析附C++实现源码.pdf

    设计模式精解-GoF 23种设计模式解析附C++实现源码 目 录 0 引言.........................................................................................................................................

    设计模式精解(GoF 23种设计解析附C++实现源码)

    1.5 Prototype模式...................................................................................................................23 2 结构型模式........................................................

    设计模式精解-GoF 23 种设计模式解析附 C++实现源码.rar

    设计模式精解-GoF 23 种设计模式解析附 C++实现源码 目 录 0 引言 ............................................................................................................................................

    用Java实现23种设计模式

    用Java实现23种设计模式 1. 创建型模式 工厂模式(Factory Pattern) 抽象工厂模式(Abstract Factory Pattern) 单例模式(Singleton Pattern) 建造者模式(Builder Pattern) 原型模式(Prototype Pattern)...

    java版本二十三种设计模式.zip

    - 23种设计模式 - 工厂方法模式(Factory Method) - 抽象工厂模式(Abstract Factory) - 单例模式(Singleton) - 建造者模式(Builder) - 原型模式(Prototype) - 代理模式(Proxy) - 适配器模式(Adapter) - 装饰...

    C#设计模式之Visitor

    C#设计模式之1 --- Visitor (附原码)

    设计模式--C++

    1.6 设计模式怎样解决设计问题 8 1.6.1 寻找合适的对象 8 1.6.2 决定对象的粒度 9 1.6.3 指定对象接口 9 1.6.4 描述对象的实现 10 1.6.5 运用复用机制 13 1.6.6 关联运行时刻和编译时刻的结构 15 1.6.7 设计应支持...

    36种最新设计模式整理

    36种最新设计模式整理 Design Pattern: Simple Factory 模式 Design Pattern: Abstract Factory 模式 Design Pattern: Builder 模式 Design Pattern: Factory Method 模式 Design Pattern: Prototype 模式 ...

    23种设计模式 - 各种模式的学习

    23种设计模式 目录 创建型 1. Factory Method(工厂方法) 2. Abstract Factory(抽象工厂) 3. Builder(建造者) 4. Prototype(原型) 5. Singleton(单例) 结构型 6. Adapter Class/Object(适配器) ...

    单例模式源码java-DesignPattern:在个人自学阶段的23种设计模式代码的全部实现,全部使用Java编写,其中还包括各个设计模式在

    在个人自学阶段的23种设计模式代码的全部实现,全部使用Java编写,其中还包括各个设计模式在源码中的使用,每种设计模式都举了一个简单的小例子来进行实现,并加以注释 包名解释 一、DesignPattern 1.1 创建型模式 ...

    设计模式-访问者(Visitor)模式详解和应用.pdf

    设计模式 -访问者(Visitor)模式详解和应用.pdf

    设计模式(23种)与设计原则(6种)

    详细描述全部(23种)设计模式与设计原则(6种)。 (一)设计原则包括: 1、开闭原则 2、里氏代换原则 3、依赖转换原则 4、接口隔离原则 5、合成/聚合复用原则 6、最少知识原则 (二)设计模式 1)工厂模式...

    C#23种设计模式_示例源代码及PDF

    观察者模式: 让多个观察者对象同时监听某一个 观察者模式 观察者模式定义了一种一队多的依赖关系, 主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使他们能够自动更 新自己。 20、STATE —...

    设计模式系列之visitor

    博文链接:https://notguru.iteye.com/blog/78260

    试试visitor设计模式

    也许最开始出现这种模式,是因为另外的原因: 我有一堆数据放在一个库里头,不想让其它人拿着, 如果你要用数据干活,那你就把函数指针给我,我来替你使用这个数据。...然后人们就说,这是visitor模式。

    Laravel开发-visitor-log

    Laravel开发-visitor-log Laravel 4记录所有访客的包

    精心整理的23种python设计模式代码

    代码都可以直接运行,部分设计模式有多种实现,主要的设计模式如下:Creational-abstract_factory,Creational-factory_method,Creational-simple_factory,Creational-singleton,Creational-builder,Creational-...

Global site tag (gtag.js) - Google Analytics