泛型和模板設計模式


當兩個或多個功能很大一部分實現都一樣,只有其中一部分處理邏輯不同的情況下。我們通常都會采用模板設計模式來實現,這樣既可以滿足功能的需求也可以很好地實現代碼的維護。這也正是設計模式的精髓所在。但是,如果有這樣一個需求,該如何實現呢?既滿足了模板設計模式的條件,也就是說兩個或多個功能的總體實現流程是一致的,只是部分處理邏輯上存在差異;但有點特別的是根據不同的功能,返回值類型有所差別。這樣的情況下我們可以通過模板設計模式結合泛型來很好地實現相應的功能。

技術要點

我們先來看下模板設計模式的技術點,模板設計模式使用的技術點是:

  • 抽象類:控制程序總體邏輯(骨架)
  • 實現類:繼承於抽象類,實現具體差異部分的邏輯

此處要求返回值類型根據不同的業務,返回不同類型的響應信息,因此還需要用到泛型。

  • 泛型於設計模式的結合

具體實現如下:

響應實體泛型的定義

public class Result<T> {
    T response;

    public T getResponse() {
        return response;
    }

    public void setResponse(T response) {
        this.response = response;
    }
}

程序骨架,模板設計模式

public abstract class BaseService<T> {

    /**
     * 定義了程序的主要實現流程-骨架
     * @return
     */
    public Result handle() {
        Result result = new Result();
        method1();
        result.setResponse(method2());
        return result;
    }

    /**
     * 返回值-泛型,根據不同的業務返回不同的響應類型
     * @return
     */
    private T method2() {
        T response = initResponse();//獲取子類初始化的響應實例
        System.out.println("BaseService method2");
        return response;
    }

    /**
     * 公共處理業務
     */
    private void method1() {
        System.out.println("BaseService method1");
    }

    /**
     * 響應類型-泛型,提供出去給具體實現類進行初始化
     * @return
     */
    protected abstract T initResponse();
}

模板抽象類需要注意的幾個點:

  • BaseService<T>,模板類提供泛型支持
  • Result里的response返回值類型,由子類進行控制
  • 返回值類型,通過提供抽象方法,子類進行初始化來實現。protected abstract T initResponse();

至此,根據不同業務類型返回不同響應類型的模板設計模式的總體框架已經搭建完成了。

差異業務實現類

  • 定義返回值類型
  • 繼承於模板抽象類-業務實現類
  • 實現模板抽象類的方法

返回值類型

/**
 *
 * 返回值類型基類,公共部分
 */
public class BaseResponse {
    private int age;
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
/**
 *
 * 返回值類型
 */
public class ChinaResponse extends BaseResponse {

    List<String> province;

    public List<String> getProvince() {
        return province;
    }

    public void setProvince(List<String> province) {
        this.province = province;
    }
}
/**
 *
 * 返回值類型
 */
public class AmericaResponse extends BaseResponse {
    List<String> state;

    public List<String> getState() {
        return state;
    }

    public void setState(List<String> state) {
        this.state = state;
    }
}

繼承於模板抽象類-業務實現類

/**
 *
 * 業務實現類1
 */
public class ChinaServiceImpl extends BaseService<ChinaResponse> {

    public Result<ChinaResponse> handle() {
        Result result = super.handle();
        return result;
    }

    /**
     * 實現抽象方法,初始化返回值類型
     * @return
     */
    @Override
    protected ChinaResponse initResponse() {
        return new ChinaResponse();
    }
}
/**
 *
 * 業務實現類2
 */
public class AmericaServiceImpl extends BaseService<AmericaResponse> {

    /**
     * 實現抽象方法,初始化返回值類型
     * @return
     */
    @Override
    protected AmericaResponse initResponse() {
        return new AmericaResponse();
    }
}

測試

    public static void main(String[] args) {
        BaseService<ChinaResponse> baseService = new ChinaServiceImpl();
        Result<ChinaResponse> result = baseService.handle();
        ChinaResponse chinaResponse = result.getResponse();
        System.out.println(chinaResponse.toString());

        BaseService<AmericaResponse> americaService = new AmericaServiceImpl();
        Result<AmericaResponse> americaResult = americaService.handle();
        AmericaResponse americaResponse = americaResult.getResponse();
        System.out.println(americaResponse.toString());
    }

測試結果:

BaseService method1
BaseService method2
com.designpatterns.template.generic.response.ChinaResponse@28d93b30
BaseService method1
BaseService method2
com.designpatterns.template.generic.response.AmericaResponse@1b6d3586

總結

通過模板設計模式和泛型的結合,可以非常靈活地處理通用流程和處理邏輯之間的差異;又可以很好地滿足不同業務不同返回值類型的需求。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM