国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

設(shè)計模式—訪問者模式

這篇具有很好參考價值的文章主要介紹了設(shè)計模式—訪問者模式。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

?需求:店鋪采購了一批水果(蘋果及橘子),現(xiàn)在市場監(jiān)督局來店里檢查過期的水果。

public class Fruit {

    private String name;
    private Date pickDate;

    public Fruit(String name, Date pickDate) {
        this.name = name;
        this.pickDate = pickDate;
    }

    public String getName() {
        return name;
    }

    public Date getPickDate() {
        return pickDate;
    }

    @Override
    public String toString() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm");
        return "{" +
                "name='" + name + '\'' +
                ", 采摘日期=" + simpleDateFormat.format(pickDate) +
                '}';
    }
}

public class Apple extends Fruit{

    public Apple(String name, Date pickDate) {
        super(name, pickDate);
    }
    
}

public class Orange extends Fruit{
    public Orange(String name, Date pickDate) {
        super(name, pickDate);
    }
}

public class FruitShop  {

    private final String name;

    public FruitShop(String name) {
        this.name = name;
    }

    private final List<Fruit> fruitList = new ArrayList<>();

    public List<Fruit> getFruitList() {
        return fruitList;
    }

    public String getName() {
        return name;
    }

}

public class FruitMarket {

    public static void main(String[] args) throws ParseException {
        FruitShop myShop = new FruitShop("老果農(nóng)");
        purchaseFruit(myShop);
        expCheck("市場監(jiān)督局",myShop); //市場監(jiān)督局檢查過期水果:蘋果過期時間5天,橘子過期時間10天
        expCheck("城管",myShop); //城管檢查過期水果:蘋果過期時間3天,橘子過期時間6天
        newArrival(myShop);//新品上市水果
    }

    // 采購水果
    public static void purchaseFruit(FruitShop shop) throws ParseException {
        List<Fruit> fruitList = shop.getFruitList();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm");
        fruitList.add(new Apple("富士康",simpleDateFormat.parse("2023-06-21 12:00")));
        fruitList.add(new Orange("贛南臍橙", simpleDateFormat.parse("2023-05-25 18:00")));
        fruitList.add(new Orange("韶關(guān)帝王橘", simpleDateFormat.parse("2023-6-18 21:00")));
        fruitList.add(new Apple("王掌柜",simpleDateFormat.parse("2023-06-11 12:00")));
    }

    // 過期檢查
    public static void expCheck(String development,FruitShop shop) {
        int appleExpDay = 0, orangeExpDay = 0;
        if ("市場監(jiān)督局".equals(development)) {
            appleExpDay = 5;
            orangeExpDay = 10;
        } else if ("城管".equals(development)) {
            appleExpDay = 2;
            orangeExpDay = 4;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DATE,-appleExpDay);
        Date appleExpDate = calendar.getTime();
        calendar.setTime(new Date());
        calendar.add(Calendar.DATE,-orangeExpDay);
        Date orangeExpDate = calendar.getTime();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm");
        System.out.println(development + "檢查 蘋果過期天數(shù):" + appleExpDay + "  橘子過期天數(shù):" + orangeExpDay + "  檢查時間:" + dateFormat.format(new Date()) + " " + shop.getName());
        for (Fruit fruit : shop.getFruitList()) {
            boolean exp = false;
            if (fruit instanceof Apple) {
                if (appleExpDate.after(fruit.getPickDate())) exp = true;
            } else if (fruit instanceof Orange) {
                if (orangeExpDate.after(fruit.getPickDate())) exp = true;
            }
            if (exp) System.out.println(fruit + "  過期! ");
        }
        System.out.println("-------");
    }
   
}

如果此時再添加一個操作:找出新品上市的水果。

// 新品上市 蘋果為2023-06-20 后采摘, 橘子為2023-06-21后采摘
    public static void newArrival(FruitShop shop) throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date appleNewDate = simpleDateFormat.parse("2023-06-20");
        Date orangeNewDate = simpleDateFormat.parse("2023-06-21");
        for (Fruit fruit : shop.getFruitList()) {
            boolean isNew = false;
            if (fruit instanceof Apple) {
                if(appleNewDate.before(fruit.getPickDate())) isNew = true;
            } else if (fruit instanceof  Orange) {
                if(orangeNewDate.before(fruit.getPickDate())) isNew= true;
            }
            if (isNew) System.out.println(fruit.getName() + " 新品上市");
        }
    }

上述代碼中,F(xiàn)ruitMarket為應(yīng)付新增操作,增加了相應(yīng)的方法來滿足要求,但這樣破壞了FruitMarket的結(jié)構(gòu)。

訪問者模式

本質(zhì)是將數(shù)據(jù)結(jié)構(gòu)和數(shù)據(jù)操作分離,通過定義一個訪問者對象,實現(xiàn)對數(shù)據(jù)結(jié)構(gòu)中各個元素的訪問和處理,從而達到解耦和靈活性的目的。

設(shè)計模式—訪問者模式

圖 訪問者UML

Visitor 抽象訪問者

為ObjectStructure對象結(jié)構(gòu)中的每一個Element都聲明一個Visit操作。

ConcreteVisitor具體訪問者

Visitor的實現(xiàn),實現(xiàn)要真正被添加到對象結(jié)構(gòu)中的功能。

ObjectStructure 對象結(jié)構(gòu)

通常包含多個被訪問的對象,可以是一個復合或是一個集合。

Element 抽象元素

為Visitor聲明一個accept方法,實現(xiàn)元素與訪問者的綁定。

ConcreteElement 具體元素

對象結(jié)構(gòu)體中具體的對象,是被訪問的對象。

/**
 * 水果元素抽象類
 */
public abstract class FruitElement {

    private String name;
    private Date pickDate;

    public FruitElement(String name, Date pickDate) {
        this.name = name;
        this.pickDate = pickDate;
    }

    public String getName() {
        return name;
    }

    public Date getPickDate() {
        return pickDate;
    }

    public abstract void accept(Visitor visitor);

    @Override
    public String toString() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm");
        return "{" +
                "name='" + name + '\'' +
                ", 采摘日期=" + simpleDateFormat.format(pickDate) +
                '}';
    }

}
public class AppleElement extends FruitElement{

    public AppleElement(String name, Date pickDate) {
        super(name, pickDate);
    }

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

}

public class OrangeElement extends FruitElement{

    public OrangeElement(String name, Date pickDate) {
        super(name, pickDate);
    }

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }

}
/**
 * 訪問者
 */
public interface Visitor {

    void visit(AppleElement apple);

    void visit(OrangeElement orange);

}

/**
 * 政府檢查部門
 */
public class DevelopmentVisitor implements Visitor{

    private final int appleExpDay;

    private final int orangeExpDay;

    public DevelopmentVisitor(String name, int appleExpDay, int orangeExpDay) {
        this.appleExpDay = appleExpDay;
        this.orangeExpDay = orangeExpDay;
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm");
        System.out.println(name + " 檢查過期水果, 蘋果過期天數(shù):" + appleExpDay + ",橘子過期天數(shù):" +
                orangeExpDay + " 檢查時間:" + dateFormat.format(new Date()));
    }

    @Override
    public void visit(AppleElement apple) {
        expCheck(apple, appleExpDay);
    }

    @Override
    public void visit(OrangeElement orange) {
        expCheck(orange,orangeExpDay);
    }

    private void expCheck(FruitElement fruit,int expDay) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DATE,-appleExpDay);
        Date appleExpDate = calendar.getTime();
        if (appleExpDate.after(fruit.getPickDate())) {
            System.out.println(fruit.getName() + " 過期!");
        }
    }
}


/**
 * 新品上市檢查
 */
public class NewArrivalVisitor implements Visitor {

    private final Date appleNewDate;

    private final Date orangeNewDate;

    public NewArrivalVisitor(Date appleNewDate, Date orangeNewDate) {
        this.appleNewDate = appleNewDate;
        this.orangeNewDate = orangeNewDate;
        System.out.println("新品上市檢查");
    }

    @Override
    public void visit(AppleElement apple) {
        if (appleNewDate.before(apple.getPickDate())) {
            System.out.println(apple.getName() + " 新品上市");
        }
    }

    @Override
    public void visit(OrangeElement orange) {
        if (orangeNewDate.before(orange.getPickDate())) {
            System.out.println(orange.getName() + " 新品上市");
        }
    }
}
/**
 * 水果店結(jié)構(gòu)
 */
public class FruitShopStructure {

    private final List<FruitElement> fruitList = new ArrayList<>();

    public List<FruitElement> getFruitList() {
        return fruitList;
    }

}
public class FruitMarket2 {

    public static void main(String[] args) throws ParseException {
        //新開一家水果店
        FruitShopStructure shop = new FruitShopStructure();
        purchaseFruit(shop);

        System.out.println("------------------------------");
        //市場監(jiān)督局來檢查是否存在過期水果
        DevelopmentVisitor devVisitor1 = new DevelopmentVisitor("市場監(jiān)督局", 5, 10);
        for (FruitElement element : shop.getFruitList()) {
            element.accept(devVisitor1);
        }
        System.out.println("------------------------------");
        //農(nóng)業(yè)局來檢查是否存在過期水果
        DevelopmentVisitor devVisitor2 = new DevelopmentVisitor("農(nóng)業(yè)局", 2, 4);
        for (FruitElement element : shop.getFruitList()) {
            element.accept(devVisitor2);
        }
        System.out.println("------------------------------");
        //檢查新品上市
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        NewArrivalVisitor newArrivalVisitor = new NewArrivalVisitor(simpleDateFormat.parse("2023-06-20"), simpleDateFormat.parse("2023-06-21"));
        for (FruitElement element : shop.getFruitList()) {
            element.accept(newArrivalVisitor);
        }
    }

    // 采購水果
    public static void purchaseFruit(FruitShopStructure shop) throws ParseException {
        List<FruitElement> fruitList = shop.getFruitList();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm");
        fruitList.add(new AppleElement("富士康",simpleDateFormat.parse("2023-06-21 12:00")));
        fruitList.add(new OrangeElement("贛南臍橙", simpleDateFormat.parse("2023-05-25 18:00")));
        fruitList.add(new OrangeElement("韶關(guān)帝王橘", simpleDateFormat.parse("2023-6-18 21:00")));
        fruitList.add(new AppleElement("王掌柜",simpleDateFormat.parse("2023-06-11 12:00")));
    }
}

設(shè)計模式—訪問者模式

圖 運行結(jié)果?

以上代碼是用訪問者模式實現(xiàn)文章開頭處的需求。

優(yōu)點

  1. 好的擴展性,能夠在不修改對象結(jié)構(gòu)中的元素的情況下,為對象結(jié)構(gòu)中的元素添加新的功能。
  2. 好的復用性,可以通過訪問者來定義整個對象結(jié)構(gòu)通用的功能,從而提高復用程度。
  3. 分離無關(guān)行為,通過訪問者來分離無關(guān)的行為,把相關(guān)行為封裝在一起,構(gòu)成一個訪問者,這樣每個訪問者的功能都比較單一。

缺點

1)對象結(jié)構(gòu)變化很困難,不適用于對象結(jié)構(gòu)中的類經(jīng)常變化的情況,當對象結(jié)構(gòu)發(fā)生改變時,訪問者的接口及實現(xiàn)都要做相應(yīng)改變。

2)破壞封裝,訪問者模式通常需要對象結(jié)構(gòu)開放內(nèi)部數(shù)據(jù)給訪問者和ObjectStructure,這破壞了對象的封裝性。

應(yīng)用場景

1)需要對一個復雜的數(shù)據(jù)結(jié)構(gòu)進行操作,并且這些操作可能需要根據(jù)不同的元素類型進行變化。

2)當數(shù)據(jù)結(jié)構(gòu)中的元素種類相對穩(wěn)定,但可能需要新增一些新的操作時。文章來源地址http://www.zghlxwxcb.cn/news/detail-498370.html

到了這里,關(guān)于設(shè)計模式—訪問者模式的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 設(shè)計模式之訪問者模式(上)

    設(shè)計模式之訪問者模式(上)

    訪問者模式 1)概述 1.概念 訪問者模式包含 訪問者 和 被訪問元素 兩個主要組成部分。 處方單中的各種藥品信息就是 被訪問的元素 ,而劃價人員和藥房工作人員就是 訪問者 ,被訪問的元素通常具有不同的類型,且不同的訪問者可以對它們進行不同的訪問操作。 被訪問元素

    2024年04月25日
    瀏覽(56)
  • js設(shè)計模式:訪問者模式

    js設(shè)計模式:訪問者模式

    將操作方法封裝在一個訪問者對象中,而不是封裝在每個被訪問對象當中。 訪問者對象可以通過調(diào)用被訪問者的接口,用來操作被訪問者。

    2024年02月22日
    瀏覽(36)
  • Java設(shè)計模式-訪問者模式

    在軟件開發(fā)領(lǐng)域中,設(shè)計模式是解決常見問題的經(jīng)典方法。其中,訪問者模式是一種強大且靈活的設(shè)計模式,用于處理對象結(jié)構(gòu)中的元素,并根據(jù)不同的訪問者實現(xiàn)不同的操作。 訪問者模式是一種行為型設(shè)計模式,它允許你在不改變元素類的前提下定義新的操作。該模式將算

    2024年02月06日
    瀏覽(20)
  • 03-JAVA設(shè)計模式-訪問者模式

    03-JAVA設(shè)計模式-訪問者模式

    訪問者模式(Visitor Pattern)是軟件設(shè)計模式中的一種行為模式,它用于將數(shù)據(jù)結(jié)構(gòu)中的元素與操作這些元素的操作解耦。這種模式使得可以在不修改數(shù)據(jù)結(jié)構(gòu)的情況下添加新的操作。 在訪問者模式中,我們定義了兩個主要角色: 訪問者(Visitor): 這個接口聲明了一個訪問元

    2024年04月29日
    瀏覽(45)
  • 設(shè)計模式:訪問者模式(C++實現(xiàn))

    訪問者模式通過將對元素的操作與元素本身分離,使得可以在不修改元素類的情況下定義新的操作。 運行結(jié)果: 在上述代碼中,Visitor是訪問者接口,定義了訪問具體元素的方法。Element是元素接口,定義了接受訪問者訪問的方法。ConcreteElementA和ConcreteElementB是具體元素類,實

    2024年02月07日
    瀏覽(36)
  • 設(shè)計模式(二十三)訪問者

    設(shè)計模式(二十三)訪問者

    表示一個作用于某對象結(jié)構(gòu)中的各個元素的操作。訪問者模式讓你可以在不改變各元素的類的前提下定義作用于這些元素的新操作。訪問者模式是一種對象行為型模式 訪問者模式是一種較為復雜的行為型模式,它包含訪問者和被訪問元素兩個主要組成部分,這些被訪問的元素

    2024年02月19日
    瀏覽(21)
  • 【設(shè)計模式與范式:行為型】69 | 訪問者模式(下):為什么支持雙分派的語言不需要訪問者模式?

    上一節(jié)課中,我們學習了訪問者模式的原理和實現(xiàn),并且還原了訪問者模式誕生的思維過程??傮w上來講,這個模式的代碼實現(xiàn)比較難,所以應(yīng)用場景并不多。從應(yīng)用開發(fā)的角度來說,它的確不是我們學習的重點。 不過,我們前面反復說過,學習我的專欄,并不只是讓你掌握

    2024年02月10日
    瀏覽(23)
  • 笨蛋學設(shè)計模式行為型模式-訪問者模式【21】

    8.8.1概念 ? 訪問者模式是一種將操作邏輯與對象結(jié)構(gòu)分離的方法,使得操作可以獨立變化,操作邏輯被封裝在獨立的訪問者類中,并在被訪問的元素類中提供接受訪問者的方法,而不是直接嵌入到數(shù)據(jù)結(jié)構(gòu)中的對象中。 8.8.2場景 ? 我們可以將一個購物商場中的商品類作為元

    2024年01月23日
    瀏覽(23)
  • 瑞_23種設(shè)計模式_訪問者模式

    瑞_23種設(shè)計模式_訪問者模式

    ?? 前言:本文章為瑞_系列專欄之《23種設(shè)計模式》的訪問者模式篇。本文中的部分圖和概念等資料,來源于博主學習設(shè)計模式的相關(guān)網(wǎng)站《菜鳥教程 | 設(shè)計模式》和《黑馬程序員Java設(shè)計模式詳解》,特此注明。本文中涉及到的軟件設(shè)計模式的概念、背景、優(yōu)點、分類、以及

    2024年04月15日
    瀏覽(20)
  • 【設(shè)計模式】字節(jié)三面:請舉例闡釋訪問者模式

    【設(shè)計模式】字節(jié)三面:請舉例闡釋訪問者模式

    今天我們要一起探討的主題是一種設(shè)計模式——訪問者模式(Visitor Pattern)。我將從最基礎(chǔ)的概念、應(yīng)用場景,再到實例代碼的展示,全方位的為大家剖析訪問者模式。而且,我保證,你即使是編程新手, 也能理解并開始應(yīng)用這個設(shè)計模式! 首先,讓我們先看一眼訪問者模式的

    2024年01月23日
    瀏覽(30)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包