? 访问者模式是一种将操作逻辑与对象结构分离的方法,使得操作可以独立变化,操作逻辑被封装在独立的访问者类中,并在被访问的元素类中提供接受访问者的方法,而不是直接嵌入到数据结构中的对象中。
? 我们可以将一个购物商场中的商品类作为元素类,不同的销售人员可以作为访问者类。当销售人员需要对商品进行销售操作时,可以创建一个具体的访问者对象,然后通过商品类的接受访问者的方法将访问者对象传入。然后商品类再根据传入的访问者对象调用相应的访问者方法,从而实现对商品的不同销售策略,如打折、促销等。
小明家有一些圆形和长方形面积的土地,请你帮他实现一个访问者模式,使得可以通过访问者计算每块土地的面积。
图形的面积计算规则如下:
第一行是一个整数 n(1 <= n <= 1000),表示图形的数量。
接下来的 n 行,每行描述一个图形,格式为 “Circle r” 或 “Rectangle width height”,其中 r、width、height 是正整数。
对于每个图形,输出一行,表示该图形的面积。
package com.technologystatck.designpattern.mode.visitor;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int nums = scanner.nextInt();
scanner.nextLine();
//创建数组来存储图形对象
Shape[] shapes = new Shape[nums];
//根据用户输入来创建不同类型的图形对象
for (int i = 0; i < nums; i++) {
String[] inputs = scanner.nextLine().split(" ");
if (inputs[0].equals("Circle")) {
int radius = Integer.parseInt(inputs[1]);
shapes[i] = new Circle(radius);
} else if (inputs[0].equals("Rectangle")) {
int width = Integer.parseInt(inputs[1]);
int height = Integer.parseInt(inputs[2]);
shapes[i] = new Rectangle(width, height);
} else {
System.out.println("Invalid input");
return;
}
}
//创建图形集合
Drawing drawing = new Drawing(shapes);
//创建面积计算访问者
ConcreteAreaCalc concreteAreaCalc = new ConcreteAreaCalc();
drawing.accept(concreteAreaCalc);
}
}
//访问者接口
interface Visitor {
//圆形的访问者方法
void visit(Circle circle);
//矩形的访问者方法
void visit(Rectangle rectangle);
}
//实现具体访问者,相当于计算圆形/矩形
class ConcreteAreaCalc implements Visitor {
@Override
public void visit(Circle circle) {
double area = 3.14 * Math.pow(circle.getRadius(), 2);
System.out.println(area);
}
@Override
public void visit(Rectangle rectangle) {
double area = rectangle.getHeight() * rectangle.getWidth();
System.out.println(area);
}
}
//定义元素接口
interface Shape {
void accept(Visitor visitor);
}
//实现圆形具体元素
class Circle implements Shape {
private int radius;
public Circle(int radius) {
this.radius = radius;
}
public int getRadius() {
return radius;
}
@Override
public void accept(Visitor visitor) {
//调用访问者的方法,访问当前对象,并将当前对象传递给访问者。
visitor.visit(this);
}
}
//实现矩形具体元素
class Rectangle implements Shape {
private int width;
private int height;
public Rectangle(int width, int height) {
this.width = width;
this.height = height;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
//创造对象结构,用于让访问者访问它的元素
class Drawing {
private Shape[] shapes;
public Drawing(Shape[] shapes) {
this.shapes = shapes;
}
//循环遍历访问者接口
public void accept(Visitor visitor) {
for (Shape shape : shapes) {
shape.accept(visitor);
}
}
}