在我的客户中,我想指定在builder构建的类中使用的策略。

但是,我无法将这些策略对象传递给构建器,因为它们的初始化部分由构建器处理。但是,我仍然必须与生成器进行通信,以使用哪个对象以及将其传递给哪些附加参数。

这是Builder类

public class MarketGeneratorBuilder {
    private MarketGenerator.Parameters parameters;

    public MarketGeneratorBuilder(MarketGenerator.Parameters parameters) {
        this.parameters = parameters;
    }

    public MarketGenerator build() {
        return new MarketGenerator(
            parameters,
            new GoodsGenerator(
                new UniformDistribution(
                    new ValueRange(0,parameters.getNumberOfLevels()-1)
                )
            ),
            new ITGenerator(),
            new OTGenerator(),
            new IOTGenerator(
                new UniformDistribution(
                    new ValueRange(1,parameters.getNumberOfLevels()-2)
                ),
                new BundlesGenerator(
                    new ForwardMarkovDistribution(
                        new MarkovDistribution.Parameters(
                            new ValueRange(0,parameters.getNumberOfLevels()-1),
                            0.1,
                            0.1
                        )
                    ),
                    new UniformDistribution(
                        new ValueRange(1,parameters.getNumberOfGoodsToCreate()-1)
                    )
                ),
                new BundlesGenerator(
                    new BackwardMarkovDistribution(
                        new MarkovDistribution.Parameters(
                            new ValueRange(0,parameters.getNumberOfLevels()-1),
                             0.2,
                             0.2
                        )
                    ),
                    new UniformDistribution(
                        new ValueRange(1,parameters.getNumberOfGoodsToCreate()-1)
                    )
                )
            )
        );
    }
}


发行版(UniformDistribution,ForwardMarkovDistribution,ForwardMarkovDistribution以及可能更多的发行版)现在已进行硬编码,但应由客户端选择。值范围由Builder(ValueRange对象)定义。但是,某些发行版还包含其他参数(ForwardMarkovDistribution带有ValueRange,alpha,beta),这些参数应由客户端定义。

我能看到的唯一解决方案是将ValueRange从构造函数拉入setter。但这似乎是错误的,因为它是对象的必要领域。另外,我希望客户端代码不包含构建器的内部逻辑。更像,

DistributionType levelDistribution = new DistributionType(Distributions.UNIFORM);
DistributionType goodsDistribution = new DistributionsType(Distributions.MARKOV_FORWARD, 0.1,0.1);


但是在这种情况下,我不了解如何实施数据完整性。这意味着当客户端选择Distributions.UNIFORM时,没有更多的参数可以传递。或在Distributions.MARKOV_FORWARD的情况下,他必须通过alpha和beta。

因此,我希望您能指出一个更好的模式。谢谢!

最佳答案

为了获得充分的灵活性,请为每个发行版添加一个提供程序/工厂:

interface DistributionProvider<D extends Distribution> {
  D create(ValueRange vr);
}

class UniformDistributionProvider implements DistributionProvider<UniformDistribution> {
  UniformDistribution create(ValueRange vr) {
    return new UniformDistribution(vr);
  }
}

class ForwardMarkovDistributionProvider implements DistributionProvider<ForwardMarkovDistribution> {

  private final MarkovDistribution.Parameters params;

  ForwardMarkovDistributionProvider(MarkovDistribution.Parameters pParams) {
    params = pParams;
  }

  ForwardMarkovDistribution create(ValueRange vr) {
    return new ForwardMarkovDistribution(vr, params);
  }
}

// etc.


(从ValueRange删除MarkovDistribution.Parameters。)

基本上,每个提供程序都存储分发的所有必要参数,但ValueRange除外。
然后,客户端可以为所需的分发实例化提供程序,并为其配置适当的值。
构建器将获取DistributionProvider的那些实例,并使用这些实例创建分发,并传递ValueRange

09-05 05:19