访客模式 无痕模式 区别
问候,
这周我们放开所有代数的内容,然后集中精力
面向对象编程的全部内容。 Java声称支持OO,因此
为什么不使用它? 在本周的文章中,我们将讨论一下何时
以及为什么要应用某些模式。 我们将从“访客”模式开始。
该模式也称为“双重调度”,在
这篇小文章的结尾。 这是故事:
假设前段时间您编写了一堆漂亮而有效的类; 他们是
真正的宝石。 为了本文的方便,让我们使用以下类:
public class Beautiful { ... }
public class Efficient { ... }
public class Gem { ... }
无需编写更多此类,也无需添加更多此类
他们的功能; 用户总是在集合中使用您的类对象; 他们
遍历集合并在其中调用对象的优良功能
集合。 理想的解决方案。
直到某个悲伤的日子,一位顾客出现了,身上满是钱,愿意付款并
他希望向您的班级添加一些其他功能。 他已经使用
您的课程,他对他们非常满意:他认为他们非常有效率,
美丽而真实的宝石。 但是...他希望向其中添加一些功能。
我们称这个客户为Fred。
您确实喜欢弗雷德愿意支付的钱,然后开始添加通缉犯
功能,直到下一个悲伤的日子Barney到来之前,您的表现还不错
在您的办公室,他也需要一些其他功能。 首先
他也愿意为此付出代价。 很高兴您告诉Barney
您也在为客户弗雷德(Fred)开发其他功能
此刻,您当然愿意接受这项任务。
Barney对此想法不感兴趣:他不喜欢Fred的新增功能
在他的最新课程版本中,他不愿意为此付费
要么。 您决定使用两种不同版本的高效,美观
类的宝石还不错,钱也不错。
那天晚上,你做噩梦:威尔玛,贝蒂,鹅卵石,班巴姆,甚至还有迪诺
进入您的办公室,他们都希望将一些其他功能添加到您的
也很好。 一场维护噩梦抬起了丑陋的头。
该怎么办? 您不希望课程的七个版本,甚至整个课程
Bedrock希望向您的班级添加其他所有功能。
然后,您醒来并找到解决方案:而不是实施越来越多的解决方案
您可以使用精细类的版本来执行以下操作:
public class Beautiful implements Visitee {
public void whoIsThere(Visitor v) { v.thisIsBeautiful(this); }
// ...
}
public class Efficient implements Visitee {
public void whoIsThere(Visitor v) { v.thisIsEfficient(this); }
// ...
}
public class Gem implements Visitee {
public void whoIsThere(Visitor v) { v.thisIsGem(this); }
// ...
}
...,然后添加两个简单的界面:
public interface Visitee {
public void whoIsThere(Visitor v);
}
public interface Visitor {
public void thisIsBeautiful(Beautiful b);
public void thisIsEfficient(Efficient e);
public void thisIsGem(Gem g);
}
您的班级结构(美丽,高效和宝石)保持不变;
那么多
您知道,并且您只向每个类添加了一个小方法,并且您已经定义了
两个接口。 那就是你所做的。
让我们为客户Fred实现功能; 您仍然必须实施
因为您已经接受了这笔钱,但是现在您可以实现该功能
在一个单独的班级中:弗雷德班级; 你给它一个所有对象的迭代器
在Fred的收藏夹中,并实现以下功能:
public class Fred implements Visitor {
private Iterator<Visitee> i;
public Fred(Iterator<Visitee> i) { this.i= i; }
public void especiallyForFred() {
while (i.hasNex()) i.whoIsThere(this);
}
public void thisIsBeautiful(Beautiful b) {
// added functionality for Beautiful
// all specially made for Fred
}
public void thisIsEfficient(Efficient e) {
// added functionality for Efficient
// all specially made for Fred
}
public void thisIsGem(Gem g) {
// added functionality for Gem
// all specially made for Fred
}
}
您告诉客户Fred,他要做的就是实例化Fred对象。
用一个迭代器遍历他的集合,然后调用尤其是ForFred
方法。 然后,他获得了其他功能,因此不需要
他(或他的程序员)要做任何其他事情。
我想您可以想象Barney的班级会是什么样。 如果是威尔玛,贝蒂
Bambam,Pebbles甚至Dino都出现了,您无需改变上等的班级;
您要做的就是单独实现所需的功能
类,就像我们在上面的示例中所做的一样。 每个客户都有自己的添加
功能,并且没有任何功能与其他功能发生冲突
(您根本不会将其传递给其他客户)。 所有这些都在你的
现在,维护列表是那些单独的访问者类别,每个客户一个)。
这就是访客模式的全部意义
:一组固定的类或所有以固定方式使用的接口以及具有
在不同情况下实施。 您固定的班级将是
访问者及其附加功能将由访问者实现。
原始罚款类别所需的修改很小(只有一个)
添加了实现Visitee接口的小方法)。
当然,仍然需要实现其他功能,但是您已经
从最初的班级中吸取了灵感。 甚至更多:您可以添加
无需修改您的任何其他功能
原始类广告恶心。 另一方面:Visitor模式只能是
当您的班级或多或少是固定的时应用(您不想更改
这些界面和以前存在的访问者一次又一次)。 但是如果你
一组类是固定的,继续进行:在现有代码中实现Visitors
保持课堂清洁。 您只需要准备课程即可
尚未设计和编写的访问者,即您的固定访问者
这套课程是为未知的未来而准备的。
如果您仔细阅读了上面的示例类和接口,您会发现
访客通过呼叫被访者开始; 被访者通过致电回应
再次对访问者使用适当的方法。 这就是为什么访客
模式称为“双重派遣”模式:从访客到访客
再次回来。 这就是保持课堂清洁和释放您所需要的一切
从维护的噩梦。
下次见到我们谈论装饰器(也称为包装器)时,
以及他们可以为您做什么。
亲切的问候,
乔斯
翻译自: https://bytes.com/topic/java/insights/636063-patterns-visitor-pattern
访客模式 无痕模式 区别