91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

折騰Java設計模式之模板方法模式

發布時間:2020-06-24 12:27:17 來源:網絡 閱讀:402 作者:大萌小路 欄目:軟件技術

博客原文地址:折騰Java設計模式之模板方法模式

模板方法模式

Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.

翻譯過來就是,把算法的框架定義好,可以將某些步抽象出來放到子類去實現。模板方法允許子類在不改變算法框架的情況下重新實現算法的某些步驟。

模板方法模式UML圖

UML圖

折騰Java設計模式之模板方法模式cdn.xitu.io/2019/4/1/169d676374d89d71?w=500&h=240&f=jpeg&s=12703">

抽象類AbstractClass定義了算法框架templateMethod()方法,其中有2個方法primitve1()primitve2()被抽象出來,子類SubClass1繼承了抽象類AbstractClass,從而實現了primitve1()primitve2()

模板方法模式角色

抽象類(AbstractClass): 定義了算法核心框架,同時把局部的算法行為封裝成步驟,讓子類去實現。

子類(SubClass): 繼承了抽象類,實現抽象類中的抽象方法,具體實現了算法部分邏輯。

模板方法模式源碼示例

源碼地址:Template-method

抽象方法

先定義抽象類,抽象類AbstractProcessor中核心算法handle方法中大體分3部,第一先校驗參數具體怎么校驗放在子類中實現,第二獲取結果也放在子類實現,第三獲取結果后的操作也放在子類實現。

@Slf4j
public abstract class AbstractProcessor<P extends Request, R extends Response> {

    /**
     * 邏輯處理
     *
     * @param request
     * @return
     */
    public R handle(P request) {
        // 1.校驗參數
        log.info("開始處理, 請求參數={}", request);
        validRequest(request);

        // 2.獲取結果
        R response = getResponse(request);
        log.info("獲取結果, 響應結果={}", response);

        // 3.結果之后的處理
        afterHandle(response);
        return response;
    }

    /**
     * 結果之后的處理 可以更新其他業務或者處理緩存
     *
     * @param response
     */
    protected abstract void afterHandle(R response);

    /**
     * 校驗請求參數
     *
     * @param request
     */
    protected void validRequest(P request) {
        if (Objects.isNull(request.getToken())) {
            throw new RuntimeException("token不能為空");
        }
        if (Objects.isNull(request.getVersion())) {
            throw new RuntimeException("version不能為空");
        }

        validRequestParam(request);
    }

    /**
     * 校驗請求真正的參數
     * @param request
     */
    protected abstract void validRequestParam(P request);

    /**
     * 獲取到結果
     * @param request
     * @return
     */
    protected abstract R getResponse(P request);
}

基本請求

@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class Request {

     private String version;

     private String token;
}

基本響應

@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class Response {

     private String msg;

     private int code;

     private boolean success;

}

子類實現

第一個子類實現

@Slf4j
public class OneProcessor extends AbstractProcessor<OneRequest, OneResponse> {

    public OneProcessor() {
        ProcessorFactory.putProcess("two", this);
    }

    @Override
    protected void afterHandle(OneResponse response) {
        log.info("處理One結果: {}", response.getOne());
    }

    @Override
    protected void validRequestParam(OneRequest request) {
        log.info("校驗one參數...省略......");
    }

    @Override
    protected OneResponse getResponse(OneRequest request) {
        String name = request.getName();
                return OneResponse.builder()
                .one(name + "one")
                .success(true)
                .code(0)
                .msg("成功")
                .build();
    }
}

第一個子類的請求

@Data
@ToString(callSuper = true)
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class OneRequest extends Request {

    private String name;

    @Builder.Default
    private int a = 0;

}

第一個子類的響應

@Data
@ToString(callSuper = true)
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class OneResponse extends Response {

    private String one;

}

第二個子類實現

@Slf4j
public class TwoProcessor extends AbstractProcessor<TwoRequest, TwoResponse> {

    public TwoProcessor() {
        ProcessorFactory.putProcess("two", this);
    }

    @Override
    protected void afterHandle(TwoResponse response) {
        log.info("處理結果TWO, {}", response);
    }

    @Override
    protected void validRequestParam(TwoRequest request) {
        log.info("校驗TWO參數...省略......");
    }

    @Override
    protected TwoResponse getResponse(TwoRequest request) {
        Long id = request.getId();
        return TwoResponse.builder()
                .two("id為"+id)
                .success(true)
                .code(0)
                .msg("成功")
                .build();
    }
}

第二個子類的請求

@Data
@ToString(callSuper = true)
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class TwoRequest extends Request {

    private Long id;
}

第二個子類的響應

@Data
@ToString(callSuper = true)
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class TwoResponse extends Response {

    private String two;
}

擴展為工廠

有的時候我們定義的子類在Spring容器的時候由Spring定義好后,我們其實可以借用工廠模式方法,在子類初始化的時候就把子類放置在ProcessorFactory中,后續只需要根據key從中拿取即可,實際項目中用這種方式還是比較多的。

public class ProcessorFactory {

    private static Map<String, AbstractProcessor> factories = new HashMap();

    public static void putProcess(String key, AbstractProcessor process) {
        factories.put(key, process);
    }

    public static AbstractProcessor selectProcess(String key) {
        return factories.get(key);
    }

}

執行程序

@Slf4j
public class TemplateMethodApplication {

    public static void main(String[] args) {
        OneRequest oneRequest = OneRequest.builder()
                .version("2312312")
                .token("23423")
                .name("張三")
                .build();
        new OneProcessor().handle(oneRequest);

        log.info("--------------------------");

        TwoRequest twoRequest = TwoRequest.builder()
                .version("2312312")
                .token("23423")
                .id(23456L)
                .build();
        new TwoProcessor().handle(twoRequest);

    }
}

結果

折騰Java設計模式之模板方法模式

總體上來講,抽象類中定義了算法的框架,然后把部分算法步驟抽象出來供子類實現,有的時候有些方法只有個別子類會去實現,我們可以在抽象類中實現為空實現,在有需要的子類中我們可以覆蓋抽象類的實現,這樣避免了所有的子類都去實現,其實不關心的話都是空實現了。本示例用到了lombok@SuperBuilder特性,可能在下載完完整的代碼后會出現編譯錯誤,這是因為Lombok的插件暫時還不支持@SuperBuilder

模板方法模式總結

模板方法經常和其他模式混合使用,比如工廠、策略等等。其實在Spring中大量使用了模板方法模式,其實也不光在Spring中,像平時jdbcTemplate或者RedisTemplate,像這種帶有Template的。

優點 1、封裝不變部分,擴展可變部分。 2、提取公共代碼,便于維護。 3、行為由父類控制,子類實現。

缺點 每一個不同的實現都需要一個子類來實現,導致類的個數增加,使得系統更加龐大。

使用場景 1、有多個子類共有的方法,且邏輯相同。 2、重要的、復雜的方法,可以考慮作為模板方法。

注意事項 為防止惡意操作,一般模板方法都加上 final 關鍵詞。

參考

模板模式|菜鳥教程

Template method pattern

歡迎關注我的微信公眾號

折騰Java設計模式之模板方法模式

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

贞丰县| 灌南县| 邹城市| 共和县| 肇源县| 新平| 清新县| 铜山县| 永清县| 百色市| 原平市| 衡阳县| 湟中县| 青海省| 嘉义县| 三河市| 神池县| 长海县| 伊金霍洛旗| 禹城市| 马山县| 永安市| 博爱县| 马公市| 赤峰市| 尼勒克县| 定结县| 赫章县| 太湖县| 涞水县| 蓬溪县| 河池市| 巍山| 九江县| 微山县| 麦盖提县| 长沙县| 义乌市| 昆山市| 华阴市| 胶南市|