日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 综合教程 >内容正文

综合教程

七:策略模式(不同等级会员打折算法)

發(fā)布時(shí)間:2023/12/29 综合教程 35 生活家
生活随笔 收集整理的這篇文章主要介紹了 七:策略模式(不同等级会员打折算法) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

定義:策略模式定義了一系列的算法,并將每一個(gè)算法封裝起來(lái),而且使它們還可以相互替換。策略模式讓算法獨(dú)立于使用它的客戶(hù)而獨(dú)立變化;

下面給出策略模式的類(lèi)圖,引自百度百科。

策略模式在LZ第一次接觸到的時(shí)候,LZ是這么理解的,就是如果我們想往一個(gè)方法當(dāng)中插入隨便一段代碼的話(huà),就是策略模式。即如下形式。

public class MyClass {

    public void myMethod(){
        System.out.println("方法里的代碼");
        //LZ想在這插入一段代碼,而且這個(gè)代碼是可以改變的,想怎么變就怎么變
        System.out.println("方法里的代碼");
    }
}

在JAVA中,接口可以滿(mǎn)足LZ的這一過(guò)分要求,我們可以設(shè)計(jì)一個(gè)接口,并當(dāng)做參數(shù)傳進(jìn)去,就能達(dá)到這個(gè)效果了。我們來(lái)看,先定義一個(gè)接口。

public interface MyInterface {
    //我想插入的代碼
    void insertCode();
    
}

將原來(lái)的類(lèi)改成這樣,傳遞一個(gè)接口進(jìn)去。

public class MyClass {

    public void myMethod(MyInterface myInterface){
        System.out.println("方法里的代碼");
        //你看我是不是插進(jìn)來(lái)一段代碼?而且這段代碼是可以隨便改變的
        myInterface.insertCode();
        System.out.println("方法里的代碼");
    }
}

我們只要實(shí)現(xiàn)了MyInterface這個(gè)接口,在insertCode方法中寫(xiě)入我們想要插進(jìn)去的代碼,再將這個(gè)類(lèi)傳遞給myMethod方法,就可以將我們隨手寫(xiě)的代碼插到這個(gè)方法當(dāng)中。比如這樣。

class InsertCode1 implements MyInterface{

    public void insertCode() {
        System.out.println("我想插進(jìn)去的代碼,第一種");
    }

}

class InsertCode2 implements MyInterface{

    public void insertCode() {
        System.out.println("我想插進(jìn)去的代碼,第二種");
    }

}

這樣我們?cè)谡{(diào)用myMethod方法時(shí)就可以隨意往里面插入代碼了,比如。

//客戶(hù)端調(diào)用
public class Client {

    public static void main(String[] args) {
        MyClass myClass = new MyClass();
        myClass.myMethod(new InsertCode1());
        System.out.println("--------------------");
        myClass.myMethod(new InsertCode2());
    }
    
}

那么運(yùn)行出來(lái)的結(jié)果就是我們成功的將兩端代碼插入到了myMethod方法中,以上所講的算是JAVA中一種技術(shù)層面的實(shí)現(xiàn),就是傳入一個(gè)接口,封裝代碼。那么既然談到設(shè)計(jì)模式,就要有設(shè)計(jì)模式的應(yīng)用場(chǎng)景,有關(guān)策略模式,所產(chǎn)生的形式就和上述是一模一樣的,只是我們適當(dāng)?shù)慕o予模式的應(yīng)用場(chǎng)景,就會(huì)讓它變的更有價(jià)值。

上面的例子代碼清晰但卻理解起來(lái)很生硬,下面LZ舉一個(gè)具有實(shí)際意義的例子。

就比如我們要做一個(gè)商店的收銀系統(tǒng),這個(gè)商店有普通顧客,會(huì)員,超級(jí)會(huì)員以及金牌會(huì)員的區(qū)別,針對(duì)各個(gè)顧客,有不同的打折方式,并且一個(gè)顧客每在商店消費(fèi)1000就增加一個(gè)級(jí)別,那么我們就可以使用策略模式,因?yàn)椴呗阅J矫枋龅木褪撬惴ǖ牟煌疫@個(gè)算法往往非常繁多,并且可能需要經(jīng)常性的互相替換。

這里我們舉例就采用最簡(jiǎn)單的,以上四種顧客分別采用原價(jià),八折,七折和半價(jià)的收錢(qián)方式。

那么我們首先要有一個(gè)計(jì)算價(jià)格的策略接口,如下。

public interface CalPrice {
    //根據(jù)原價(jià)返回一個(gè)最終的價(jià)格
    Double calPrice(Double originalPrice);
    
}

下面我們給出四個(gè)計(jì)算方式。

class Common implements CalPrice{

    public Double calPrice(Double originalPrice) {
        return originalPrice;
    }

}
class Vip implements CalPrice{

    public Double calPrice(Double originalPrice) {
        return originalPrice * 0.8;
    }

}
class SuperVip implements CalPrice{

    public Double calPrice(Double originalPrice) {
        return originalPrice * 0.7;
    }

}
class GoldVip implements CalPrice{

    public Double calPrice(Double originalPrice) {
        return originalPrice * 0.5;
    }

}

以上四種計(jì)算方式非常清晰,分別是原價(jià),八折,七折和半價(jià)。下面我們看客戶(hù)類(lèi),我們需要客戶(hù)類(lèi)幫我們完成客戶(hù)升級(jí)的功能。

//客戶(hù)類(lèi)
public class Customer {

    private Double totalAmount = 0D;//客戶(hù)在本商店消費(fèi)的總額
    private Double amount = 0D;//客戶(hù)單次消費(fèi)金額
    private CalPrice calPrice = new Common();//每個(gè)客戶(hù)都有一個(gè)計(jì)算價(jià)格的策略,初始都是普通計(jì)算,即原價(jià)
    
    //客戶(hù)購(gòu)買(mǎi)商品,就會(huì)增加它的總額
    public void buy(Double amount){
        this.amount = amount;
        totalAmount += amount;
        if (totalAmount > 3000) {//3000則改為金牌會(huì)員計(jì)算方式
            calPrice = new GoldVip();
        }else if (totalAmount > 2000) {//類(lèi)似
            calPrice = new SuperVip();
        }else if (totalAmount > 1000) {//類(lèi)似
            calPrice = new Vip();
        }
    }
    //計(jì)算客戶(hù)最終要付的錢(qián)
    public Double calLastAmount(){
        return calPrice.calPrice(amount);
    }
}

下面我們看客戶(hù)端調(diào)用,系統(tǒng)會(huì)幫我們自動(dòng)調(diào)整收費(fèi)策略。

//客戶(hù)端調(diào)用
public class Client {

    public static void main(String[] args) {
        Customer customer = new Customer();
        customer.buy(500D);
        System.out.println("客戶(hù)需要付錢(qián):" + customer.calLastAmount());
        customer.buy(1200D);
        System.out.println("客戶(hù)需要付錢(qián):" + customer.calLastAmount());
        customer.buy(1200D);
        System.out.println("客戶(hù)需要付錢(qián):" + customer.calLastAmount());
        customer.buy(1200D);
        System.out.println("客戶(hù)需要付錢(qián):" + customer.calLastAmount());
    }
    
}

 運(yùn)行以后會(huì)發(fā)現(xiàn),第一次是原價(jià),第二次是八折,第三次是七折,最后一次則是半價(jià)。我們這樣設(shè)計(jì)的好處是,客戶(hù)不再依賴(lài)于具體的收費(fèi)策略,依賴(lài)于抽象永遠(yuǎn)是正確的。不過(guò)上述的客戶(hù)類(lèi)實(shí)在有點(diǎn)難看,尤其是buy方法,我們可以使用簡(jiǎn)單工廠來(lái)稍微改進(jìn)一下它。我們建立如下策略工廠。

//我們使用一個(gè)標(biāo)準(zhǔn)的簡(jiǎn)單工廠來(lái)改進(jìn)一下策略模式
public class CalPriceFactory {

    private CalPriceFactory(){}
    //根據(jù)客戶(hù)的總金額產(chǎn)生相應(yīng)的策略
    public static CalPrice createCalPrice(Customer customer){
        if (customer.getTotalAmount() > 3000) {//3000則改為金牌會(huì)員計(jì)算方式
            return new GoldVip();
        }else if (customer.getTotalAmount() > 2000) {//類(lèi)似
            return new SuperVip();
        }else if (customer.getTotalAmount() > 1000) {//類(lèi)似
            return new Vip();
        }else {
            return new Common();
        }
    }
}

這樣我們就將制定策略的功能從客戶(hù)類(lèi)分離了出來(lái),我們的客戶(hù)類(lèi)可以變成這樣。

//客戶(hù)類(lèi)
public class Customer {

    private Double totalAmount = 0D;//客戶(hù)在本商店消費(fèi)的總額
    private Double amount = 0D;//客戶(hù)單次消費(fèi)金額
    private CalPrice calPrice = new Common();//每個(gè)客戶(hù)都有一個(gè)計(jì)算價(jià)格的策略,初始都是普通計(jì)算,即原價(jià)
    
    //客戶(hù)購(gòu)買(mǎi)商品,就會(huì)增加它的總額
    public void buy(Double amount){
        this.amount = amount;
        totalAmount += amount;
        /* 變化點(diǎn),我們將策略的制定轉(zhuǎn)移給了策略工廠,將這部分責(zé)任分離出去 */
        calPrice = CalPriceFactory.createCalPrice(this);
    }
    //計(jì)算客戶(hù)最終要付的錢(qián)
    public Double calLastAmount(){
        return calPrice.calPrice(amount);
    }
    
    public Double getTotalAmount() {
        return totalAmount;
    }
    
    public Double getAmount() {
        return amount;
    }
    
}

現(xiàn)在比之前來(lái)講,我們的策略模式更加靈活一點(diǎn),但是相信看過(guò)LZ博文的都知道,LZ最不喜歡elseif,所以策略模式也是有缺點(diǎn)的,就是當(dāng)策略改變時(shí),我們需要使用elseif去判斷到底使用哪一個(gè)策略,哪怕使用簡(jiǎn)單工廠,也避免不了這一點(diǎn)。比如我們又添加一類(lèi)會(huì)員,那么你需要去添加elseif。再比如我們的會(huì)員現(xiàn)在打九折了,那么你需要添加一個(gè)九折的策略,這沒(méi)問(wèn)題,我們對(duì)擴(kuò)展開(kāi)放,但是你需要修改elseif的分支,將會(huì)員的策略從八折替換為九折,這是簡(jiǎn)單工廠的詬病,在之前已經(jīng)提到過(guò),對(duì)修改開(kāi)放。

總結(jié)

以上是生活随笔為你收集整理的七:策略模式(不同等级会员打折算法)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。