java
主页 > 软件编程 > java >

Java访问者模式实现优雅的对象结构处理

2023-11-22 | 佚名 | 点击:

Java访问者模式(Visitor Pattern)是一种行为型设计模式,它允许将算法与其所操作的对象分离.该模式定义了一个访问者对象,它可以访问不同类型的对象并执行一些操作,同时也能让你在不修改现有代码的情况下,添加新的操作.

再访问者模式中,有两个重要的角色:访问者和元素. 元素是一个对象结构的组成部分.访问者是一个表示要执行的操作的对象.访问者可以通过元素的接受方法来访问元素.

Java访问者模式通常涉及以下5种角色:

实现

动物园中有不同种类的动物,包括狗,猫和鸟.访问者模式可以用于统计不同类型的动物的个数,以及不同类型的动物的属性信息.

抽象元素

1

2

3

public interface Animal {

    void accept(Visitor visitor);

}

具体元素

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

@Data

public class Bird implements Animal{

    private String name;

    private String habitat;

    public Bird(String name, String habitat) {

        this.name = name;

        this.habitat = habitat;

    }

    @Override

    public void accept(Visitor visitor) {

        visitor.visitor(this);

    }

}

@Data

public class Cat implements Animal{

    private String sound;

    private int age;

    public Cat(String sound, int age) {

        this.sound = sound;

        this.age = age;

    }

    @Override

    public void accept(Visitor visitor) {

        visitor.visitor(this);

    }

}

@Data

public class Dog implements Animal{

    private String color;

    private int size;

    public Dog(String color, int size) {

        this.color = color;

        this.size = size;

    }

    @Override

    public void accept(Visitor visitor) {

        visitor.visitor(this);

    }

}

抽象访问者

1

2

3

4

5

public interface Visitor {

    void visitor(Dog dog);

    void visitor(Cat cat);

    void visitor(Bird bird);

}

具体访问者

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

public class AnimalCountVisitor implements Visitor{

    private int dogCount;

    private int birdCount;

    private int catCount;

    @Override

    public void visitor(Dog dog) {

        dogCount++;

    }

    @Override

    public void visitor(Cat cat) {

        catCount++;

    }

    @Override

    public void visitor(Bird bird) {

        birdCount++;

    }

    public void printCount(){

        System.out.println("狗的个数:"+dogCount);

        System.out.println("猫的个数:"+catCount);

        System.out.println("鸟的个数:"+birdCount);

    }

}

public class AnimalFeatureVisitor implements Visitor {

    private List<String> features;

    public AnimalFeatureVisitor() {

        features = new ArrayList<>();

    }

    @Override

    public void visitor(Dog dog) {

        features.add("Dog:color=" + dog.getColor() + ",size=" + dog.getSize());

    }

    @Override

    public void visitor(Cat cat) {

        features.add("Car:sound=" + cat.getSound() + ",age=" + cat.getAge());

    }

    @Override

    public void visitor(Bird bird) {

        features.add("Bird:name=" + bird.getName() + ",habitat=" + bird.getHabitat());

    }

    public void printFeatures(){

        features.forEach(System.out::println);

    }

}

测试

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

public class Demo {

    public static void main(String[] args) {

        List<Animal> animals = new ArrayList<>();

        animals.add(new Dog("褐色", 50));

        animals.add(new Dog("白色", 45));

        animals.add(new Cat("喵喵叫", 2));

        animals.add(new Cat("呜呜声", 3));

        animals.add(new Bird("鹦鹉", "森林"));

        animals.add(new Bird("麻雀", "田野"));

        AnimalCountVisitor animalCountVisitor = new AnimalCountVisitor();

        AnimalFeatureVisitor animalFeatureVisitor = new AnimalFeatureVisitor();

        animals.forEach(animal -> {

            animal.accept(animalCountVisitor);

            animal.accept(animalFeatureVisitor);

        });

        animalCountVisitor.printCount();

        animalFeatureVisitor.printFeatures();

    }

}

再这个例子中,我们定义了三种动物类,包括Dog,Cat和Bird,它们都实现了Animal接口,并且是心啊了accept方法,其中传入了Visitor类型的参数.

接下来,定义了Visitor接口,其中包含了visitor方法,该方法根据传入的不同类型的动物进行访问.

再具体的Visitor的实现中,定义了AnimalCountVisitor和AnimalFeatureVisitor两个访问者,前者用于统计不同类型的动物的个数,后者用于打印不同类型的动物的属性.

总结

优点

缺点

应用场景

原文链接:
相关文章
最新更新