欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java訪問(wèn)者設(shè)計(jì)模式詳細(xì)講解

 更新時(shí)間:2022年11月23日 16:58:28   作者:lpf_wei  
大多數(shù)情況下你不需要訪問(wèn)者模式,但當(dāng)一旦需要訪問(wèn)者模式時(shí),那就是真的需要它了,這是設(shè)計(jì)模式創(chuàng)始人的原話。可以看出應(yīng)用場(chǎng)景比較少,但需要它的時(shí)候是不可或缺的,這篇文章就開(kāi)始學(xué)習(xí)最后一個(gè)設(shè)計(jì)模式——訪問(wèn)者模式

編程是一門(mén)藝術(shù),大批量的改動(dòng)顯然是非常丑陋的做法,用心的琢磨寫(xiě)的代碼讓它變的更美觀。

在生活中,電影或電視劇中的人物角色,不同的觀眾對(duì)他們的評(píng)價(jià)也不同;還有顧客在商場(chǎng)購(gòu)物時(shí)放在“購(gòu)物車(chē)”中的商品,顧客主要關(guān)心所選商品的性價(jià)比,而收銀員關(guān)心的是商品的價(jià)格和數(shù)量。

這些被處理的數(shù)據(jù)元素相對(duì)穩(wěn)定而訪問(wèn)方式多種多樣的數(shù)據(jù)結(jié)構(gòu),如果用“訪問(wèn)者模式”來(lái)處理比較方便。訪問(wèn)者模式能把處理方法從數(shù)據(jù)結(jié)構(gòu)中分離出來(lái),并可以根據(jù)需要增加新的處理方法,且不用修改原來(lái)的程序代碼與數(shù)據(jù)結(jié)構(gòu),這提高了程序的擴(kuò)展性和靈活性。

1.模式的定義

訪問(wèn)者(Visitor)模式:是將作用于某種數(shù)據(jù)結(jié)構(gòu)中的各元素的操作分離出來(lái)封裝成獨(dú)立的類(lèi),使其在不改變數(shù)據(jù)結(jié)構(gòu)的前提下可以添加作用于這些元素的新的操作,為數(shù)據(jù)結(jié)構(gòu)中的每個(gè)元素提供多種訪問(wèn)方式。它將對(duì)數(shù)據(jù)的操作與數(shù)據(jù)結(jié)構(gòu)進(jìn)行分離,是行為類(lèi)模式中最復(fù)雜的一種模式。

訪問(wèn)者設(shè)計(jì)模式主要解決:java多態(tài)方法重載的靜態(tài)化問(wèn)題。

2.訪問(wèn)者設(shè)計(jì)模式的優(yōu)點(diǎn)與不足

訪問(wèn)者(Visitor)模式是一種對(duì)象行為型模式,其主要優(yōu)點(diǎn):

  • 擴(kuò)展性好。能夠在不修改對(duì)象結(jié)構(gòu)中的元素的情況下,為對(duì)象結(jié)構(gòu)中的元素添加新的功能。
  • 復(fù)用性好??梢酝ㄟ^(guò)訪問(wèn)者來(lái)定義整個(gè)對(duì)象結(jié)構(gòu)通用的功能,從而提高系統(tǒng)的復(fù)用程度。
  • 靈活性好。訪問(wèn)者模式將數(shù)據(jù)結(jié)構(gòu)與作用于結(jié)構(gòu)上的操作解耦,使得操作集合可相對(duì)自由地演化而不影響系統(tǒng)的數(shù)據(jù)結(jié)構(gòu)。
  • 符合單一職責(zé)原則。訪問(wèn)者模式把相關(guān)的行為封裝在一起,構(gòu)成一個(gè)訪問(wèn)者,使每一個(gè)訪問(wèn)者的功能都比較單一。

訪問(wèn)者(Visitor)模式的不足:

  • 增加新的元素類(lèi)很困難。在訪問(wèn)者模式中,每增加一個(gè)新的元素類(lèi),都要在每一個(gè)具體訪問(wèn)者類(lèi)中增加相應(yīng)的具體操作,這違背了“開(kāi)閉原則”。
  • 破壞封裝。訪問(wèn)者模式中具體元素對(duì)訪問(wèn)者公布細(xì)節(jié),這破壞了對(duì)象的封裝性。
  • 違反了依賴倒置原則。訪問(wèn)者模式依賴了具體類(lèi),而沒(méi)有依賴抽象類(lèi)。

3.訪問(wèn)者設(shè)計(jì)模式的實(shí)現(xiàn)思路

訪問(wèn)者(Visitor)模式實(shí)現(xiàn)的關(guān)鍵是如何將作用于元素的操作分離出來(lái)封裝成獨(dú)立的類(lèi)

訪問(wèn)者模式包含以下主要角色。

  • 抽象訪問(wèn)者(Visitor)角色:定義一個(gè)訪問(wèn)具體元素的接口,為每個(gè)具體元素類(lèi)對(duì)應(yīng)一個(gè)訪問(wèn)操作 visit() ,該操作中的參數(shù)類(lèi)型標(biāo)識(shí)了被訪問(wèn)的具體元素。
  • 具體訪問(wèn)者(ConcreteVisitor)角色:實(shí)現(xiàn)抽象訪問(wèn)者角色中聲明的各個(gè)訪問(wèn)操作,確定訪問(wèn)者訪問(wèn)一個(gè)元素時(shí)該做什么。
  • 抽象元素(Element)角色:聲明一個(gè)包含接受操作 accept() 的接口,被接受的訪問(wèn)者對(duì)象作為 accept() 方法的參數(shù)。
  • 具體元素(ConcreteElement)角色:實(shí)現(xiàn)抽象元素角色提供的 accept() 操作,其方法體通常都是 visitor.visit(this) ,另外具體元素中可能還包含本身業(yè)務(wù)邏輯的相關(guān)操作。
  • 對(duì)象結(jié)構(gòu)(Object Structure)角色:是一個(gè)包含元素角色的容器,提供讓訪問(wèn)者對(duì)象遍歷容器中的所有元素的方法,通常由 List、Set、Map 等聚合類(lèi)實(shí)現(xiàn)。

4.訪問(wèn)者設(shè)計(jì)模式實(shí)例

場(chǎng)景介紹:統(tǒng)計(jì)不同水果的價(jià)格,不同的水果放置到不同的集合,但是由于java多態(tài)中方法重載是靜態(tài)化的不足,導(dǎo)致統(tǒng)計(jì)不出來(lái)價(jià)格,就可以使用訪問(wèn)者設(shè)計(jì)模式來(lái)處理。

public interface Fruit {
    int price();
    void draw();
    int accept(Visit visit);
}
public class Apple implements Fruit {
    private int price = 100;
    public Apple(){
    }
    public Apple(int price){
        this.price = price;
    }
    public void pack(AppleBag bag){
        bag.pack();
    }
    @Override
    public int price() {
        return price;
    }
    @Override
    public void draw() {
        System.out.print("蘋(píng)果紅富士");
    }
    public void setPrice(int price) {
        this.price = price;
    }
    public int accept(Visit visit){
        /*指針可以傳遞真實(shí)類(lèi)型*/
        return visit.sell(this);
    }
}
public class Banana implements Fruit {
    private int price = 60;
    @Override
    public int price() {
        return price;
    }
    public void pack(BananaBag bag){
        bag.pack();
    }
    @Override
    public void draw() {
        System.out.print("仙人蕉");
    }
    public int accept(Visit visit){
        return visit.sell(this);
    }
    public void setPrice(int price) {
        this.price = price;
    }
}
public class Orange implements Fruit {
    private String name = "";
    private int price = 70;
    public Orange(String name,int price){
        this.price = price;
        this.name = name;
    }
    public void pack(OrangeBag bag){
        bag.pack();
    }
    @Override
    public int price() {
        return price;
    }
    @Override
    public void draw() {
        System.out.print("砂糖桔");
    }
    public int accept(Visit visit){
        return visit.sell(this);
    }
    public void setPrice(int price) {
        this.price = price;
    }
}
public class Visit {
	/*蘋(píng)果計(jì)價(jià)*/
	public int sell(Apple apple){
		System.out.println("apple's price: ¥50");
		return 50;
	}
	/*桔子計(jì)價(jià)*/
	public int sell(Orange orange){
		System.out.println("orange's price: ¥20");
		return 20;
	}
	/*香蕉計(jì)價(jià)*/
	public int sell(Banana banana){
		System.out.println("banana's price: ¥30");
		return 30;
	}
	//其它水果計(jì)價(jià)
	public int sell(Fruit fruit){
		System.out.println("other price: ¥10");
		return 10;
	}
}
public class VisitClient {
    private static Visit visit = new Visit();
    /*庫(kù)存*/
    private static List<Fruit> list = new ArrayList<>();
    static {
        list.add(StaticFactory.getFruitApple());
        list.add(StaticFactory.getFruitOrange());
        list.add(StaticFactory.getFruitBanana());
        list.add(StaticFactory.getFruitApple());
        list.add(StaticFactory.getFruitOrange());
    }
    private static int price() {
        int total = 0;
        for (Fruit fruit : list) {
            total += fruit.accept(visit);
        }
        System.out.println("總價(jià)值:" + total);
        return total;
    }
      public static void main(String[] args) {
        price();
    }

訪問(wèn)者設(shè)計(jì)模式的關(guān)鍵是:不能直接使用visit對(duì)象直接調(diào)用sell方法將水果對(duì)象傳遞進(jìn)去,因?yàn)橹苯觽鬟f進(jìn)去由于方法重載的靜態(tài)化問(wèn)題,不會(huì)執(zhí)行相應(yīng)的方法,需要是使用fruit的accept方法才行。

5.訪問(wèn)者設(shè)計(jì)模式的使用場(chǎng)景

通常在以下情況可以考慮使用訪問(wèn)者(Visitor)模式。

  • 對(duì)象結(jié)構(gòu)相對(duì)穩(wěn)定,但其操作算法經(jīng)常變化的程序。
  • 對(duì)象結(jié)構(gòu)中的對(duì)象需要提供多種不同且不相關(guān)的操作,而且要避免讓這些操作的變化影響對(duì)象的結(jié)構(gòu)。
  • 對(duì)象結(jié)構(gòu)包含很多類(lèi)型的對(duì)象,希望對(duì)這些對(duì)象實(shí)施一些依賴于其具體類(lèi)型的操作。

到此這篇關(guān)于Java訪問(wèn)者設(shè)計(jì)模式詳細(xì)講解的文章就介紹到這了,更多相關(guān)Java訪問(wèn)者模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java延遲隊(duì)列原理與用法實(shí)例詳解

    Java延遲隊(duì)列原理與用法實(shí)例詳解

    這篇文章主要介紹了Java延遲隊(duì)列原理與用法,結(jié)合實(shí)例形式詳細(xì)分析了延遲隊(duì)列的概念、原理、功能及具體使用方法,需要的朋友可以參考下
    2018-09-09
  • SpringBoot微信消息接口配置詳解

    SpringBoot微信消息接口配置詳解

    這篇文章主要介紹了SpringBoot 微信消息接口配置詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-06-06
  • java實(shí)現(xiàn)微信H5支付方法詳解

    java實(shí)現(xiàn)微信H5支付方法詳解

    本篇文章主要介紹了java實(shí)現(xiàn)微信H5支付方法詳解,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2017-04-04
  • 詳解Spring Security如何在權(quán)限中使用通配符

    詳解Spring Security如何在權(quán)限中使用通配符

    小伙伴們知道,在Shiro中,默認(rèn)是支持權(quán)限通配符的?,F(xiàn)在給用戶授權(quán)的時(shí)候,可以一個(gè)權(quán)限一個(gè)權(quán)限的配置,也可以直接用通配符。本文將介紹Spring Security如何在權(quán)限中使用通配符,需要的可以參考一下
    2022-06-06
  • Spring Boot 結(jié)合 aop 實(shí)現(xiàn)讀寫(xiě)分離

    Spring Boot 結(jié)合 aop 實(shí)現(xiàn)讀寫(xiě)分離

    這篇文章主要介紹了Spring Boot 結(jié)合 aop 實(shí)現(xiàn)讀寫(xiě)分離的示例,幫助大家更好的理解和使用Spring Boot框架,感興趣的朋友可以了解下
    2020-11-11
  • SpringBoot集成screw實(shí)現(xiàn)數(shù)據(jù)庫(kù)文檔生成的代碼示例

    SpringBoot集成screw實(shí)現(xiàn)數(shù)據(jù)庫(kù)文檔生成的代碼示例

    數(shù)據(jù)庫(kù)設(shè)計(jì)文檔是項(xiàng)目技術(shù)文檔的重要組成部分,Screw 是一款開(kāi)源的數(shù)據(jù)庫(kù)文檔生成工具,它支持多種數(shù)據(jù)庫(kù)類(lèi)型,并能生成豐富格式的文檔,本文將通過(guò)一個(gè)實(shí)際的例子,展示如何使用 Spring Boot 集成 Screw 生成數(shù)據(jù)庫(kù)設(shè)計(jì)文檔
    2024-07-07
  • SpringBoot使用@Value實(shí)現(xiàn)給靜態(tài)變量注入值

    SpringBoot使用@Value實(shí)現(xiàn)給靜態(tài)變量注入值

    這篇文章主要介紹了SpringBoot使用@Value實(shí)現(xiàn)給靜態(tài)變量注入值的方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • IDEA+Maven創(chuàng)建Spring項(xiàng)目的實(shí)現(xiàn)步驟

    IDEA+Maven創(chuàng)建Spring項(xiàng)目的實(shí)現(xiàn)步驟

    這篇文章主要介紹了IDEA+Maven創(chuàng)建Spring項(xiàng)目的實(shí)現(xiàn)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Java多線程和并發(fā)基礎(chǔ)面試題(問(wèn)答形式)

    Java多線程和并發(fā)基礎(chǔ)面試題(問(wèn)答形式)

    多線程和并發(fā)問(wèn)題是Java技術(shù)面試中面試官比較喜歡問(wèn)的問(wèn)題之一。在這里,從面試的角度列出了大部分重要的問(wèn)題,感興趣的小伙伴們可以參考一下
    2016-06-06
  • JavaSE文件操作工具類(lèi)FileUtil詳解

    JavaSE文件操作工具類(lèi)FileUtil詳解

    這篇文章主要為大家詳細(xì)介紹了JavaSE系列之文件操作工具類(lèi)FileUtil,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08

最新評(píng)論