Java中的访问者设计模式–示例教程
訪客模式是行為設(shè)計(jì)模式之一 。 當(dāng)我們必須對(duì)一組相似類型的對(duì)象執(zhí)行操作時(shí),將使用訪問(wèn)者模式。 借助訪問(wèn)者模式,我們可以將操作邏輯從對(duì)象移動(dòng)到另一個(gè)類。
例如,假設(shè)有一個(gè)購(gòu)物車,我們可以在其中添加不同類型的項(xiàng)目(元素),當(dāng)我們單擊“結(jié)帳”按鈕時(shí),它將計(jì)算要支付的總金額。 現(xiàn)在我們可以將計(jì)算邏輯包含在項(xiàng)目類中,或者可以使用訪問(wèn)者模式將此邏輯移到另一個(gè)類中。 讓我們?cè)谠L問(wèn)者模式示例中實(shí)現(xiàn)此功能。
為了實(shí)現(xiàn)訪客模式,首先,我們將創(chuàng)建用于購(gòu)物車的不同類型的項(xiàng)目(元素)。
ItemElement.java
package com.journaldev.design.visitor;public interface ItemElement {public int accept(ShoppingCartVisitor visitor); }注意,accept方法接受Visitor參數(shù),我們可以有一些其他特定于項(xiàng)目的方法,但為簡(jiǎn)單起見(jiàn),我不打算討論太多細(xì)節(jié),而僅關(guān)注于訪問(wèn)者模式。
讓我們?yōu)椴煌愋偷捻?xiàng)目創(chuàng)建一些具體的類。
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;}@Overridepublic int accept(ShoppingCartVisitor visitor) {return visitor.visit(this);}}水果.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;}@Overridepublic int accept(ShoppingCartVisitor visitor) {return visitor.visit(this);}}注意具體類中accept()方法的實(shí)現(xiàn),它調(diào)用Visitor的visit()方法并將其自身作為參數(shù)傳遞。
我們?cè)赩isitor界面中具有針對(duì)不同項(xiàng)目類型的visit()方法,將由具體的visitor類實(shí)現(xiàn)。
ShoppingCartVisitor.java
package com.journaldev.design.visitor;public interface ShoppingCartVisitor {int visit(Book book);int visit(Fruit fruit); }現(xiàn)在,我們將實(shí)現(xiàn)訪客界面,并且每個(gè)項(xiàng)目都有其自己的邏輯來(lái)計(jì)算費(fèi)用。
ShoppingCartVisitorImpl.java
package com.journaldev.design.visitor;public class ShoppingCartVisitorImpl implements ShoppingCartVisitor {@Overridepublic int visit(Book book) {int cost=0;//apply 5$ discount if book price is greater than 50if(book.getPrice() > 50){cost = book.getPrice()-5;}else cost = book.getPrice();System.out.println("Book ISBN::"+book.getIsbnNumber() + " cost ="+cost);return cost;}@Overridepublic int visit(Fruit fruit) {int cost = fruit.getPricePerKg()*fruit.getWeight();System.out.println(fruit.getName() + " cost = "+cost);return cost;}}讓我們看看如何在客戶端應(yīng)用程序中使用它。
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;}}當(dāng)我們運(yùn)行上面的程序時(shí),我們得到以下輸出。
Book ISBN::1234 cost =20 Book ISBN::5678 cost =95 Banana cost = 20 Apple cost = 25 Total Cost = 160注意,如果所有項(xiàng)目中的accept()方法的實(shí)現(xiàn)都是相同的,但是可以有所不同,例如,可以使用邏輯檢查項(xiàng)目是否為空,那么根本不要調(diào)用visit()方法。
訪客模式類圖
我們的訪客模式實(shí)現(xiàn)的類圖是:
這種模式的好處是,如果操作的邏輯發(fā)生了變化,那么我們只需要在訪問(wèn)者實(shí)現(xiàn)中進(jìn)行更改,而不必在所有項(xiàng)目類中進(jìn)行更改。
另一個(gè)好處是,將新項(xiàng)目添加到系統(tǒng)很容易,它將僅需要在訪問(wèn)者界面和實(shí)現(xiàn)中進(jìn)行更改,而現(xiàn)有項(xiàng)目類別將不受影響。
訪問(wèn)者模式的缺點(diǎn)在于,在設(shè)計(jì)時(shí)我們應(yīng)該知道visit()方法的返回類型,否則我們將不得不更改接口及其所有實(shí)現(xiàn)。 另一個(gè)缺點(diǎn)是,如果訪問(wèn)者接口的實(shí)現(xiàn)過(guò)多,則很難擴(kuò)展。
翻譯自: https://www.javacodegeeks.com/2013/08/visitor-design-pattern-in-java-example-tutorial.html
總結(jié)
以上是生活随笔為你收集整理的Java中的访问者设计模式–示例教程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 适用于高级Java开发人员的十大书籍
- 下一篇: 奔驰也玩起了 800V,续航超 750