设计模式之-访问者模式,快速掌握访问者模式,通俗易懂的讲解访问者模式以及它的使用场景
2023-12-25 17:41:10
一、快速理解访问者模式
当谈到访问者模式时,我们可以通过以下方式进行详细解释:
访问者模式是一种行为型设计模式,它允许你在不修改已有代码的情况下,向现有对象结构添加新的操作。该模式将操作(或方法)封装在称为访问者的独立对象中,使得可以在不修改元素类的情况下,通过访问者对象访问元素类的元素。
通俗地说,访问者模式就像是一个游客(访问者),他可以访问各个房间(元素类),并对每个房间进行不同的操作。
二、访问者模式使用场景
- 当一个对象结构(如集合、树状结构等)包含多个不同类型的元素,并且你希望对这些元素执行不同的操作时,访问者模式很有用。
- 当你需要在不改变元素类的前提下,向现有元素结构中添加新的操作时,访问者模式也是一个好的选择。
- 当元素类的结构相对稳定,但经常需要在该结构上定义新的操作时,访问者模式可以避免在元素类中添加大量的条件语句。
三、示例代码:
假设我们有一个动物园,里面有不同类型的动物,包括狗、猫和鸟。我们希望能够对这些动物执行不同的操作,如喂食、清洁和训练。
// 元素接口 - 动物
interface Animal {
void accept(Visitor visitor);
}
// 具体元素类 - 狗
class Dog implements Animal {
@Override
public void accept(Visitor visitor) {
visitor.visitDog(this);
}
public void bark() {
System.out.println("狗叫:汪汪汪!");
}
}
// 具体元素类 - 猫
class Cat implements Animal {
@Override
public void accept(Visitor visitor) {
visitor.visitCat(this);
}
public void meow() {
System.out.println("猫叫:喵喵喵!");
}
}
// 具体元素类 - 鸟
class Bird implements Animal {
@Override
public void accept(Visitor visitor) {
visitor.visitBird(this);
}
public void chirp() {
System.out.println("鸟叫:啾啾啾!");
}
}
// 访问者接口 - 游客
interface Visitor {
void visitDog(Dog dog);
void visitCat(Cat cat);
void visitBird(Bird bird);
}
// 具体访问者类 - 喂食者
class Feeder implements Visitor {
@Override
public void visitDog(Dog dog) {
dog.bark();
System.out.println("喂食者给狗喂食!");
}
@Override
public void visitCat(Cat cat) {
cat.meow();
System.out.println("喂食者给猫喂食!");
}
@Override
public void visitBird(Bird bird) {
bird.chirp();
System.out.println("喂食者给鸟喂食!");
}
}
// 具体访问者类 - 清洁者
class Cleaner implements Visitor {
@Override
public void visitDog(Dog dog) {
dog.bark();
System.out.println("清洁者清理狗窝!");
}
@Override
public void visitCat(Cat cat) {
cat.meow();
System.out.println("清洁者清理猫砂盆!");
}
@Override
public void visitBird(Bird bird) {
bird.chirp();
System.out.println("清洁者清理鸟笼!");
}
}
// 具体访问者类 - 训练师
class Trainer implements Visitor {
@Override
public void visitDog(Dog dog) {
dog.bark();
System.out.println("训练师训练狗!");
}
@Override
public void visitCat(Cat cat) {
cat.meow();
System.out.println("训练师训练猫!");
}
@Override
public void visitBird(Bird bird) {
bird.chirp();
System.out.println("训练师训练鸟!");
}
}
// 客户端代码
public class Main {
public static void main(String[] args) {
Animal dog = new Dog();
Animal cat = new Cat();
Animal bird = new Bird();
Visitor feeder = new Feeder();
Visitor cleaner = new Cleaner();
Visitor trainer = new Trainer();
dog.accept(feeder);
cat.accept(feeder);
bird.accept(feeder);
dog.accept(cleaner);
cat.accept(cleaner);
bird.accept(cleaner);
dog.accept(trainer);
cat.accept(trainer);
bird.accept(trainer);
}
}
在上述示例代码中,我们定义了动物元素接口 Animal,并实现了具体的元素类 Dog、Cat 和 Bird。访问者接口 Visitor 定义了访问者的操作方法。具体访问者类 Feeder、Cleaner 和 Trainer 实现了访问者接口,分别表示喂食者、清洁者和训练师。
在客户端代码中,我们创建了不同类型的动物对象,并创建了不同的访问者对象。然后,通过调用 accept() 方法,将访问者对象传递给动物对象,实现了对不同动物执行不同操作
四 优缺点
优点:
- 增加新的操作很容易:当需要增加新的操作时,只需创建一个新的访问者对象并实现相应的操作方法,而无需修改现有的元素对象结构,符合开闭原则。
- 结构清晰:访问者模式将相关的操作封装在访问者类中,使得代码结构更清晰,易于理解和维护。
- 增加新的元素类比较容易:当需要增加新的元素类时,只需在访问者接口中新增对应的访问方法,并在具体访问者类中实现该方法,不需要修改现有的访问者类。
缺点:
- 增加新的元素类困难:当需要增加新的元素类时,除了在元素接口中新增对应的接受访问者方法外,还需要在所有具体访问者类中实现对新元素类的访问方法,可能导致代码修改量较大。
- 违反了单一职责原则:访问者模式将对元素对象的操作分离到了访问者类中,可能导致访问者类承担过多的责任,使其变得复杂且难以维护。
- 元素对象暴露细节:为了让访问者能够访问元素对象的内部状态,可能需要在元素接口中暴露一些细节,增加了元素对象的耦合性。
六、 总结
总体而言,访问者模式适用于元素对象结构相对稳定,但需要频繁添加新的操作的场景。如果元素对象结构经常变化或者需要添加新的元素类,使用访问者模式可能会增加代码的复杂性。因此,在使用访问者模式时需要根据具体情况进行权衡和设计。
文章来源:https://blog.csdn.net/qq_42262444/article/details/135203638
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!