簡體   English   中英

策略模式,將函數傳遞給父方法

[英]Strategy pattern, pass function into parent method

我想實施類似“戰略模式”的方法。 我在Parent方法中使用了通用邏輯,我需要將特定的邏輯(使用強制轉換等)傳遞給parent。

我有以下課程:

class A{
    public Object generateData(Function fetchData, AbstractForm form)
    {
        List<DataBean> dataBeans = (List<DataBean>) fetchData.apply(form);
        //...
    }
}

class B extends A{
    void someMethod(AbstractForm form){
        Function<AbstractForm, List<DataBean>> fetchFunction = new Function<AbstractForm, List<DataBean>>() {
            //here goes form specific casting and other data fetch specific logic
            return dataBeans;
        }
        super.generateData(fetchFunction, form);
    }
}

我在這里正確理解了功能的想法嗎?

正確使用Strategy模式意味着在Context(在您的情況下為A類)和Strategy(在您的情況下為Function的實現)之間進行聚合。

您可以在下圖中看到這種關系(摘自《四人幫》一書, 設計模式:可重用的面向對象軟件的元素 )。

策略模式UML

下面,我對您的問題應用了傳統的策略模式方法。 在這種情況下,我做到了讓Function.apply(AbstractForm)返回List<DataBean>來消除強制轉換的需要。 您當然可以使用泛型來使Function更加靈活。

戰略

public interface Function {
    List<DataBean> apply(AbstractForm form);    
}

語境

public class A {

    private Function fetchData; // strategy

    public void setStrategy(Function fetchData) { // method for setting the strategy
        this.fetchData = fetchData;
    }

    // precondition: fetchData != null
    public Object generateData(AbstractForm form) {
        List<DataBean> dataBeans = fetchData.apply(form); // using the strategy
        return null; // whatever you want to return
    }    
}

在這種情況下,擴展類A時並不需要,因為我們可以注入我們的策略( Function使用) setStrategy(Function) 但是,我們總是可以使用預定義的策略將A擴展為A好的對象。

例如:

public class B extends A {

    public B() {
        setStrategy((form) -> null); // implement your concrete strategy here
    }
}

使用工廠方法

由於可能需要一種獲取數據的策略,並且可能沒有使用“默認值”並且可能永遠都不會更改,因此可以使用Factory方法模式來強制執行Product( Function )的創建。 注意,類A現在是抽象的,包括一個Factory方法createFunction() ,然后在子類(例如B )中實現該方法以創建Function

可以在下面的UML中看到工廠方法模式的設計。 在這種情況下,我們的產品現在是以前的策略( Function ),而創建者為A類,ConcreteCreator為B類。

工廠方法模式UML

創作者

public abstract class A {

    private Function fetchData; // product to be used

    public class A() {
        fetchData = createFunction(); // call factory method
    }

    protected abstract Function createFunction(); // factory method

    // precondition: fetchData != null
    public Object generateData(AbstractForm form) {
        List<DataBean> dataBeans = fetchData.apply(form); // using the product
        return null; // whatever you want to return
    }

}

ConcreteCreator

public class B extends A {

    @Override
    protected Function createFunction() {
        return (form) -> null; // return product
    }
}

在這種情況下,乘積是固定的並且不能更改,但是可以通過將兩個模式混合在一起並在第一個示例中再次包含來自類A setStrategy(Function)來克服。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM