策略模式,将函数传递给父方法

Strategy pattern, pass function into parent method

我想实现类似策略模式的东西。我在 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);
    }
}

我对功能的理解是否正确?

正确使用策略模式意味着上下文(在您的情况下 class A)和策略(在您的情况下 Function 的实现)之间的聚合。

你可以在下图中看到关系(取自四人帮书,Design patterns: elements of reusable object-oriented software)。

下面我对您的问题应用了传统的策略模式方法。在这种情况下,我已经做到了 Function.apply(AbstractForm) returns 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
    }    
}

在这种情况下,不需要扩展 class A,因为我们可以使用 setStrategy(Function) 注入我们的策略 (Function)。但是,我们总是可以将 A 扩展到具有预定义策略的伟大对象。

例如:

public class B extends A {

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

使用工厂方法

由于可能需要获取数据的策略,并且可能没有 'default' 可以使用并且可能永远不会更改,因此可以使用工厂方法模式来强制创建产品(Function).注意 class A 现在是抽象的并且包含一个工厂方法 createFunction() 然后在子 class 中实现(例如 B)以创建 Function.

工厂方法模式的设计可以在下面的 UML 中看到。在这种情况下,我们的产品现在是我们以前的策略 (Function),而创建者是 class A,而 ConcreteCreator 是 class B

创作者

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
    }
}

在这种情况下,Product 是固定的且不可更改,但这可以通过将两个模式混合在一起并从第一个示例中的 class A 再次包含 setStrategy(Function) 来克服.