如何为工厂设计添加随机功能

本文关键字:添加 随机 功能 工厂 | 更新日期: 2023-09-27 18:21:38

我正在为公司做一个内部项目,该项目的一部分是能够在工厂设计中生成各种"数学问题"。

  • 要生成问题,必须指定工厂中的难度级别
  • 每个ProblemFactory都包含作为ConfigureXLevels和Generate的抽象方法
  • 提供Random变量
  • 包含一个字典,其中包含可用级别(key:=Levelsvalue:=IConfiguration,其工作方式类似于用于生成问题的对象容器(例如二进制表和时间表都需要两个Bound对象)

_

public abstract class ProblemFactory
{
    private IDictionary<Levels, IConfiguration> Configurations = new Dictionary<Levels, IConfiguration>();
    protected Random Random = new Random();
    public ProblemFactory() {
        LoadLevels();
    }
    protected abstract Problem Generate();
    protected abstract IConfiguration ConfigureEasyLevel();
    protected abstract IConfiguration ConfigureMediumLevel();
    protected abstract IConfiguration ConfigureHardLevel();
    private void LoadLevels() {
            Configurations.Add(Levels.Easy, ConfigureEasyLevel();
            Configurations.Add(Levels.Medium, ConfigureMediumLevel();
            Configurations.Add(Levels.Hard, ConfigureHardLevel();
    }
} 

这里有一个关于创建添加问题的具体类,检查我是如何从抽象ProblemFactory重写一些ConfigureXLevel并返回IConfiguration的。

public class AdditionProblemFactory : ProblemFactory
{
    public override Problem Generate() {
        int x = //.. x must receive a random number according to the configuration selected for the level
        int y =  //.. 
        Operators op = Operator.Addition
        return BinaryProblem.CreateProblem(x, y, op);
    }
    protected override IConfiguration ConfigureEasyLevel() {
        // the same of ConfigureMediumLevel() but with others values
    }
    protected override IConfiguration ConfigureMediumLevel() {
        BinaryProblemConfiguration configuration = new BinaryProblemConfiguration();
        configuration.Bound1 = new Bound<int>(100, 1000);
        configuration.Bound2 = new Bound<int>(10, 100);
        return configuration;
    }
    protected override IConfiguration ConfigureHardLevel() {
        // the same of ConfigureMediumLevel() but with others values
    }
}
public class BinaryProblemConfiguration : IConfiguration
{
    public Bound<int> Bound1 { get; set; }  //Bounds for Number1 of a binary problem
    public Bound<int> Bound2 { get; set; } // Bounds…    Number2  …
}

问题是在Generate method中从AdditionProblemFactoryTimesTablesProblemFactoryx, y应根据级别IConfiguration接收随机数。

Bound类包含MinMax值。例如,如果我选择Levels.Medium,我必须在Number1和Number2(Number 1 + Number 2 = X)中收到特定范围或界限的问题

    AdditionProblemFactory factory = new AdditionProblemFactory();
    BinaryProblem problem = (BinaryProblem)factory.Generate(Levels.Medium);

这是我不知道在设计中应该修改的部分。Random在ProblemFactory上,但最好将变量移动到IConfiguration并在那里生成数字。

如果你喜欢下载的话。别担心,它太小了。http://www.mediafire.com/?z5j9hu1szpuu2u5

如何为工厂设计添加随机功能

通过进行一些重构,我建议创建以下类层次结构:

public interface IConfiguration
{
     Bound<int> Bound1 { get; }
     Bound<int> Bound2 { get; }
}
public class EasyLevelConfiguration : IConfiguration
{
    public Bound<int> Bound1
    {
        get { return new Bound<int>(100, 1000); }
    }
    public Bound<int> Bound2
    {
        get { return new Bound<int>(10, 100); }
    }   
}

并更改ProbemGeneratorFactory的实现,如下所示:

public override Problem Generate(IConfiguration configuration)
{
    int x = this.Random.Next(configuration.Bound1.Max); //use value from configuration
    int y = this.Random.Next(configuration.Bound2.Min); //use value from configuration
    Operators op = Operator.Addition
    return BinaryProblem.CreateProblem(x, y, op);
}

或者,您可以在ProblemFactory的构造函数中提供各种IConfiguration对象,并为各种配置提供不同的实例。

我将从重构工厂类开始。每个难度级别都有一个课程:EasyProblemFactory、MediumProblemFactory&困难问题工厂。允许它们从通用接口继承

interface IProblemFactory
{
    Problem Create();
}

那么ProblemFactory的每个实现都可以有自己的特定属性

class EasyProblemFactory
{
    Problem Create()
    {
        return new Problem(...);
    }
    public int X;
    public int Y;
}
class MediumProblemFactory
{
    Problem Create()
    {
        return new Problem(...);
    }
    public Bound<int> Range;
}
...

现在的问题是配置每个工厂,独立于其他类型的工厂。取决于工厂的实例化方式以及您使用的IoC容器(如果有的话),将决定如何配置工厂。

另一种选择是用命令对象替换factory对象,并将命令链接在一起。例如,加法、减法、倍数、除法的命令。然后将这些命令链接在一起以构建问题。您甚至可以为指数、圆周率、对数函数创建命令。