- 浏览: 194547 次
- 性别:
- 来自: 厦门
文章分类
最新评论
-
行者买刀:
qxpidt 写道楼主,我想问下,嵌套这些WEB应用后,如何操 ...
JDIC一个能够用java调用ie内核的包 -
qxpidt:
楼主,我想问下,嵌套这些WEB应用后,如何操作你登录的COOK ...
JDIC一个能够用java调用ie内核的包 -
lookforwarding:
...
java重写JSplitPane的UI,设置分隔条的颜色 -
v韧竹v:
最后那个抽象工厂模式,CarType是不是定义错了,应该abs ...
设计模式之略见一斑(工厂模式Factory) -
l7810:
这与模板模式有什么区别啊?
设计模式之略见一斑(建造模式builder)
在开发中,我们可能会经常碰到客户提了一新的需求,那么在现有的类实现新的需求呢?通常的做法是添加新的方法。但是有时候我们只能看到接口,而根本无法看到其接口实现。这个时候我们就无法往接口里添加接的方法。但是,开发人员能够多大设计的时候采用Visitor模式的话,结果就大不一样了。
Visitor模式就是让代码用户能够在不修改现有类层次结构的情况下,定义该类层次结构的操作。
例子:
关于访问者模式的JE上的例子比较多,而且争议也比较大。下面就举出个常见的Visitor模式的例子,欢迎拍砖。
如一个公司里有老板,经理,员工三种角色,每个角色都继续Human这个类,对于Human这个类,我们定义为抽象的
public abstract class Human { protected int id; //该人物所管理的人员,如果是老板那么那就可管理经理 protected List<? extends Human> list = new ArrayList<Human>(); public List<? extends Human> getList() { return list; } public void setList(List<? extends Human> list) { this.list = list; } public int getId() { return id; } public void setId(int id) { this.id = id; } public void accept(Visitor visitor){ } }
其三种角色都继续这个Human类:
public class Boss extends Human { public Boss(int id){ this.id = id; } @Override public void accept(Visitor visitor) { visitor.visit(this); } public String toString(){ return new StringBuffer("Manager the id:"+id).toString(); } } public class Manager extends Human { public Manager(int id){ this.id = id; } @Override public void accept(Visitor visitor) { visitor.visit(this); } public String toString(){ return new StringBuffer("Manager the id:"+id).toString(); } } public class Employee extends Human{ public Employee(int id){ this.id = id; } @Override public void accept(Visitor visitor) { visitor.visit(this); } public String toString(){ return new StringBuffer("Employee the id:"+id).toString(); } }
在我们构造这些公司的成员时, 我假设用如下方法构造:
Boss boss = new Boss(1); List<Manager> managers = new ArrayList<Manager>(); for(int i =2;i<10;i++){ Manager manager = new Manager(i); List<Employee> employees = new ArrayList<Employee>(); int k = i*10; for(int j = k;j<k+8;j++){ employees.add(new Employee(j)); } manager.setList(employees); managers.add(manager); } boss.setList(managers);
于是这个时候,我想查询员工号为20的员工的相关信息.当然我可以直接从Boss开始,然后遍历他的List列表,以及子列表。实现如下:
public static Human getHuman(Human human, int id) { if (human.getId() != id) { List<Human> ms = (List<Human>) human.getList(); for (Human h : ms) { if(getHuman(h,id)!=null){ return getHuman(h,id); }else{ return null; } } return null; } else { return human; } }
但是我们想用访问者模式来实现它,于是我们定义一个访问者接口:
/** * 访问员工接口 * @author Administrator * */ public interface Visitor { public void visit(Employee employee); public void visit(Human human); }
接口实现如下:
public class FindVisitor implements Visitor{ private int soughtId; private Human found; public void visit(Employee employee) { if(found==null&&employee.getId()==soughtId){ found=employee; } } public void visit(Human human) { if(found==null&&human.getId()==soughtId){ found=human; return; } List<? extends Human> list = human.getList(); for(Human e:list){ if(found==null) e.accept(this); } } public Human find(Human mc,int id){ found = null; soughtId = id; mc.accept(this); return found; } }
下面做一下简单的测试吧:
FindVisitor fv =new FindVisitor(); Human human = fv.find(boss, 20); System.out.println("find:"+ human);
小结:
访问者模式可以让我们在不改变类层次结构中的类的情况下,为该类层次结构定义新的操作。如上面的例子,如果想添加新的需求,如要找某个员工号,并修改员工信息,于是我们可以新增接口方法,并添加实现。在类层次结构中添加访问器将调用accept()方法,accept()方法通过采用”两次分开“技术将调用结果返回给访问器类。visit()方法定义在访问器类中,类层次结构中的某个类对象可以根据其类型调用合适的visti()方法。
访问器类的开发人员必须清楚将要访问的类层次结构的全部或者部分设计细节。另外,在设计访问器类的时候,我们必须特别注意被访问的对象模型中可能会出现环状结构。考虑到这些问题, 一些开发人员常常会有意避免使个访问者框框。习惯地使用其他方案替换。一般而言,软件开发团队需要根据自己所采用的软件开发方法学,根据项目组以及具体项目的具体情况使用访问者模式 。
评论
<div class="quote_div">
<p> 在开发中,我们可能会经常碰到客户提了一新的需求,那么在现有的类实现新的需求呢?通常的做法是添加新的方法。但是有时候我们只能看到接口,而根本无法看到其接口实现。这个时候我们就无法往接口里添加接的方法。但是,开发人员能够多大设计的时候采用Visitor模式的话,结果就大不一样了。</p>
<p> </p>
<p><strong>Visitor模式就是让代码用户能够在不修改现有类层次结构的情况下,定义该类层次结构的操作。</strong></p>
<p><strong></strong></p>
<p>例子:</p>
<p> 关于访问者模式的JE上的例子比较多,而且争议也比较大。下面就举出个常见的Visitor模式的例子,欢迎拍砖。</p>
<p> </p>
<p>如一个公司里有老板,经理,员工三种角色,每个角色都继续Human这个类,对于Human这个类,我们定义为抽象的</p>
<pre name="code" class="java">public abstract class Human {
protected int id;
//该人物所管理的人员,如果是老板那么那就可管理经理
protected List<? extends Human> list = new ArrayList<Human>();
public List<? extends Human> getList() {
return list;
}
public void setList(List<? extends Human> list) {
this.list = list;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public void accept(Visitor visitor){
}
}
</pre>
<p> </p>
<p> </p>
<p>其三种角色都继续这个Human类:</p>
<pre name="code" class="java">public class Boss extends Human {
public Boss(int id){
this.id = id;
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
public String toString(){
return new StringBuffer("Manager the id:"+id).toString();
}
}
public class Manager extends Human {
public Manager(int id){
this.id = id;
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
public String toString(){
return new StringBuffer("Manager the id:"+id).toString();
}
}
public class Employee extends Human{
public Employee(int id){
this.id = id;
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
public String toString(){
return new StringBuffer("Employee the id:"+id).toString();
}
}</pre>
<p> </p>
<p> </p>
<p> </p>
<p>在我们构造这些公司的成员时, 我假设用如下方法构造:</p>
<pre name="code" class="java">Boss boss = new Boss(1);
List<Manager> managers = new ArrayList<Manager>();
for(int i =2;i<10;i++){
Manager manager = new Manager(i);
List<Employee> employees = new ArrayList<Employee>();
int k = i*10;
for(int j = k;j<k+8;j++){
employees.add(new Employee(j));
}
manager.setList(employees);
managers.add(manager);
}
boss.setList(managers);</pre>
<p> </p>
<p>于是这个时候,我想查询员工号为20的员工的相关信息.当然我可以直接从Boss开始,然后遍历他的List列表,以及子列表。实现如下:</p>
<pre name="code" class="java"> public static Human getHuman(Human human, int id) {
if (human.getId() != id) {
List<Human> ms = (List<Human>) human.getList();
for (Human h : ms) {
if(getHuman(h,id)!=null){
return getHuman(h,id);
}else{
return null;
}
}
return null;
} else {
return human;
}
}</pre>
<p> </p>
<p>但是我们想用访问者模式来实现它,于是我们定义一个访问者接口:</p>
<pre name="code" class="java">/**
* 访问员工接口
* @author Administrator
*
*/
public interface Visitor {
public void visit(Employee employee);
public void visit(Human human);
}
</pre>
<p> </p>
<p>接口实现如下:</p>
<pre name="code" class="java">public class FindVisitor implements Visitor{
private int soughtId;
private Human found;
public void visit(Employee employee) {
if(found==null&&employee.getId()==soughtId){
found=employee;
}
}
public void visit(Human human) {
if(found==null&&human.getId()==soughtId){
found=human;
return;
}
List<? extends Human> list = human.getList();
for(Human e:list){
if(found==null)
e.accept(this);
}
}
public Human find(Human mc,int id){
found = null;
soughtId = id;
mc.accept(this);
return found;
}
}
</pre>
<p> </p>
<p>下面做一下简单的测试吧:</p>
<pre name="code" class="java">FindVisitor fv =new FindVisitor();
Human human = fv.find(boss, 20);
System.out.println("find:"+ human);</pre>
<p> </p>
<p>小结:</p>
<p> 访问者模式可以让我们在不改变类层次结构中的类的情况下,为该类层次结构定义新的操作。如上面的例子,如果想添加新的需求,如要找某个员工号,并修改员工信息,于是我们可以新增接口方法,并添加实现。在类层次结构中添加访问器将调用accept()方法,accept()方法通过采用”两次分开“技术将调用结果返回给访问器类。visit()方法定义在访问器类中,类层次结构中的某个类对象可以根据其类型调用合适的visti()方法。</p>
<p> </p>
<p> 访问器类的开发人员必须清楚将要访问的类层次结构的全部或者部分设计细节。另外,在设计访问器类的时候,我们必须特别注意被访问的对象模型中可能会出现环状结构。考虑到这些问题, 一些开发人员常常会有意避免使个访问者框框。习惯地使用其他方案替换。一般而言,软件开发团队需要根据自己所采用的软件开发方法学,根据项目组以及具体项目的具体情况使用访问者模式 。</p>
</div>
<p>其实我不懂什么visitor模式,我只是觉得Human类这样实现会更好:</p>
<p>
</p>
<pre name="code" class="java">public abstract class Human {
private final int id;
public Human(final int id){
this.id = id;
}
//该人物所管理的人员,如果是老板那么那就可管理经理
protected List<? extends Human> list = new ArrayList<Human>();
public List<? extends Human> getList() {
return list;
}
public void setList(List<? extends Human> list) {
this.list = list;
}
public final int getId() {
return id;
}
public final void setId(int id) {
this.id = id;
}
public abstract void accept(Visitor visitor);
}</pre>
访问者模式可以说假定变的是需求,不变的是用户信息
我也一直搞不明白这个模式,但这两句话让我很有感觉,似乎就是这么回事吧
有需要请教的地方:
不知道
# public void accept(Visitor visitor){
#
# }
这个方法有什么存在的理由
# public void visit(Human human) {
# if(found==null&&human.getId()==soughtId){
# found=human;
# return;
# }
# List<? extends Human> list = human.getList();
# for(Human e:list){
# if(found==null)
# e.accept(this); 把这里改成visit(e);效果是一样的
# }
# }
lz的这个例子是不是有问题?我总觉得这个visitor接口跟实际的类耦合在一起了 不爽!!
结果是一样的,但设计的时候会发现全不一样。
1. 从封闭性上讲,对象都有对外公开的东西,还有不公开的东西,
e就是被访问者,this就是访问者, e.accept(this)这个调用表示出访问的逻辑将在被访问者中实现,它可以很好地隐藏被访问者的私有内容,visit(e)意味着e必须公开大量信息给this,而this将被众多的e所公开的不同信息搞得焦头烂额。
2. 从模型建讲,它表达一对多的关系,它非常符合现实,一份资源总是被很多其它东西共享,比如一份文件,有人会把它下载下来,有人需要在页面上显示它的基本信息,还有人可能要把它emails给别人,你不可能把这些不同的逻辑都写在文件类里,因为文件生来就有,它不知道将来会有谁来使用自己。类似的例子,还有经理在每个年底访问自己的手下,访问者模式可以把访问过程从经理这里分享给手下,从而应对不同的手下。
accept和visit只是一种形式,在很多时候你可以将它倒置,表达你被不同的人访问,基本思想都是把逻辑放在多的一方,因为变化在多的一方。
有需要请教的地方:
不知道
# public void accept(Visitor visitor){
#
# }
这个方法有什么存在的理由
# public void visit(Human human) {
# if(found==null&&human.getId()==soughtId){
# found=human;
# return;
# }
# List<? extends Human> list = human.getList();
# for(Human e:list){
# if(found==null)
# e.accept(this); 把这里改成visit(e);效果是一样的
# }
# }
lz的这个例子是不是有问题?我总觉得这个visitor接口跟实际的类耦合在一起了 不爽!!
假定老板,经理,员工这三个角色都有自己的特有的东西,如工资,并且是不对外的,也就说没有getXX()方法,现在要工资调查组(FindVisitor )要调查他们的工资,并且不让彼此知道,要怎么办?。。。。
public class Employee extends Human{ public Employee(int id){ this.id = id; } @Override public void accept(Visitor visitor) { visitor.visit(this); } public String toString(){ return new StringBuffer("Employee the id:"+id).toString(); } }
这个时候可以在上面的
@Override
public void accept(Visitor visitor) {
//。。。可以在这里通过接口返回调查组所需要的工资
visitor.visit(this);
}
有需要请教的地方:
不知道
# public void accept(Visitor visitor){
#
# }
这个方法有什么存在的理由
# public void visit(Human human) {
# if(found==null&&human.getId()==soughtId){
# found=human;
# return;
# }
# List<? extends Human> list = human.getList();
# for(Human e:list){
# if(found==null)
# e.accept(this); 把这里改成visit(e);效果是一样的
# }
# }
lz的这个例子是不是有问题?我总觉得这个visitor接口跟实际的类耦合在一起了 不爽!!
发表评论
-
UtilCommon
2016-08-16 07:23 0aaaaaa -
Java面试题全集(上)
2016-08-14 17:23 0版权声明:本文为博 ... -
设计模式之略见一斑(Mediator中介者模式)
2010-02-25 10:07 1884设计模式 写道 通常,面向对象的软件开发要求尽可能 ... -
设计模式之略见一斑(Chain of Responsibility责任链模式)
2010-02-24 15:00 1497设计模式 写道 面向对 ... -
设计模式之略见一斑(Observer观察者模式)
2010-02-23 17:15 2211用户通常通过调用对象的方法来收集该对象的信息。但是当这 ... -
设计模式之略见一斑(Memento备忘录模式)
2010-02-23 11:46 1464有时候,我们需要 ... -
设计模式之略见一斑(Template Method模板方法模式)
2010-02-22 21:33 1442模板方法模式就是预 ... -
设计模式之略见一斑(策略模式strategy)
2010-02-22 17:56 1972java设计模式 写道 ... -
设计模式之略见一斑(状态模式State)
2010-02-22 15:42 1698设计模式中的状态模式相对比较简单,简单的说就是对某 ... -
设计模式之略见一斑(解释器模式Interpreter)
2010-02-22 10:27 3390解释器模式是 ... -
设计模式之略见一斑(命令模式Command)
2010-02-22 09:49 1557终于把构造模式的几种设计模式写完,接下来开始写的行为模 ... -
设计模式之略见一斑(享元模式flyweight)
2010-02-10 11:39 1441flyweight模式中文解释为轻量极模式,所以顾名 ... -
设计模式之略见一斑(代理模式Proxy)
2010-02-10 11:04 1969普通对象所需要完成的任务就是通过公共接口为外界提供自己所承诺的 ... -
设计模式之略见一斑(装饰模式decorator)
2010-02-09 11:08 1824标头:(引自设计模式 ... -
设计模式之略见一斑(组合模式Composite)
2010-02-08 14:45 1501定义: 将对象以树形结构组织起来,以达成"部 ... -
设计模式之略见一斑(外观模式Facade)
2010-02-07 09:30 1393外观模式又称门面模式,它是为了给子系统中提供一个一致的界面,从 ... -
设计模式之略见一斑(桥梁模式bridge)
2010-02-06 18:04 1561桥梁模式的宗旨就是将 ... -
设计模式之略见一斑(适配器模式Adapter)
2010-02-03 10:39 1608适配器模式就是基于客户提供的接口和功能,再此基础上实 ... -
设计模式之略见一斑(原型模式Prototype)
2010-02-01 17:15 1700原型模式允许一个对象 ... -
设计模式之略见一斑(建造模式builder)
2010-02-01 16:18 1765建造模式是将复杂的 ...
相关推荐
本篇文章将深入探讨“Observer”观察者模式,这是一种行为设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。 观察者模式的核心概念是主题...
《21种设计模式略见一斑》这篇文章和配套的"行者买刀21种设计模式详解.pdf"文件,是面向IT专业人士,尤其是软件开发者的一份珍贵资源,旨在深入理解并掌握软件设计中的核心概念——设计模式。设计模式是经验丰富的...
CRC的全称为Cyclic Redundancy Check,中文名称为循环冗余校验。它是一类重要的线性分组码,编码...例如我们读软盘上的文件,以及解压一个ZIP文件时,偶尔会碰到“Bad CRC”错误,由此它在数据存储方面的应用可略见一斑
综上所述,该报告以详细的数据和深入的分析为避雷器行业的企业决策者提供了宝贵的信息,帮助他们了解行业现状、预测未来趋势,并据此制定有效的竞合策略。对于电力行业和相关制造业来说,这份报告不仅能够帮助他们更...
10. **略见一斑**:形容从局部可以推测到整体的一部分情况。 11. **有口皆碑**:形容人们对某人或某事的赞扬之声普遍且一致。 12. **并行不悖**:两个或多个事情可以同时进行,彼此之间并不冲突。 13. **白璧微瑕**...
《现场活动大屏幕系统v1.1806221》是一款专为现场活动设计的多媒体展示系统,它的核心功能在于提供一个高效、稳定且易于操作的大屏幕展示平台。这款系统能够帮助活动组织者在活动现场实时展示各种信息,如活动进程、...
6. 略见一斑:从一点细微之处就能看出整体的情况或品质。 7. 班门弄斧:在专家面前卖弄自己的技能,暗示自不量力。 8. 英雄辈出:形容一个时代或群体中不断涌现出杰出的人物。 9. 并行不悖:两件事物同时进行而互不...
"略见一斑"意味着事情的端倪已经显现,“光明灿烂”和“辉煌”均形容美好前景,但前者更侧重于未来的可能性,后者侧重于实际的辉煌成就。因此,选B:希望光明,光明璀璨。 8. 经济形势描述:第八题中,“内热外冷”...
- (3) "我当时的想法,从这几段文字中也可以看出一点" 可以替换为 "言外之意,略见一斑"。 2. 动词填空: - ① "暗夜渐渐__上天空,__上对面的屋顶" 可以填入 "爬上,爬满",表达夜晚降临的情景。"一切都__在朦胧...
1. 语文基础知识:题目涉及到词语辨析,如“心酸”与“辛酸往事”,“一般”与“略见一斑”,“过度”与“过渡时期”,“无谓”与“无私无畏”,“家世”与“处理家事”,“明智”与“淡泊明志”,“灌注”与...
3. 字形校正:题目中还包含了错别字的纠正,如A项中的“烦燥”应为“烦躁”,“甜言密语”应为“甜言蜜语”,B项中的“半响”应为“半晌”,“略见一班”应为“略见一斑”,C项中的“脉膊”应为“脉搏”,“歪风斜气...
12. "略见一斑"(lüè jiàn yī bān):从部分看出整体,通过局部了解全局。 13. "暴虎冯河"(bào hǔ píng hé):形容有勇无谋,冒险行事。 14. "有口皆碑"(yǒukǒu jiē bēi):形容人人称赞,具有很高的...
10. **略见一斑**:从局部看出事物的一部分特征,了解其大概。 11. **有口皆碑**:所有人都称赞,形容事迹或人品受到普遍赞扬。 12. **并行不悖**:两件事情可以同时进行,互不冲突。 13. **白璧微瑕**:完美的事物...
4. **黯然失色**:形容相比之下显得差远了,不如别人。同义词有“相形见绌”、“大相径庭”。反义成语如“光彩夺目”、“不相上下”。 5. **慷慨激昂**:形容精神振奋,情绪高昂,充满正气。同义词有“热血沸腾”、...
《爱的教育》的影响力之广泛,从它的翻译版本就能略见一斑。作为一部文学作品,它跨越国界和文化,成为全人类的精神财富。通过阅读《争吵》,学生不仅能够提升自己的语言表达能力,更能在情感和道德上得到深刻的教育...
10. **略见一斑**:通过部分了解整体,形容对事物的初步认识。 11. **有口皆碑**:所有人都称赞,表示对某人或某事的普遍好评。 12. **并行不悖**:两件事情同时进行,并不互相冲突。 13. **白璧微瑕**:比喻美好的...
- 《红楼梦》是中国古代四大名著之一,属于章回体小说,现有120回,前80回由曹雪芹创作,后40回一般认为是高鹗续写。曹雪芹,原名霑,字梦阮。《红楼梦》以贾、史、王、薛四大家族的兴衰为背景,以贾宝玉和林黛玉的...
例如,我们读软盘上的文件,以及解压一个 ZIP 文件时,偶尔会碰到“Bad CRC”错误,由此它在数据存储方面的应用可略见一斑。 CRC 的优点 CRC 的优点在于编码和解码方法简单,检错和纠错能力强,在通信领域广泛地...
题目2考察学生对汉字书写的准确性,如"烦燥"应为"烦躁"、"甜言密语"应为"甜言蜜语"、"颓垣"、"略见一班"应为"略见一斑"、"莫钟一是一言既出,驷马难追"中"莫钟一是"可能是错误,正确可能是"莫衷一是"。 3. 成语运用...