最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java訪問者設計模式詳細講解

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

編程是一門藝術,大批量的改動顯然是非常丑陋的做法,用心的琢磨寫的代碼讓它變的更美觀。

在生活中,電影或電視劇中的人物角色,不同的觀眾對他們的評價也不同;還有顧客在商場購物時放在“購物車”中的商品,顧客主要關心所選商品的性價比,而收銀員關心的是商品的價格和數(shù)量。

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

1.模式的定義

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

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

2.訪問者設計模式的優(yōu)點與不足

訪問者(Visitor)模式是一種對象行為型模式,其主要優(yōu)點:

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

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

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

3.訪問者設計模式的實現(xiàn)思路

訪問者(Visitor)模式實現(xiàn)的關鍵是如何將作用于元素的操作分離出來封裝成獨立的類

訪問者模式包含以下主要角色。

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

4.訪問者設計模式實例

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

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("蘋果紅富士");
    }
    public void setPrice(int price) {
        this.price = price;
    }
    public int accept(Visit visit){
        /*指針可以傳遞真實類型*/
        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 {
	/*蘋果計價*/
	public int sell(Apple apple){
		System.out.println("apple's price: ¥50");
		return 50;
	}
	/*桔子計價*/
	public int sell(Orange orange){
		System.out.println("orange's price: ¥20");
		return 20;
	}
	/*香蕉計價*/
	public int sell(Banana banana){
		System.out.println("banana's price: ¥30");
		return 30;
	}
	//其它水果計價
	public int sell(Fruit fruit){
		System.out.println("other price: ¥10");
		return 10;
	}
}
public class VisitClient {
    private static Visit visit = new Visit();
    /*庫存*/
    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("總價值:" + total);
        return total;
    }
      public static void main(String[] args) {
        price();
    }

訪問者設計模式的關鍵是:不能直接使用visit對象直接調(diào)用sell方法將水果對象傳遞進去,因為直接傳遞進去由于方法重載的靜態(tài)化問題,不會執(zhí)行相應的方法,需要是使用fruit的accept方法才行。

5.訪問者設計模式的使用場景

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

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

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

相關文章

  • HttpServletRequestWrapper干預Request處理流程解析

    HttpServletRequestWrapper干預Request處理流程解析

    這篇文章主要分析在?Tomcat的處理?http?請求的流程中干預?Request對象,?通過基于HttpServletRequestWrapper和?Filter組合進行干預,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2023-09-09
  • Android中的LinearLayout布局

    Android中的LinearLayout布局

    在一般情況下,當有很多控件需要在一個界面列出來時,我們就可以使用線性布局(LinearLayout)了,線性布局是按照垂直方向(vertical)或水平方向(horizontal)的順序依次排序子元素,每一個子元素都位于前一個元素之后,下面我們就簡單的了解一下吧
    2017-01-01
  • 簡單了解spring bean的循環(huán)引用

    簡單了解spring bean的循環(huán)引用

    這篇文章主要介紹了簡單了解spring bean的循環(huán)引用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-08-08
  • 23種設計模式(9) java橋接模式

    23種設計模式(9) java橋接模式

    這篇文章主要為大家詳細介紹了java設計模式之橋接模式,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • JVM Client和Server端有什么區(qū)別

    JVM Client和Server端有什么區(qū)別

    這篇文章主要介紹了JVM Client和Server端有什么區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-11-11
  • 淺析Java中Apache BeanUtils和Spring BeanUtils的用法

    淺析Java中Apache BeanUtils和Spring BeanUtils的用法

    這篇文章主要介紹了Java中Apache BeanUtils和Spring BeanUtils的用法,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11
  • SpringBoot學習之全局異常處理設置(返回JSON)

    SpringBoot學習之全局異常處理設置(返回JSON)

    本篇文章主要介紹了SpringBoot學習之全局異常處理設置(返回JSON),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-02-02
  • kotlin快速入門之標準函數(shù)與靜態(tài)方法

    kotlin快速入門之標準函數(shù)與靜態(tài)方法

    學完了Kotlin的基礎知識,是時候來來學習 Kotlin的標準函數(shù)和靜態(tài)方法了,下面這篇文章主要給大家介紹了關于kotlin快速入門之標準函數(shù)與靜態(tài)方法的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2021-09-09
  • spring中actuator監(jiān)視器配置詳解

    spring中actuator監(jiān)視器配置詳解

    這篇文章主要介紹了spring中actuator監(jiān)視器配置詳解,actuator主要是完成微服務的監(jiān)控,完成監(jiān)控治理,可以查看微服務間的數(shù)據(jù)處理和調(diào)用,當它們之間出現(xiàn)了異常,就可以快速定位到出現(xiàn)問題的地方,需要的朋友可以參考下
    2023-09-09
  • 使用Iterator刪除List中的多個元素操作

    使用Iterator刪除List中的多個元素操作

    這篇文章主要介紹了使用Iterator刪除List中的多個元素操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09

最新評論

衡东县| 深水埗区| 东城区| 突泉县| 松溪县| 建昌县| 独山县| 武汉市| 清水县| 建瓯市| 巴里| 兴化市| 安西县| 女性| 集安市| 临沂市| 淳化县| 阿拉善右旗| 灵宝市| 澄迈县| 隆子县| 信丰县| 沈丘县| 衡东县| 醴陵市| 武陟县| 贵港市| 桐梓县| 宜都市| 肃宁县| 六枝特区| 峨眉山市| 伊宁县| 广昌县| 垫江县| 南乐县| 手游| 高密市| 榆中县| 桦甸市| 察雅县|