访问者模式和观察者模式都是设计模式中的一种,它们的区别在于处理方式不同。访问者模式是通过在访问者类中定义不同的访问方法来实现对不同对象的操作;而观察者模式则是通过在被观察者对象中注册观察者对象,在状态改变时主动通知 。
在计算机编程中,设计模式是一种被广泛接受和应用的解决问题的方法,它们提供了一种可重用的解决方案,可以帮助开发者更有效地解决复杂的问题,我们将深入探讨一种设计模式——访问者模式。
访问者模式是一种行为型设计模式,它定义了一种操作对象结构中的元素的接口,但不指定具体如何操作,这使得可以在不改变数据结构的前提下,添加新的操作。
访问者模式的主要角色包括:
1、抽象访问者(Visitor):定义一个操作接口,用于对元素进行操作。
2、具体访问者(ConcreteVisitor):实现抽象访问者的操作接口。
3、元素(Element):定义一个接受操作的接口。
4、目标对象(Object):包含一个元素列表,以及一个接受访问者的方法。
下面我们通过一个简单的例子来说明访问者模式的使用:
假设我们有一个表示动物的类,每个动物都有一个发出声音的方法,但是每种动物发出的声音不同,我们可以使用访问者模式来实现这个功能,而不需要修改动物类的代码。
我们定义一个抽象访问者类:
public abstract class AnimalSoundVisitor { public abstract void visit(Animal animal); }
我们定义具体的访问者类,例如猫和狗:
public class CatSoundVisitor extends AnimalSoundVisitor { @Override public void visit(Animal animal) { System.out.println("喵喵喵"); } } public class DogSoundVisitor extends AnimalSoundVisitor { @Override public void visit(Animal animal) { System.out.println("汪汪汪"); } }
我们定义一个表示动物的抽象类:
public abstract class Animal { public abstract void makeSound(); }
我们定义具体的动物类,例如猫和狗:
public class Cat extends Animal { @Override public void makeSound() { System.out.println("The cat meows."); } } public class Dog extends Animal { @Override public void makeSound() { System.out.println("The dog barks."); } }
我们在目标对象中使用访问者模式:
import java.util.ArrayList; import java.util.List; public class Zoo implements AnimalSoundVisitor { private List<Animal> animals; public Zoo() { animals = new ArrayList<>(); } public void addAnimal(Animal animal) { animals.add(animal); } public void accept(AnimalSoundVisitor visitor) { for (Animal animal : animals) { animal.makeSound(); // The sound of an animal is made without modifying the animal's code. We just call the appropriate method on the visitor object. This is the power of visitor pattern! :)) It makes our code DRY (Don't Repeat Yourself). If we want to add more sounds in future, we don't need to change the existing code but can just add a new sound visitor and add it to the list of visitors. Then we just call accept() again with the new visitor. That's it! No changes needed in existing code! :)) Also this design pattern allows us to add new kinds of animals in future without changing any code of the existing classes! :))