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

策略模式:告別if else

 更新時(shí)間:2021年06月08日 12:02:55   作者:活躍的咸魚(yú)  
你是不是還在寫(xiě)著大量的if else語(yǔ)句,if else 不僅難以維護(hù)不易擴(kuò)展,而且使代碼臃腫不堪,想不想讓你的業(yè)務(wù)代碼更加的健壯,更易擴(kuò)展,那你一定要學(xué)一學(xué)今天的主角策略模式

閱讀完本篇文章你將了解到什么是策略模式,策略模式的優(yōu)缺點(diǎn),以及策略模式在源碼中的應(yīng)用。

策略模式引入

在軟件開(kāi)發(fā)中,我們常常會(huì)遇到這樣的情況,實(shí)現(xiàn)某一個(gè)功能有多條途徑,每一條途徑對(duì)應(yīng)一種算法,此時(shí)我們可以使用一種設(shè)計(jì)模式來(lái)實(shí)現(xiàn)靈活地選擇解決途徑,也能夠方便地增加新的解決途徑。

譬如商場(chǎng)購(gòu)物場(chǎng)景中,有些商品按原價(jià)賣(mài),商場(chǎng)可能為了促銷(xiāo)而推出優(yōu)惠活動(dòng),有些商品打九折,有些打八折,有些則是返現(xiàn)10元等。而優(yōu)惠活動(dòng)并不影響結(jié)算之外的其他過(guò)程,只是在結(jié)算的時(shí)候需要根據(jù)優(yōu)惠方案結(jié)算。

再比如不同的人出去旅游出行的交通方式也不同,經(jīng)濟(jì)條件好的會(huì)選擇高鐵飛機(jī),而普通人可能會(huì)選擇綠皮火車(chē)。

在這里插入圖片描述

富豪老王打算去西藏旅游,老王定了豪華酒店,并且定了機(jī)票當(dāng)天直達(dá)。而普通人老張也要去西藏旅游,他打算選擇乘坐高鐵出行。而學(xué)生黨的我小汪肯定會(huì)選擇綠皮火車(chē),主要是為了看路邊的風(fēng)景,而不是因?yàn)楦F。

下面我們用代碼來(lái)描述一下上訴場(chǎng)景:

public class Travel {
    private String vehicle;//出行方式
    private String name;
    public String getName() {
        return name;
    }
    public Travel(String name) {
        this.name = name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void setVehicle(String vehicle) {
        this.vehicle = vehicle;
    }
    public String getVehicle() {
        return vehicle;
    }
    public void TravelTool(){
        if(name.equals("小汪")){
            setVehicle("綠皮火車(chē)");
        }else if(name.equals("老張")){
            setVehicle("高鐵");
        }else if(name.equals("老王")){
            setVehicle("飛機(jī)");
        }
        System.out.println(name+"選擇坐"+getVehicle()+"去西藏旅游");
    }
}
public class Test {
    public static void main(String[] args) {
        Travel travel1 = new Travel("小汪");
        Travel travel2 = new Travel("老王");
        Travel travel3 = new Travel("老張");
        travel1.TravelTool();
        travel2.TravelTool();
        travel3.TravelTool();
    }
}
小汪選擇坐綠皮火車(chē)去西藏旅游
老王選擇坐飛機(jī)去西藏旅游
老張選擇坐高鐵去西藏旅游

以上代碼雖然完成了我們的需求,但是存在以下問(wèn)題

Travel類(lèi)的TravelTool方法非常龐大,它包含各種人的旅行實(shí)現(xiàn)代碼,在代碼中出現(xiàn)了較長(zhǎng)的 if…else… 語(yǔ)句,假如日后小汪發(fā)達(dá)了也想體驗(yàn)一下做飛機(jī)去西藏旅游,那就要去修改TravelTool方法。違反了 “開(kāi)閉原則”,系統(tǒng)的靈活性和可擴(kuò)展性較差。

算法的復(fù)用性差,如果在另一個(gè)系統(tǒng)中需要重用某些算法,只能通過(guò)對(duì)源代碼進(jìn)行復(fù)制粘貼來(lái)重用,無(wú)法單獨(dú)重用其中的某個(gè)或某些算法。

策略模式

策略模式的介紹

策略模式(Strategy Pattern)中,定義算法族,分別封裝起來(lái),讓他們之間可以互相替換,此模式讓算法的變化獨(dú)立于使用算法的客戶(hù)這算法體現(xiàn)了幾個(gè)設(shè)計(jì)原則,

第一、把變化的代碼從不變的代碼中分離出來(lái);

第二、針對(duì)接口編程而不是具體類(lèi)(定義了策略接口);

第三、多用組合/聚合,少用繼承(客戶(hù)通過(guò)組合方式使用策略)。

策略模式的原理類(lèi)圖

在這里插入圖片描述

角色分析

Context(環(huán)境類(lèi)):環(huán)境類(lèi)是使用算法的角色,它在解決某個(gè)問(wèn)題(即實(shí)現(xiàn)某個(gè)方法)時(shí)可以采用多種策略。在環(huán)境類(lèi)中維持一個(gè)對(duì)抽象策略類(lèi)的引用實(shí)例,用于定義所采用的策略。

Strategy(抽象策略類(lèi)):它為所支持的算法聲明了抽象方法,是所有策略類(lèi)的父類(lèi),它可以是抽象類(lèi)或具體類(lèi),也可以是接口。環(huán)境類(lèi)通過(guò)抽象策略類(lèi)中聲明的方法在運(yùn)行時(shí)調(diào)用具體策略類(lèi)中實(shí)現(xiàn)的算法。

ConcreteStrategy(具體策略類(lèi)):它實(shí)現(xiàn)了在抽象策略類(lèi)中聲明的算法,在運(yùn)行時(shí),具體策略類(lèi)將覆蓋在環(huán)境類(lèi)中定義的抽象策略類(lèi)對(duì)象,使用一種具體的算法實(shí)現(xiàn)某個(gè)業(yè)務(wù)處理。

我們下面用策略模式來(lái)改進(jìn)一下上面旅行的代碼例子。

抽象策略類(lèi) Discount

public abstract class AbstractTravle {
    private String vehicle;
    private String name;
    public AbstractTravle(String vehicle, String name) {
        this.vehicle = vehicle;
        this.name = name;
    }
    public String getVehicle() {
        return vehicle;
    }
    public String getName() {
        return name;
    }
    public abstract void TravelTool();
}

ConcreteStrategy(具體策略類(lèi))

public class XiaoWang extends AbstractTravle{
    public XiaoWang(String vehicle, String name) {
        super(vehicle, name);
    }
    @Override
    public void TravelTool() {
        System.out.println(getName()+"選擇坐"+getVehicle()+"去西藏旅游");
    }
}
public class LaoWang extends AbstractTravle{
    public LaoWang(String vehicle, String name) {
        super(vehicle, name);
    }
    @Override
    public void TravelTool() {
        System.out.println(getName()+"選擇坐"+getVehicle()+"去西藏旅游");
    }
}
public class LaoZhang extends AbstractTravle{
    public LaoZhang(String vehicle, String name) {
        super(vehicle, name);
    }
    @Override
    public void TravelTool() {
        System.out.println(getName()+"選擇坐"+getVehicle()+"去西藏旅游");
    }
}

環(huán)境類(lèi)

public class Context {
    private AbstractTravle abstractTravle;
    public Context(AbstractTravle abstractTravle) {
        this.abstractTravle = abstractTravle;
    }
    public void TravelTool() {
        System.out.println(abstractTravle.getName()+"選擇坐"+abstractTravle.getVehicle()+"去西藏旅游");
    }
}

策略模式總結(jié)

public class Test {
    public static void main(String[] args) {
        Context context1 = new Context(new LaoWang("飛機(jī)", "老王"));
        context1.TravelTool();
        Context context2 = new Context(new LaoZang("高鐵", "老張"));
        context2.TravelTool();
        Context context3 = new Context(new XiaoWang("綠皮火車(chē)", "小汪"));
        context3.TravelTool();
    }
}
老王選擇坐飛機(jī)去西藏旅游
老張選擇坐高鐵去西藏旅游
小汪選擇坐綠皮火車(chē)去西藏旅游

策略模式的主要優(yōu)點(diǎn)如下

1.模式提供了對(duì) “開(kāi)閉原則” 的完美支持,用戶(hù)可以在不修改原有系統(tǒng)的基礎(chǔ)上選擇算法或行為,也可以靈活地增加新的算法或行為。

2.模式提供了管理相關(guān)的算法族的辦法。策略類(lèi)的等級(jí)結(jié)構(gòu)定義了一個(gè)算法或行為族,恰當(dāng)使用繼承可以把公共的代碼移到抽象策略類(lèi)中,從而避免重復(fù)的代碼。

3.模式提供了一種可以替換繼承關(guān)系的辦法。如果不使用策略模式而是通過(guò)繼承,這樣算法的使用就和算法本身混在一起,不符合 “單一職責(zé)原則”,而且使用繼承無(wú)法實(shí)現(xiàn)算法或行為在程序運(yùn)行時(shí)的動(dòng)態(tài)切換。

4.模式可以避免多重條件選擇語(yǔ)句。多重條件選擇語(yǔ)句是硬編碼,不易維護(hù)。

5.模式提供了一種算法的復(fù)用機(jī)制,由于將算法單獨(dú)提取出來(lái)封裝在策略類(lèi)中,因此不同的環(huán)境類(lèi)可以方便地復(fù)用這些策略類(lèi)。

策略模式的主要缺點(diǎn)如下

1.端必須知道所有的策略類(lèi),并自行決定使用哪一個(gè)策略類(lèi)。這就意味著客戶(hù)端必須理解這些算法的區(qū)別,以便適時(shí)選擇恰當(dāng)?shù)乃惴?。換言之,策略模式只適用于客戶(hù)端知道所有的算法或行為的情況。

2.將造成系統(tǒng)產(chǎn)生很多具體策略類(lèi),任何細(xì)小的變化都將導(dǎo)致系統(tǒng)要增加一個(gè)新的具體策略類(lèi)。

3.同時(shí)在客戶(hù)端使用多個(gè)策略類(lèi),也就是說(shuō),在使用策略模式時(shí),客戶(hù)端每次只能使用一個(gè)策略類(lèi),不支持使用一個(gè)策略類(lèi)完成部分功能后再使用另一個(gè)策略類(lèi)來(lái)完成剩余功能的情況。

適用場(chǎng)景

1.系統(tǒng)需要?jiǎng)討B(tài)地在幾種算法中選擇一種,那么可以將這些算法封裝到一個(gè)個(gè)的具體算法類(lèi)中,而這些具體算法類(lèi)都是一個(gè)抽象算法類(lèi)的子類(lèi)。換言之,這些具體算法類(lèi)均有統(tǒng)一的接口,根據(jù) “里氏代換原則” 和面向?qū)ο蟮亩鄳B(tài)性,客戶(hù)端可以選擇使用任何一個(gè)具體算法類(lèi),并只需要維持一個(gè)數(shù)據(jù)類(lèi)型是抽象算法類(lèi)的對(duì)象。

2.對(duì)象有很多的行為,如果不用恰當(dāng)?shù)哪J?,這些行為就只好使用多重條件選擇語(yǔ)句來(lái)實(shí)現(xiàn)。此時(shí),使用策略模式,把這些行為轉(zhuǎn)移到相應(yīng)的具體策略類(lèi)里面,就可以避免使用難以維護(hù)的多重條件選擇語(yǔ)句。

3.望客戶(hù)端知道復(fù)雜的、與算法相關(guān)的數(shù)據(jù)結(jié)構(gòu),在具體策略類(lèi)中封裝算法與相關(guān)的數(shù)據(jù)結(jié)構(gòu),可以提高算法的保密性與安全性。

源碼分析策略模式的典型應(yīng)用

Java Comparator 中的策略模式

java.util.Comparator 接口是比較器接口,可以通過(guò) Collections.sort(List,Comparator) 和 Arrays.sort(Object[],Comparator) 對(duì)集合和數(shù)據(jù)進(jìn)行排序,下面為示例程序

@Data
@AllArgsConstructor
public class Student {
    private Integer id;
    private String name;
    @Override
    public String toString() {
        return "{id=" + id + ", name='" + name + "'}";
    }
}
// 降序
public class DescSortor implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        return o2.getId() - o1.getId();
    }
}
// 升序
public class AscSortor implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        return o1.getId() - o2.getId();
    }
}

通過(guò) Arrays.sort() 對(duì)數(shù)組進(jìn)行排序

public class Test1 {
    public static void main(String[] args) {
        Student[] students = {
                new Student(3, "張三"),
                new Student(1, "李四"),
                new Student(4, "王五"),
                new Student(2, "趙六")
        };
        toString(students, "排序前");        
        Arrays.sort(students, new AscSortor());
        toString(students, "升序后");        
        Arrays.sort(students, new DescSortor());
        toString(students, "降序后");
    }
    public static void toString(Student[] students, String desc){
        for (int i = 0; i < students.length; i++) {
            System.out.print(desc + ": " +students[i].toString() + ", ");
        }
        System.out.println();
    }
}
排序前: {id=3, name='張三'}, 排序前: {id=1, name='李四'}, 排序前: {id=4, name='王五'}, 排序前: {id=2, name='趙六'}, 
升序后: {id=1, name='李四'}, 升序后: {id=2, name='趙六'}, 升序后: {id=3, name='張三'}, 升序后: {id=4, name='王五'}, 
降序后: {id=4, name='王五'}, 降序后: {id=3, name='張三'}, 降序后: {id=2, name='趙六'}, 降序后: {id=1, name='李四'}, 

通過(guò) Collections.sort() 對(duì)集合List進(jìn)行排序

public class Test2 {
    public static void main(String[] args) {
        List<Student> students = Arrays.asList(
                new Student(3, "張三"),
                new Student(1, "李四"),
                new Student(4, "王五"),
                new Student(2, "趙六")
        );
        toString(students, "排序前");       
        Collections.sort(students, new AscSortor());
        toString(students, "升序后");
        Collections.sort(students, new DescSortor());
        toString(students, "降序后");
    }
    public static void toString(List<Student> students, String desc) {
        for (Student student : students) {
            System.out.print(desc + ": " + student.toString() + ", ");
        }
        System.out.println();
    }
}
排序前: {id=3, name='張三'}, 排序前: {id=1, name='李四'}, 排序前: {id=4, name='王五'}, 排序前: {id=2, name='趙六'}, 
升序后: {id=1, name='李四'}, 升序后: {id=2, name='趙六'}, 升序后: {id=3, name='張三'}, 升序后: {id=4, name='王五'}, 
降序后: {id=4, name='王五'}, 降序后: {id=3, name='張三'}, 降序后: {id=2, name='趙六'}, 降序后: {id=1, name='李四'}, 

我們向 Collections.sort() 和 Arrays.sort() 分別傳入不同的比較器即可實(shí)現(xiàn)不同的排序效果(升序或降序)

這里 Comparator 接口充當(dāng)了抽象策略角色,兩個(gè)比較器 DescSortor 和 AscSortor 則充當(dāng)了具體策略角色,Collections 和 Arrays 則是環(huán)境角色

Spring Resource 中的策略模式

Spring 把所有能記錄信息的載體,如各種類(lèi)型的文件、二進(jìn)制流等都稱(chēng)為資源,譬如最常用的Spring配置文件。

在 Sun 所提供的標(biāo)準(zhǔn) API 里,資源訪(fǎng)問(wèn)通常由 java.NET.URL 和文件 IO 來(lái)完成,尤其是當(dāng)我們需要訪(fǎng)問(wèn)來(lái)自網(wǎng)絡(luò)的資源時(shí),通常會(huì)選擇 URL 類(lèi)。

URL 類(lèi)可以處理一些常規(guī)的資源訪(fǎng)問(wèn)問(wèn)題,但依然不能很好地滿(mǎn)足所有底層資源訪(fǎng)問(wèn)的需要,比如,暫時(shí)還無(wú)法從類(lèi)加載路徑、或相對(duì)于 ServletContext 的路徑來(lái)訪(fǎng)問(wèn)資源,雖然 Java 允許使用特定的 URL 前綴注冊(cè)新的處理類(lèi)(例如已有的 http: 前綴的處理類(lèi)),但是這樣做通常比較復(fù)雜,而且 URL 接口還缺少一些有用的功能,比如檢查所指向的資源是否存在等。

Spring 改進(jìn)了 Java 資源訪(fǎng)問(wèn)的策略,Spring 為資源訪(fǎng)問(wèn)提供了一個(gè) Resource 接口,該接口提供了更強(qiáng)的資源訪(fǎng)問(wèn)能力,Spring 框架本身大量使用了 Resource 接口來(lái)訪(fǎng)問(wèn)底層資源。

public interface Resource extends InputStreamSource {
    boolean exists();    // 返回 Resource 所指向的資源是否存在
    boolean isReadable();   // 資源內(nèi)容是否可讀
    boolean isOpen();   // 返回資源文件是否打開(kāi)
    URL getURL() throws IOException;
    URI getURI() throws IOException;
    File getFile() throws IOException;  // 返回資源對(duì)應(yīng)的 File 對(duì)象
    long contentLength() throws IOException;
    long lastModified() throws IOException;
    Resource createRelative(String var1) throws IOException;
    String getFilename();
    String getDescription();    // 返回資源的描述信息
}

Resource 接口是 Spring 資源訪(fǎng)問(wèn)策略的抽象,它本身并不提供任何資源訪(fǎng)問(wèn)實(shí)現(xiàn),具體的資源訪(fǎng)問(wèn)由該接口的實(shí)現(xiàn)類(lèi)完成——每個(gè)實(shí)現(xiàn)類(lèi)代表一種資源訪(fǎng)問(wèn)策略。

Spring 為 Resource 接口提供的部分實(shí)現(xiàn)類(lèi)如下:

1.lResource:訪(fǎng)問(wèn)網(wǎng)絡(luò)資源的實(shí)現(xiàn)類(lèi)。

2.assPathResource:訪(fǎng)問(wèn)類(lèi)加載路徑里資源的實(shí)現(xiàn)類(lèi)。

3.leSystemResource:訪(fǎng)問(wèn)文件系統(tǒng)里資源的實(shí)現(xiàn)類(lèi)。

4.rvletContextResource:訪(fǎng)問(wèn)相對(duì)于ServletContext 路徑里的資源的實(shí)現(xiàn)類(lèi):

5.putStreamResource:訪(fǎng)問(wèn)輸入流資源的實(shí)現(xiàn)類(lèi)。

6.teArrayResource:訪(fǎng)問(wèn)字節(jié)數(shù)組資源的實(shí)現(xiàn)類(lèi)。

7.itableResource:寫(xiě)資源文件

類(lèi)圖如下

在這里插入圖片描述

AbstractResource 資源抽象類(lèi)實(shí)現(xiàn)了 Resource 接口,為子類(lèi)通用的操作提供了具體實(shí)現(xiàn),非通用的操作留給子類(lèi)實(shí)現(xiàn),所以這里也應(yīng)用了模板方法模式。(只不過(guò)缺少了模板方法)

Resource 不僅可在 Spring 的項(xiàng)目中使用,也可直接作為資源訪(fǎng)問(wèn)的工具類(lèi)使用。意思是說(shuō):即使不使用 Spring 框架,也可以使用 Resource 作為工具類(lèi),用來(lái)代替 URL。

譬如我們可以使用 UrlResource 訪(fǎng)問(wèn)網(wǎng)絡(luò)資源。

也可以通過(guò)其它協(xié)議訪(fǎng)問(wèn)資源,file: 用于訪(fǎng)問(wèn)文件系統(tǒng);http: 用于通過(guò) HTTP 協(xié)議訪(fǎng)問(wèn)資源;ftp: 用于通過(guò) FTP 協(xié)議訪(fǎng)問(wèn)資源等

public class Test {
    public static void main(String[] args) throws IOException {
        UrlResource ur = new UrlResource("http://image.laijianfeng.org/hello.txt");
        System.out.println("文件名:" + ur.getFilename());
        System.out.println("網(wǎng)絡(luò)文件URL:" + ur.getURL());
        System.out.println("是否存在:" + ur.exists());
        System.out.println("是否可讀:" + ur.isReadable());
        System.out.println("文件長(zhǎng)度:" + ur.contentLength());

        System.out.println("\n--------文件內(nèi)容----------\n");
        byte[] bytes = new byte[47];
        ur.getInputStream().read(bytes);
        System.out.println(new String(bytes));
    }
}
文件名:hello.txt
網(wǎng)絡(luò)文件URL:http://image.laijianfeng.org/hello.txt
是否存在:true
是否可讀:true
文件長(zhǎng)度:47
--------文件內(nèi)容----------
hello world!
welcome to http://laijianfeng.org

Spring Bean 實(shí)例化中的策略模式

Spring實(shí)例化Bean有三種方式:構(gòu)造器實(shí)例化、靜態(tài)工廠(chǎng)實(shí)例化、實(shí)例工廠(chǎng)實(shí)例化

具體實(shí)例化Bean的過(guò)程中,Spring中角色分工很明確,創(chuàng)建對(duì)象的時(shí)候先通

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans     <bean id="person" class="com.demo.Person"></bean>
        <bean id="personWithParam" class="com.demo.Person">
        <constructor-arg name="name" value="小旋鋒"/>
    </bean>
        <bean id="personWirhParams" class="com.demo.Person">
            <constructor-arg name="name" value="小旋鋒"/>
            <constructor-arg name="age" value="22"/>
    </bean>
</beans>

過(guò) ConstructorResolver 找到對(duì)應(yīng)的實(shí)例化方法和參數(shù),再通過(guò)實(shí)例化策略 InstantiationStrategy 進(jìn)行實(shí)例化,根據(jù)創(chuàng)建對(duì)象的三個(gè)分支( 工廠(chǎng)方法、有參構(gòu)造方法、無(wú)參構(gòu)造方法 ), InstantiationStrategy 提供了三個(gè)接口方法:

public interface InstantiationStrategy {
	// 默認(rèn)構(gòu)造方法
	Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) throws BeansException;
	// 指定構(gòu)造方法
	Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner, Constructor<?> ctor,
			Object[] args) throws BeansException;
	// 指定工廠(chǎng)方法
	Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner, Object factoryBean,
			Method factoryMethod, Object[] args) throws BeansException;
}

InstantiationStrategy 為實(shí)例化策略接口,扮演抽象策略角色,有兩種具體策略類(lèi),分別為

SimpleInstantiationStrategy CglibSubclassingInstantiationStrategy

在這里插入圖片描述

leInstantiationStrategy 中對(duì)這三個(gè)方法做了簡(jiǎn)單實(shí)現(xiàn),如果工廠(chǎng)方法實(shí)例化直接用反射創(chuàng)建對(duì)象,如果是構(gòu)造方法實(shí)例化的則判斷是否有 MethodOverrides,如果有無(wú) MethodOverrides 也是直接用反射,如果有 MethodOverrides 就需要用 cglib 實(shí)例化對(duì)象,SimpleInstantiationStrategy 把通過(guò) cglib 實(shí)例化的任務(wù)交給了它的子類(lèi)ibSubclassingInstantiationStrategy。

總結(jié)

1.略類(lèi)之間可以自由切換,由于策略類(lèi)實(shí)現(xiàn)自同一個(gè)抽象,所以他們之間可以自由切換。

2.于擴(kuò)展,增加一個(gè)新的策略對(duì)策略模式來(lái)說(shuō)非常容易,基本上可以在不改變?cè)写a的基礎(chǔ)上進(jìn)行擴(kuò)展。

3.使用多重條件,如果不使用策略模式,對(duì)于所有的算法,必須使用條件語(yǔ)句進(jìn)行連接,通過(guò)條件判斷來(lái)決定使用哪一種算法,在上一篇文章中我們已經(jīng)提到,使用多重條件判斷是非常不容易維護(hù)的。

以上就是java策略模式的詳細(xì)內(nèi)內(nèi)容。也請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java測(cè)試框架Mockito的簡(jiǎn)明教程

    Java測(cè)試框架Mockito的簡(jiǎn)明教程

    這篇文章主要介紹了Java測(cè)試框架Mockito的簡(jiǎn)明教程,Mock 測(cè)試是單元測(cè)試的重要方法之一。本文介紹了基于 Java 語(yǔ)言的 Mock 測(cè)試框架 – Mockito 的使用。,需要的朋友可以參考下
    2019-06-06
  • SpringAOP實(shí)現(xiàn)日志收集管理功能(步驟詳解)

    SpringAOP實(shí)現(xiàn)日志收集管理功能(步驟詳解)

    這篇文章主要介紹了SpringAOP實(shí)現(xiàn)日志收集管理功能,本文分步驟通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • JavaWeb實(shí)現(xiàn)壓縮多個(gè)文件并下載實(shí)例詳解

    JavaWeb實(shí)現(xiàn)壓縮多個(gè)文件并下載實(shí)例詳解

    本文通過(guò)實(shí)例代碼給大家講解了javaweb實(shí)現(xiàn)壓縮多個(gè)文件并下載功能,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧
    2017-07-07
  • MyBatis3源碼解析之如何獲取數(shù)據(jù)源詳解

    MyBatis3源碼解析之如何獲取數(shù)據(jù)源詳解

    用myBatis3與spring整合的時(shí)候,我們可以通過(guò)多種方式獲取數(shù)據(jù)源,下面這篇文章主要給大家介紹了關(guān)于MyBatis3源碼解析之如何獲取數(shù)據(jù)源的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • Java實(shí)現(xiàn)一個(gè)簡(jiǎn)單計(jì)算器

    Java實(shí)現(xiàn)一個(gè)簡(jiǎn)單計(jì)算器

    這篇文章主要介紹了Java實(shí)現(xiàn)一個(gè)簡(jiǎn)單計(jì)算器,文章我圍繞實(shí)現(xiàn)簡(jiǎn)單計(jì)算器的相關(guān)代碼展現(xiàn)全文,具有一定的參考價(jià)值,需要的小伙伴可以參考一下,
    2022-01-01
  • 詳解Java讀取Jar中資源文件及示例代碼

    詳解Java讀取Jar中資源文件及示例代碼

    這篇文章主要介紹了詳解Java讀取Jar中資源文件及實(shí)現(xiàn)代碼的相關(guān)資料,在開(kāi)發(fā)java項(xiàng)目的時(shí)候,經(jīng)常會(huì)用到j(luò)ar包,這里就說(shuō)下如何讀取,需要的朋友可以參考下
    2017-07-07
  • Spring實(shí)戰(zhàn)之Bean的后處理器操作示例

    Spring實(shí)戰(zhàn)之Bean的后處理器操作示例

    這篇文章主要介紹了Spring實(shí)戰(zhàn)之Bean的后處理器操作,結(jié)合實(shí)例形式詳細(xì)分析了Bean的后處理器相關(guān)配置、操作方法及使用注意事項(xiàng),需要的朋友可以參考下
    2019-12-12
  • java用arraycopy實(shí)現(xiàn)多擊事件

    java用arraycopy實(shí)現(xiàn)多擊事件

    這篇文章主要介紹了java用arraycopy實(shí)現(xiàn)多擊事件的多種方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • SpringBoot詳細(xì)講解視圖整合引擎thymeleaf

    SpringBoot詳細(xì)講解視圖整合引擎thymeleaf

    這篇文章主要分享了Spring Boot整合使用Thymeleaf,Thymeleaf是新一代的Java模板引擎,類(lèi)似于Velocity、FreeMarker等傳統(tǒng)引擎,關(guān)于其更多相關(guān)內(nèi)容,需要的小伙伴可以參考一下
    2022-06-06
  • SpringBoot中Bean拷貝及工具類(lèi)封裝的實(shí)現(xiàn)

    SpringBoot中Bean拷貝及工具類(lèi)封裝的實(shí)現(xiàn)

    本文主要介紹了SpringBoot中Bean拷貝及工具類(lèi)封裝的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05

最新評(píng)論