Java 中的访问者设计模式
访问者设计模式是行为设计模式之一。
访问者设计模式
当我们必须对一组相似类型的对象执行操作时,将使用访问者模式。借助访问者模式,我们可以将操作逻辑从对象移动到另一个类。例如,想象一下购物车,我们可以在其中添加不同类型的商品(元素)。当我们单击结帐按钮时,它会计算要支付的总金额。现在,我们可以在商品类中使用计算逻辑,或者我们可以使用访问者模式将此逻辑移出到另一个类。让我们在访问者模式示例中实现这一点。
访问者设计模式 Java 示例
为了实现访客模式,首先我们将创建用于购物车的不同类型的项目(元素)。ItemElement.java
package com.journaldev.design.visitor;
public interface ItemElement {
public int accept(ShoppingCartVisitor visitor);
}
请注意,accept 方法接受 Visitor 参数。我们还可以针对项目使用其他一些方法,但为了简单起见,我不会讲得那么详细,只关注访问者模式。让我们为不同类型的项目创建一些具体的类。Book.java
package com.journaldev.design.visitor;
public class Book implements ItemElement {
private int price;
private String isbnNumber;
public Book(int cost, String isbn){
this.price=cost;
this.isbnNumber=isbn;
}
public int getPrice() {
return price;
}
public String getIsbnNumber() {
return isbnNumber;
}
@Override
public int accept(ShoppingCartVisitor visitor) {
return visitor.visit(this);
}
}
Fruit.java
package com.journaldev.design.visitor;
public class Fruit implements ItemElement {
private int pricePerKg;
private int weight;
private String name;
public Fruit(int priceKg, int wt, String nm){
this.pricePerKg=priceKg;
this.weight=wt;
this.name = nm;
}
public int getPricePerKg() {
return pricePerKg;
}
public int getWeight() {
return weight;
}
public String getName(){
return this.name;
}
@Override
public int accept(ShoppingCartVisitor visitor) {
return visitor.visit(this);
}
}
注意具体类中 accept() 方法的实现,它调用 Visitor 的 visit() 方法并将其自身作为参数传递。我们在 Visitor 接口中为不同类型的项目提供了 visit() 方法,该方法将由具体访问者类实现。ShoppingCartVisitor.java
package com.journaldev.design.visitor;
public interface ShoppingCartVisitor {
int visit(Book book);
int visit(Fruit fruit);
}
现在我们将实现访客界面,每个项目都有自己的逻辑来计算成本。ShoppingCartVisitorImpl.java
package com.journaldev.design.visitor;
public class ShoppingCartVisitorImpl implements ShoppingCartVisitor {
@Override
public int visit(Book book) {
int cost=0;
//apply 5$ discount if book price is greater than 50
if(book.getPrice() > 50){
cost = book.getPrice()-5;
}else cost = book.getPrice();
System.out.println("Book ISBN::"+book.getIsbnNumber() + " cost ="+cost);
return cost;
}
@Override
public int visit(Fruit fruit) {
int cost = fruit.getPricePerKg()*fruit.getWeight();
System.out.println(fruit.getName() + " cost = "+cost);
return cost;
}
}
让我们看看如何在客户端应用程序中使用访问者模式示例。ShoppingCartClient.java
package com.journaldev.design.visitor;
public class ShoppingCartClient {
public static void main(String[] args) {
ItemElement[] items = new ItemElement[]{new Book(20, "1234"),new Book(100, "5678"),
new Fruit(10, 2, "Banana"), new Fruit(5, 5, "Apple")};
int total = calculatePrice(items);
System.out.println("Total Cost = "+total);
}
private static int calculatePrice(ItemElement[] items) {
ShoppingCartVisitor visitor = new ShoppingCartVisitorImpl();
int sum=0;
for(ItemElement item : items){
sum = sum + item.accept(visitor);
}
return sum;
}
}
当我们运行上述访问者模式客户端程序时,我们得到以下输出。
Book ISBN::1234 cost =20
Book ISBN::5678 cost =95
Banana cost = 20
Apple cost = 25
Total Cost = 160
请注意,如果所有项目中的 accept() 方法的实现都相同,但也可以不同,例如可以有逻辑来检查项目是否免费,那么根本不要调用 visit() 方法。
访问者设计模式类图
我们的访问者设计模式实现的类图是:
访问者模式的好处
这种模式的好处是,如果操作逻辑发生变化,我们只需要在访问者实现中进行更改,而不必在所有项目类中进行更改。另一个好处是,向系统添加新项目很容易,只需要更改访问者界面和实现,现有的项目类不会受到影响。
访客模式限制
访问者模式的缺点是,我们在设计时必须知道 visit() 方法的返回类型,否则我们将不得不更改接口及其所有实现。另一个缺点是,如果访问者接口的实现太多,则很难扩展。以上就是访问者设计模式的全部内容,如果我遗漏了任何内容,请告诉我。如果您喜欢,请与其他人分享。