繁体   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