C# 如何为工厂设计添加随机特征?

C# 如何为工厂设计添加随机特征?,c#,design-patterns,factory,factory-pattern,C#,Design Patterns,Factory,Factory Pattern,我正在为我的公司做一个内部项目,项目的一部分是能够在工厂设计中生成各种“数学问题” 要产生问题,必须指定工厂的难度 每个ProblemFactory都包含一些抽象方法,如ConfigureXLevels和Generate 提供一个随机变量 包含一个包含可用级别的字典(key:=levels,value:=IConfiguration,其工作原理类似于用于生成问题的对象容器(例如,二进制和时间表都需要两个绑定的对象)) _ 问题在于从AdditionProblemFactory和TimeTab

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

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

问题在于从
AdditionProblemFactory
TimeTablesProblemFactory
生成的
方法中,
x,y
应根据级别I配置接收随机数

Bound
类包含
Min
Max
值。例如,如果我选择了
Levels.Medium
,我必须接收到数字1和数字2(
Number 1+Number 2=X
)中特定范围或范围的问题

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

如果你想下载的话。别担心,它太小了。

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

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

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

我首先重构factory类。针对每一个难度等级都有一门课:EasyProblemFactory、MediumProblemFactory和艰难ProblemFactory。允许它们从公共接口继承

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;
}
...
class EasyProblemFactory
{
问题创建()
{
返回新问题(…);
}
公共int X;
公共智力;
}
类问题工厂
{
问题创建()
{
返回新问题(…);
}
公众范围;
}
...
现在需要配置每个工厂,独立于其他类型的工厂,具体取决于工厂的实例化方式,以及您使用的IoC容器(如果有)将决定如何配置工厂


另一个选项是用命令对象替换factory对象,并将命令链接在一起。例如,用于添加、减法、乘法和除法的命令。然后将这些命令链接在一起以生成问题。您甚至可以为指数、pi、对数函数创建命令

@L.B很抱歉。我不知道我不该这么做。我只是想更简短地解释一下。下次我会记住的。谢谢你看我的代码。我对国际奥委会有怀疑,我真的不知道。你能详细解释一下这个容器以及我如何使用它吗?在文章中,IConfiguration是一个标记接口。其他的数学问题是由配置产生的,有必要产生这个问题。换句话说,并不是所有的问题都需要两个边界,一些问题只需要一个边界,另一些问题需要另一种类型的类,等等。我不确定这是否会影响solution@DarfZon,重要的是,您要尝试将不同的职责彼此分离,并尽可能保持类/接口的精简。如果您有其他需要不同成员或方法的类,那么这些可能应该是一个单独的接口。例如,您可以将上面的IConfiguration接口的名称更改为IBinaryProblemConfiguration。我还在学习这些设计。对不起,如果我不高兴,你能写下工厂课的问题吗?我不知道该如何更改。@DarfZon工厂类与以前一样,只需去掉
Configure*
函数,并如上所述更改
Generate
的方法签名即可。
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); }
    }   
}
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);
}
interface IProblemFactory
{
    Problem Create();
}
class EasyProblemFactory
{
    Problem Create()
    {
        return new Problem(...);
    }

    public int X;
    public int Y;
}

class MediumProblemFactory
{
    Problem Create()
    {
        return new Problem(...);
    }

    public Bound<int> Range;
}
...