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

聊一聊適配器模式

這篇具有很好參考價(jià)值的文章主要介紹了聊一聊適配器模式。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

接口不能用?行,我?guī)湍氵m配

一、概述

適配器模式(Adapter),是23種設(shè)計(jì)模式中的結(jié)構(gòu)型模式之一;它就像我們電腦上接口不夠時(shí),需要用到的拓展塢,起到轉(zhuǎn)接的作用。它可以將新的功能和原先的功能連接起來(lái),使由于需求變動(dòng)導(dǎo)致不能用的功能,重新利用起來(lái)。

聊一聊適配器模式

上圖的Mac上,只有兩個(gè)typec接口,當(dāng)我們需要用到USB、網(wǎng)線、HDMI等接口時(shí),這就不夠用了,所以我們需要一個(gè)拓展塢來(lái)增加電腦的接口

聊一聊適配器模式

言歸正傳,下面來(lái)了解下適配器模式中的角色:請(qǐng)求者(client)、目標(biāo)角色(Target)、源角色(Adaptee)、適配器角色(Adapter),這四個(gè)角色是保證這個(gè)設(shè)計(jì)模式運(yùn)行的關(guān)鍵。

  • client:需要使用適配器的對(duì)象,不需要關(guān)心適配器內(nèi)部的實(shí)現(xiàn),只對(duì)接目標(biāo)角色。
  • Target:目標(biāo)角色,和client直接對(duì)接,定義了client需要用到的功能。
  • Adaptee:需要被進(jìn)行適配的對(duì)象。
  • Adapter:適配器,負(fù)責(zé)將源對(duì)象轉(zhuǎn)化,給client做適配。

二、入門(mén)案例

適配器模式也分兩種:對(duì)象適配器、類適配器。其實(shí)兩種方式的區(qū)別在于,適配器類中的實(shí)現(xiàn),類適配器是通過(guò)繼承源對(duì)象的類,對(duì)象適配器是引用源對(duì)象的類。

當(dāng)然兩種方式各有優(yōu)缺點(diǎn),咱分別來(lái)說(shuō)下;

類適配器:由于采用繼承模式,在適配器中可以重寫(xiě)Adaptee原有的方法,使得適配器可以更加靈活;但是有局限性,Java是單繼承模式,所以適配器類只能繼承Adaptee,不能在額外繼承其他類,也導(dǎo)致Target類只能是接口。

對(duì)象適配器:這個(gè)模式規(guī)避了單繼承的劣勢(shì),將Adaptee類用引用的方式傳遞給Adapter,這樣可以傳遞的是Adaptee對(duì)象本身及其子類對(duì)象,相比類適配器更加的開(kāi)放;但是也正是因?yàn)檫@種開(kāi)放性,導(dǎo)致需要自己重新定義Adaptee,增加額外的操作。

類適配器UML圖

聊一聊適配器模式

對(duì)象適配器UML圖

聊一聊適配器模式

下面,是結(jié)合上面電腦的場(chǎng)景,寫(xiě)的一個(gè)入門(mén)案例,分別是四個(gè)類:Client、Adaptee、Adapter、Target,代表了適配器模式中的四種角色。

/**
 * @author 往事如風(fēng)
 * @version 1.0
 * @date 2023/5/9 15:54
 * @description:源角色
 */
public class Adaptee {
    /**
     * 需要被適配的適配的功能
     * 以Mac筆記本的typec接口舉例
     */
    public void typeC() {
        System.out.println("我只是一個(gè)typeC接口");
    }
}
/**
 * @author 往事如風(fēng)
 * @version 1.0
 * @date 2023/5/9 15:57
 * @description:目標(biāo)接口
 */
public interface Target {

    /**
     * 定義一個(gè)轉(zhuǎn)接功能的入口
     */
    void socket();
}
/**
 * @author 往事如風(fēng)
 * @version 1.0
 * @date 2023/5/9 16:00
 * @description:適配器
 */
public class Adapter extends Adaptee implements Target {

    /**
     * 實(shí)現(xiàn)適配功能
     * 以Mac的拓展塢為例,拓展更多的接口:usb、typc、網(wǎng)線插口...
     */
    @Override
    public void socket() {
        typeC();
        System.out.println("新增usb插口。。。");
        System.out.println("新增網(wǎng)線插口。。。");
        System.out.println("新增typec插口。。。");
    }
}
/**
 * @author 往事如風(fēng)
 * @version 1.0
 * @date 2023/5/9 15:52
 * @description:請(qǐng)求者
 */
public class Client {

    public static void main(String[] args) {
        Target target = new Adapter();
        target.socket();
    }
}

這個(gè)案例比較簡(jiǎn)單,僅僅是一個(gè)入門(mén)的demo,也是類適配器模式的案例,采用繼承模式。在對(duì)象適配器模式中,區(qū)別就是Adapter這個(gè)適配器類,采用的是組合模式,下面是對(duì)象適配器模式中Adapter的代碼;

/**
 * @author 往事如風(fēng)
 * @version 1.0
 * @date 2023/5/9 16:00
 * @description:適配器
 */
public class Adapter implements Target {

    private Adaptee adaptee;

    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    /**
     * 實(shí)現(xiàn)適配功能
     * 以Mac的拓展塢為例,拓展更多的接口:usb、typc、網(wǎng)線插口...
     */
    @Override
    public void socket() {
        adaptee.typeC();
        System.out.println("新增usb插口。。。");
        System.out.println("新增網(wǎng)線插口。。。");
        System.out.println("新增typec插口。。。");
    }
}

三、運(yùn)用場(chǎng)景

其實(shí)適配器模式為何會(huì)存在,全靠“爛代碼”的襯托。在初期的設(shè)計(jì)上,一代目沒(méi)有考慮到后期的兼容性問(wèn)題,只顧自己一時(shí)爽,那后期接手的人就會(huì)感覺(jué)到頭疼,就會(huì)有“還不如重寫(xiě)這段代碼的想法”。但是這部分代碼往往都是經(jīng)過(guò)N代人的充分測(cè)試,穩(wěn)定性比較高,一時(shí)半會(huì)還不能對(duì)它下手。這時(shí)候我們的適配器模式就孕育而生,可以在不動(dòng)用老代碼的前提下,實(shí)現(xiàn)新邏輯,并且能做二次封裝。這種場(chǎng)景,我在之前的系統(tǒng)重構(gòu)中深有體會(huì),不說(shuō)了,都是淚。

當(dāng)然還存在一種情況,可以對(duì)不同的外部數(shù)據(jù)進(jìn)行統(tǒng)一輸出。例如,寫(xiě)一個(gè)獲取一些信息的接口,你對(duì)前端暴露的都是統(tǒng)一的返回字段,但是需要調(diào)用不同的外部api獲取不同的信息,不同的api返回給你的字段都是不同的,比如企業(yè)工商信息、用戶賬戶信息、用戶津貼信息等等。下面我對(duì)這種場(chǎng)景具體分析下;

首先,我定義一個(gè)接口,接收用戶id和數(shù)據(jù)類型兩個(gè)參數(shù),定義統(tǒng)一的輸出字段。

/**
 * @author 往事如風(fēng)
 * @version 1.0
 * @date 2023/5/10 11:03
 * @description
 */
@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
public class UserInfoController {

    private final UserInfoTargetService userInfoTargetService;

    @PostMapping("/info")
    public Result<DataInfoVo> queryInfo(@RequestParam Integer userId, @RequestParam String type) {
        return Result.success(userInfoTargetService.queryData(userId, type));
    }
}

定義統(tǒng)一的輸出的類DataInfoVo,這里定義的字段需要暴露給前端,具體業(yè)務(wù)意義跟前端商定。

/**
 * @author 往事如風(fēng)
 * @version 1.0
 * @date 2023/5/10 14:40
 * @description
 */
@Data
public class DataInfoVo {
    /**
     * 名稱
     */
    private String name;
    /**
     * 類型
     */
    private String type;
    /**
     * 預(yù)留字段:具體業(yè)務(wù)意義自行定義
     */
    private Object extInfo;
}

然后,定義Target接口(篇幅原因,這里不做展示),Adapter適配器類,這里采用的是對(duì)象適配器,由于單繼承的限制,對(duì)象適配器也是最常用的適配器模式。

/**
 * @author 往事如風(fēng)
 * @version 1.0
 * @date 2023/5/10 15:09
 * @description
 */
@Service
@RequiredArgsConstructor
public class UserInfoAdapter implements UserInfoTargetService {
    /**
     * 源數(shù)據(jù)類管理器
     */
    private final AdapteeManager adapteeManager;

    @Override
    public DataInfoVo queryData(Integer userId, String type) {
        // 根據(jù)類型,得到唯一的源數(shù)據(jù)類
        UserBaseAdaptee adaptee = adapteeManager.getAdaptee(type);
        if (Objects.nonNull(adaptee)) {
            Object data = adaptee.getData(userId, type);
            return adaptee.convert(data);
        }
        return null;
    }
}

這里定義了一個(gè)AdapteeManager類,表示管理Adaptee類,內(nèi)部維護(hù)一個(gè)map,用于存儲(chǔ)真實(shí)Adaptee類。

/**
 * @author 往事如風(fēng)
 * @version 1.0
 * @date 2023/5/10 15:37
 * @description
 */
public class AdapteeManager {

    private Map<String, UserBaseAdaptee> baseAdapteeMap;

    public void setBaseAdapteeMap(List<UserBaseAdaptee> adaptees) {
        baseAdapteeMap = adaptees.stream()
                .collect(Collectors.toMap(handler -> AnnotationUtils.findAnnotation(handler.getClass(), Adapter.class).type(), v -> v, (v1, v2) -> v1));
    }

    public UserBaseAdaptee getAdaptee(String type) {
        return baseAdapteeMap.get(type);
    }
}

最后,按照數(shù)據(jù)類型,定義了三個(gè)Adaptee類:AllowanceServiceAdaptee(津貼)、BusinessServiceAdaptee(企業(yè)工商)、UserAccountServiceAdaptee(用戶賬戶)。

/**
 * @author 往事如風(fēng)
 * @version 1.0
 * @date 2023/5/10 15:00
 * @description
 */
@Adapter(type = "JT")
public class AllowanceServiceAdaptee implements UserBaseAdaptee {

    @Override
    public Object getData(Integer userId, String type) {
        // 模擬調(diào)用外部api,查詢津貼信息
        AllowanceVo allowanceVo = new AllowanceVo();
        allowanceVo.setAllowanceType("管理津貼");
        allowanceVo.setAllowanceAccount("xwqeretry2345676");
        allowanceVo.setAmount(new BigDecimal(20000));
        return allowanceVo;
    }

    @Override
    public DataInfoVo convert(Object data) {
        AllowanceVo preConvert = (AllowanceVo) data;
        DataInfoVo dataInfoVo = new DataInfoVo();
        dataInfoVo.setName(preConvert.getAllowanceAccount());
        dataInfoVo.setType(preConvert.getAllowanceType());
        dataInfoVo.setExtInfo(preConvert.getAmount());
        return dataInfoVo;
    }
}
/**
 * @author 往事如風(fēng)
 * @version 1.0
 * @date 2023/5/10 15:00
 * @description
 */
@Adapter(type = "QY")
public class BusinessServiceAdaptee implements UserBaseAdaptee {

    @Override
    public Object getData(Integer userId, String type) {
        // 模擬調(diào)用外部api,查詢企業(yè)工商信息
        BusinessVo businessVo = new BusinessVo();
        businessVo.setBusName("xxx科技有限公司");
        businessVo.setBusCode("q24243Je54sdfd99");
        businessVo.setBusType("中大型企業(yè)");
        return businessVo;
    }

    @Override
    public DataInfoVo convert(Object data) {
        BusinessVo preConvert = (BusinessVo) data;
        DataInfoVo dataInfoVo = new DataInfoVo();
        dataInfoVo.setName(preConvert.getBusName());
        dataInfoVo.setType(preConvert.getBusType());
        dataInfoVo.setExtInfo(preConvert.getBusCode());
        return dataInfoVo;
    }
}
/**
 * @author 往事如風(fēng)
 * @version 1.0
 * @date 2023/5/10 15:00
 * @description
 */
@Adapter(type = "YH")
public class UserAccountServiceAdaptee implements UserBaseAdaptee {

    @Override
    public Object getData(Integer userId, String type) {
        // 模擬調(diào)用外部api,查詢企業(yè)工商信息
        UserAccountVo userAccountVo = new UserAccountVo();
        userAccountVo.setAccountNo("afsdfd1243567");
        userAccountVo.setAccountType("銀行卡");
        userAccountVo.setName("中國(guó)農(nóng)業(yè)銀行");
        return userAccountVo;
    }

    @Override
    public DataInfoVo convert(Object data) {
        UserAccountVo preConvert = (UserAccountVo) data;
        DataInfoVo dataInfoVo = new DataInfoVo();
        dataInfoVo.setName(preConvert.getName());
        dataInfoVo.setType(preConvert.getAccountType());
        dataInfoVo.setExtInfo(preConvert.getAccountNo());
        return dataInfoVo;
    }
}

這三個(gè)類都實(shí)現(xiàn)一個(gè)接口UserBaseAdaptee,該接口定義了統(tǒng)一的規(guī)范

/**
 * @author 往事如風(fēng)
 * @version 1.0
 * @date 2023/5/10 15:03
 * @description
 */

public interface UserBaseAdaptee {
    /**
     * 獲取數(shù)據(jù)
     * @param userId
     * @param type
     * @return
     */
    Object getData(Integer userId, String type);

    /**
     * 數(shù)據(jù)轉(zhuǎn)化為統(tǒng)一的實(shí)體
     * @param data
     * @return
     */
    DataInfoVo convert(Object data);
}

這些類中,其實(shí)重點(diǎn)看下UserInfoAdapter適配器類,這里做的操作是通過(guò)源數(shù)據(jù)類,拿到外部返回的數(shù)據(jù),最后將不同的數(shù)據(jù)轉(zhuǎn)化為統(tǒng)一的字段,返回出去。

這里我沒(méi)有按照固定的模式,稍加了改變。將適配器類中引用源數(shù)據(jù)類的方式,改成將源數(shù)據(jù)類加入map中暫存,最后通過(guò)前端傳輸?shù)膖ype字段來(lái)獲取源數(shù)據(jù)類,這也是對(duì)象適配器比較靈活的一種體現(xiàn)。

四、源碼中的運(yùn)用

在JDK的源碼中,JUC下有個(gè)類FutureTask,其中它的一段構(gòu)造方法如下:

public class FutureTask<V> implements RunnableFuture<V> {
    public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
    }
    
	public FutureTask(Runnable runnable, V result) {
        this.callable = Executors.callable(runnable, result);
        this.state = NEW;       // ensure visibility of callable
    }
}

其中一個(gè)構(gòu)造函數(shù)中,callable是通過(guò)Executors類的方法進(jìn)行適配的,通過(guò)一個(gè)RunnableAdapter的適配器類,進(jìn)行包裝并返回

public static <T> Callable<T> callable(Runnable task, T result) {
        if (task == null)
            throw new NullPointerException();
        return new RunnableAdapter<T>(task, result);
    }
static final class RunnableAdapter<T> implements Callable<T> {
        final Runnable task;
        final T result;
        RunnableAdapter(Runnable task, T result) {
            this.task = task;
            this.result = result;
        }
        public T call() {
            task.run();
            return result;
        }
    }

這樣的話,無(wú)論傳入Runnable還是Callable都可以適配任務(wù),雖然看著是調(diào)用了Callable的call方法,實(shí)際內(nèi)部是調(diào)用了Runnable的run方法,并且將傳入的返回?cái)?shù)據(jù)返回給外部使用。

五、總結(jié)

適配器模式其實(shí)是一個(gè)比較好理解的設(shè)計(jì)模式,但是對(duì)于大多數(shù)初學(xué)者而言,就會(huì)很容易看一遍之后立馬忘,這是缺少實(shí)際運(yùn)用造成的。其實(shí)編程主要考察的還是我們的一種思維模式,就像這個(gè)適配器模式,理解它的運(yùn)用場(chǎng)景最重要。如果給你一個(gè)業(yè)務(wù)場(chǎng)景,你能在腦海中有大致的設(shè)計(jì)思路或者解決方案,那你就已經(jīng)掌握精髓了。至于具體的落地,有些細(xì)節(jié)忘記也是在所難免,翻翻資料就會(huì)立馬回到腦海中。

最后,每次遇到問(wèn)題,用心總結(jié),你會(huì)離成功更近一步。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-445445.html

到了這里,關(guān)于聊一聊適配器模式的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • .NET高級(jí)面試指南專題二十六【適配器模式介紹,用于將一個(gè)類的接口轉(zhuǎn)換成客戶端所期待的另一個(gè)接口】

    適配器模式是一種結(jié)構(gòu)型設(shè)計(jì)模式,用于將一個(gè)類的接口轉(zhuǎn)換成客戶端所期待的另一個(gè)接口,使得原本由于接口不兼容而不能在一起工作的類能夠協(xié)同工作。這種模式通常用于軟件系統(tǒng)的升級(jí)和重構(gòu)中,可以使得原有的代碼能夠與新的接口相兼容,同時(shí)不改變?cè)写a的情況

    2024年04月22日
    瀏覽(26)
  • 適配器模式:代理、適配器、橋接、裝飾,這四個(gè)模式有何區(qū)別?

    ????????關(guān)于適配器模式,今天我們主要學(xué)習(xí)它的兩種實(shí)現(xiàn)方式,類適配器和對(duì)象適配器,以及5種常見(jiàn)的應(yīng)用場(chǎng)景。同時(shí),我還會(huì)通過(guò)剖析slf4j日志框架,來(lái)給你展示這個(gè)模式在真實(shí)項(xiàng)目中的應(yīng)用。除此之外,在文章的最后,我還對(duì)代理、橋接、裝飾器、適配器,這4種代

    2024年02月13日
    瀏覽(19)
  • 設(shè)計(jì)模式--適配器模式

    設(shè)計(jì)模式--適配器模式

    目錄 基本介紹 工作原理 類適配模式 介紹 應(yīng)用實(shí)例介紹 類適配器模式注意事項(xiàng)和細(xì)節(jié) 對(duì)象適配模式 介紹 對(duì)象適配器模式注意事項(xiàng)和細(xì)節(jié) 接口適配器模式 介紹 適配器模式的注意事項(xiàng)和細(xì)節(jié) ?(1) 適配器模式(Adapter Pattern) 將某個(gè)類的接口轉(zhuǎn)換成客戶端期望的另一個(gè)接口表示

    2023年04月26日
    瀏覽(19)
  • 設(shè)計(jì)模式——適配器模式

    設(shè)計(jì)模式——適配器模式

    說(shuō)起適配器其實(shí)在我們的生活中是非常常見(jiàn)的,比如:學(xué)校的宿舍的電壓都比較低,而有的學(xué)生想使用大功率電器,宿舍的就會(huì)跳閘,然而如果你使用一個(gè)適配器(變壓器)就可以使用了(溫馨提示宿舍使用大功率電器不太安全,容易引起火災(zāi),希望大家謹(jǐn)慎使用)。 又比如

    2024年02月12日
    瀏覽(35)
  • 設(shè)計(jì)模式-適配器模式

    設(shè)計(jì)模式-適配器模式

    在我們生活中,插座輸出的電源都是220V的,而我們手機(jī)充電需要的電壓基本都是5V的。我們不能直接用220V的電壓來(lái)給手機(jī)充電,也不能說(shuō)專門(mén)有線路來(lái)提供5V的電壓。所以就有了充電器,充電器可以將220V的電壓轉(zhuǎn)為5V的電壓,這樣我們就方便太多了。 上面所說(shuō)的充電器其實(shí)就

    2024年02月08日
    瀏覽(34)
  • 【設(shè)計(jì)模式】適配器模式

    【設(shè)計(jì)模式】適配器模式

    適配器模式(Adapter Pattern)是作為兩個(gè)不兼容的接口之間的橋梁。這種類型的設(shè)計(jì)模式屬于結(jié)構(gòu)型模式,它結(jié)合了兩個(gè)獨(dú)立接口的功能。 這種模式涉及到一個(gè)單一的類,該類負(fù)責(zé)加入獨(dú)立的或不兼容的接口功能。舉個(gè)真實(shí)的例子,讀卡器是作為內(nèi)存卡和筆記本之間的適配器。

    2024年02月12日
    瀏覽(32)
  • 結(jié)構(gòu)型模式-適配器模式

    是作為兩個(gè)不兼容的接口之間的橋梁。這種類型的設(shè)計(jì)模式屬于結(jié)構(gòu)型模式,它結(jié)合了兩個(gè)獨(dú)立接口的功能。 意圖: 將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口。適配器模式使得原本由于接口不兼容而不能一起工作的那些類可以一起工作。 主要解決: 主要解決在軟件系

    2024年02月10日
    瀏覽(26)
  • 設(shè)計(jì)模式 06 適配器模式

    適配器模式(Adapter Pattern)屬于 結(jié)構(gòu)型 模式 結(jié)構(gòu)型 模式關(guān)注如何將現(xiàn)有的類或?qū)ο蠼M織在一起形成更加強(qiáng)大的結(jié)構(gòu)。 在生活中,我們經(jīng)常遇到這樣的一個(gè)問(wèn)題:輕薄筆記本通常只有 type-c 或者 usb-a 接口,沒(méi)有網(wǎng)口。但日常使用中是往往需要連接網(wǎng)口上網(wǎng)的,這時(shí)想到的第

    2024年02月11日
    瀏覽(18)
  • 設(shè)計(jì)模式四:適配器模式

    設(shè)計(jì)模式四:適配器模式

    1、適配器模式的理解 適配器模式可以理解為有兩個(gè)現(xiàn)成的類Adaptee和Target,它們兩個(gè)是不能動(dòng)的,要求必須使用B這個(gè)類來(lái)實(shí)現(xiàn)一個(gè)功能,但是A的內(nèi)容是能復(fù)用的,這個(gè)時(shí)候我們需要編寫(xiě)一個(gè)轉(zhuǎn)換器 適配器模式 Adaptee:被適配者,現(xiàn)有的接口或者類; Adapter:適配器類,適配器

    2024年02月22日
    瀏覽(24)
  • 設(shè)計(jì)模式-- 3.適配器模式

    設(shè)計(jì)模式-- 3.適配器模式

    將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口。使得原本由于接口不兼容而不能一起工作的那些類可以一起工作。 請(qǐng)求者(client):客戶端角色,需要使用適配器的對(duì)象,不需要關(guān)心適配器內(nèi)部的實(shí)現(xiàn),只對(duì)接目標(biāo)角色。 目標(biāo)角色(Target):目標(biāo)角色,和client直接對(duì)接,定義

    2024年01月18日
    瀏覽(26)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包