成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

面試官:JDK中都用了哪些設計模式?

開發 前端
單例模式保證一個類只有一個實例,并提供一個全局訪問點。工廠模式提供了一種將對象創建的過程封裝在一個單獨的類中的方法,這個類就是工廠類。

設計模式是前輩們經過實踐驗證總結的解決方案,幫助我們構建出更具可維護性、可擴展性和可讀性的代碼。當然,在面試的過程中,也會或多或少的被問到。那么今天,我們就來看一道設計模式中的常見面試問題:JDK 中都用了哪些設計模式?

我按照大家比較熟悉且好理解的方式,把  JDK 中使用的設計模式總結了一下,如下圖所示:

那么,接下來我們一個個來看。

1.單例模式

單例模式保證一個類只有一個實例,并提供一個全局訪問點。

Runtime 類使用了單例模式,如下源碼可知:

public class Runtime {
    private static final Runtime currentRuntime = new Runtime();
    private static Version version;
    /**
     * Returns the runtime object associated with the current Java application.
     * Most of the methods of class {@code Runtime} are instance
     * methods and must be invoked with respect to the current runtime object.
     *
     * @return  the {@code Runtime} object associated with the current
     *          Java application.
     */
    public static Runtime getRuntime() {
        return currentRuntime;
    }
    /** Don't let anyone else instantiate this class */
    private Runtime() {}
    // 省略其他源碼
}

從以上源碼可以看出,Runtime 使用的餓漢方式實現了單例模式。

2.工廠模式

工廠模式提供了一種將對象創建的過程封裝在一個單獨的類中的方法,這個類就是工廠類。

線程池中的所有線程的創建都是通過工廠創建的,使用的就是工廠模式,具體源碼如下:

3.代理模式

代理模式是一種為其他對象提供一種代理以控制對這個對象的訪問的設計模式。代理對象在客戶端和目標對象之間起到中介的作用,并且可以去掉客戶不能看到的內容和服務或者添加客戶需要的額外服務。

JDK 內置了動態代理的功能,動態代理是代理模式的一種實現,它是由 java.lang.reflect.Proxy 類提供的。

Proxy 使用 Demo 如下:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

// 1.接口
interface Subject {
    void doSomething();
}

// 2.目標類(被代理類)
class RealSubject implements Subject {
    @Override
    public void doSomething() {
        System.out.println("RealSubject is doing something");
    }
}

// 3.動態代理類
class DynamicProxyHandler implements InvocationHandler {
    private Object target;
    DynamicProxyHandler(Object target) {
        this.target = target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Before calling method");
        Object result = method.invoke(target, args);
        System.out.println("After calling method");
        return result;
    }
}

public class JDKProxyDemo {
    public static void main(String[] args) {
        // 創建真實對象
        Subject realSubject = new RealSubject();
        // 創建動態代理處理器
        InvocationHandler handler = new DynamicProxyHandler(realSubject);
        // 創建代理對象
        Subject proxySubject = (Subject) Proxy.newProxyInstance(
            realSubject.getClass().getClassLoader(),
            realSubject.getClass().getInterfaces(),
            handler);
        // 調用代理對象的方法
        proxySubject.doSomething();
    }
}

4.迭代器模式

迭代器模式能夠提供一種簡單的方法來遍歷容器中的每個元素。通過迭代器,用戶可以輕松地訪問容器中所有的元素,簡化了編程過程。

Iterable 就是標準的迭代器模式,Collection 就是 Iterator 的子類,它的使用代碼如下:

import java.util.ArrayList;
import java.util.Iterator;

public class IteratorDemo {
    public static void main(String[] args) {
        // 創建一個 ArrayList 并添加元素
        ArrayList<String> list = new ArrayList<>();
        list.add("Apple");
        list.add("Banana");
        list.add("Orange");

        // 獲取迭代器
        Iterator<String> iterator = list.iterator();

        // 使用迭代器遍歷集合
        while (iterator.hasNext()) {
            String fruit = iterator.next();
            System.out.println("Fruit: " + fruit);
        }
    }
}

5.模版方法模式

模板方法模式(Template Method Pattern)定義了一個操作中的算法骨架,將一些步驟延遲到子類中實現。模板方法使得子類可以在不改變算法結構的情況下,重新定義算法中的某些步驟。

在 AQS(AbstractQueuedSynchronizer) 中,acquire 方法和 release 方法使用了模板方法模式。

這些方法之所以被認為是模板方法模式,是因為它們定義了一個操作的基本框架或流程,但其中的某些關鍵步驟被設計為抽象方法,留給子類去具體實現。

以 acquire 方法為例,它大致的流程包括嘗試獲取資源、如果獲取失敗則將當前線程加入等待隊列、阻塞線程等步驟。但是具體如何判斷能否獲取資源(通過調用 tryAcquire 方法),以及在獲取失敗后的一些處理細節,是由子類去實現的,具體源碼如下:

protected boolean tryAcquire(int arg) {
throw new UnsupportedOperationException();
}

例如,基于 AQS 實現的 ReentrantLock 中就重寫了 tryAcquire 方法,實現源碼如下:

6.裝飾器模式

裝飾器模式是在不修改原對象的基礎上,動態地給對象添加額外功能的設計模式。

BufferedInputStream 就是典型裝飾器模式,當使用普通的 InputStream 讀取數據時,每次可能都會進行實際的 I/O 操作,而 BufferedInputStream 會先將一部分數據讀入緩沖區,后續的讀取操作可以直接從緩沖區獲取,減少了實際的 I/O 次數。

例如以下代碼:

InputStream inputStream = new FileInputStream("file.txt");
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);

BufferedInputStream 并沒有改變 FileInputStream 的基本結構和接口,只是為其添加了緩沖的特性

7.策略模式

策略模式定義了一系列可互換的算法,并將每一個算法封裝起來,使它們可以互相替換。

Comparator 是策略模式的一個典型例子,Comparator 接口定義了一個比較兩個對象的方法 compare(T o1, T o2)。這個接口允許用戶定義不同的比較策略,使得我們可以靈活地改變排序或比較邏輯。

例如以下示例代碼:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class StrategyPatternExample {
    static class Person {
        private String name;
        private int age;
        // 忽略 Setter、Getter 等方法
    }
    // 按照年齡升序排列
    static class AgeComparator implements Comparator<Person> {
        @Override
        public int compare(Person p1, Person p2) {
            return Integer.compare(p1.getAge(), p2.getAge());
        }
    }
    // 按照姓名降序排列
    static class NameDescendingComparator implements Comparator<Person> {
        @Override
        public int compare(Person p1, Person p2) {
            return p2.getName().compareTo(p1.getName());
        }
    }
    public static void main(String[] args) {
        ArrayList<Person> people = new ArrayList<>();
        people.add(new Person("Alice", 30));
        people.add(new Person("Bob", 25));
        people.add(new Person("Charlie", 35));

        // 使用年齡升序的策略
        Collections.sort(people, new AgeComparator());

        // 使用姓名降序的策略
        Collections.sort(people, new NameDescendingComparator());
    }
}

8.建造者模式

建造者模式是一種創建型設計模式,用于通過一系列的步驟來創建復雜的對象。它將對象的構建過程與其表示相分離,使得同樣的構建過程可以創建不同的表示。

在 JDK 中,使用建造者模式的常見例子是 StringBuilder 和 StringBuffer 類。

雖然這兩個類本身不是傳統意義上的建造者模式實現(因為建造者模式通常用于構建不同的表示或者不同部分的同一個對象),它們提供了一種鏈式調用的方式來構建和修改字符串,這在某種程度上體現了建造者模式的思想。

例如以下代碼:

public class StringBuilderDemo {  
    public static void main(String[] args) {  
        // 使用 StringBuilder 構建和修改字符串  
        StringBuilder builder = new StringBuilder();  
        builder.append("Hello")  
        .append(", ")  
        .append("world")  
        .append("!")  
        .insert(7, "beautiful ")  
        .deleteCharAt(13);  

        // 輸出構建和修改后的字符串  
        System.out.println(builder.toString());  
        // 輸出: Hello, beautiful world!  
    }  
}

StringBuilder 通過鏈式調用 append、insert 和 deleteCharAt 方法來逐步構建和修改字符串。這種方式使得構建和修改字符串的過程更加流暢和易于閱讀。

責任編輯:姜華 來源: 磊哥和Java
相關推薦

2019-05-29 17:20:07

Spring設計模式Java

2020-03-18 09:43:37

開發技能代碼

2024-05-30 07:37:30

2023-07-11 08:50:34

2022-11-23 07:41:52

JDKStream關鍵字

2021-10-29 09:40:21

設計模式軟件

2023-02-20 08:08:48

限流算法計數器算法令牌桶算法

2021-08-02 17:21:08

設計模式訂閱

2025-03-26 01:25:00

MySQL優化事務

2024-03-07 17:21:12

HotSpotJVMHot Code

2024-02-26 14:07:18

2021-05-10 08:01:12

BeanFactoryFactoryBean容器

2023-07-05 08:17:38

JDK動態代理接口

2022-04-29 08:17:38

RPC遠程代理代理模式

2024-04-19 00:00:00

計數器算法限流算法

2024-03-12 14:36:44

微服務HTTPRPC

2022-05-23 08:43:02

BigIntJavaScript內置對象

2024-08-19 09:13:02

2015-01-05 09:53:05

Java

2020-07-02 07:45:46

運營商2G3G
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 中文字幕11页 | 亚洲aⅴ| 亚洲精品久久久蜜桃 | 91新视频 | 久久久妇女国产精品影视 | 久久精品国产久精国产 | 国产亚洲欧美日韩精品一区二区三区 | 久久国产精品一区二区三区 | 黄色在线观看网站 | 成人在线免费电影 | a级毛片毛片免费观看久潮喷 | 曰韩一二三区 | 欧洲一区二区在线 | 97视频人人澡人人爽 | 久久69精品久久久久久久电影好 | 亚洲入口 | 国产精品日韩一区二区 | 日本久久久久久久久 | 国产日韩久久 | 国产日韩久久 | 9999国产精品欧美久久久久久 | 操网站| 黄色av观看 | 欧美视频在线播放 | 日韩二区 | 日韩一区二区在线免费观看 | 久久成人免费 | 日韩在线播放第一页 | 91中文字幕在线观看 | 中文字幕在线一区二区三区 | 91高清免费观看 | 一区二区三区日韩精品 | 午夜影院 | 亚洲国产精品久久久久久 | 日韩一区二区三区在线视频 | 欧美日韩在线免费 | 综合色播 | 久久精品国产一区二区电影 | 亚洲精品中文字幕 | 一级网站| 免费看大片bbbb欧美 |