如何改善我的抽象工厂模式?

时间:2012-03-29 01:16:49

标签: c# generics design-patterns factory

我真的没有使用设计模式的经验。我想我需要在我的情况下使用Abstract Factory Pattern

我正在创建一个生成数学问题的系统。开发人员必须实现两个接口:

  • 问题:这包含需要生成问题的属性。
  • 配置:这是生成问题的范围参数或条件。
  • 工厂:他正在制造新问题。

这是什么意思?这意味着像一个黑盒子。输入是Configuration,输出是Problem,中间的接口是工厂。

enter image description here

这里我有我的界面和标记界面:

public abstract class Problem { }
public abstract class Configuration { }
public interface IProblemFactory
{
    Problem CreateProblem();
}

这是工厂的基础,因为我需要Random类。我实现这一个的所有类都必须有相同的种子,所以我有一个静态的实例。

public abstract class ProblemBaseFactory<TProblem, TConfiguration> : IProblemFactory
    where TProblem : Problem
    where TConfiguration : Configuration
{
    private const int DEFAULT_SEED = 100;
    protected TConfiguration _config;
    private static Random _random;

    public ProblemBaseFactory() { }
    public ProblemBaseFactory(TConfiguration config)
    {
        _config = config;

        if (_random == null) _random = new Random(DEFAULT_SEED);
    }

    protected TConfiguration Configuration { get { return _config; } }
    protected Random Random { get { return _random; } }

    public void SetSeed()
    {
        _random = new Random(DEFAULT_SEED);
    }

    public Problem CreateProblem()
    {
        return CreateProblem(_config);
    }

    public abstract TProblem CreateProblem(TConfiguration config);
}

然后我实现了所有这些。例如,这是一个BinaryProblems模块,如2+3

public class BinaryConfiguration : Configuration
{
    public Range<int> Range1 { get; set; }
    public Range<int> Range2 { get; set; }
    public List<Operators> Operators { get; set; }

    public BinaryConfiguration(Range<int> range1, Range<int> range2, List<Operators> operators)
    {
        this.Range1 = range1;
        this.Range2 = range2;
        this.Operators = operators;
    }

public class BinaryProblem : Problem
{
    public BinaryProblem(decimal x, decimal y, Operators op, decimal response)
    {
        this.X = x;
        this.Y = y;
        this.Response = response;
    }

    public decimal X { get; private set; }
    public decimal Y { get; private set; }
    public decimal Response { get; private set; }
}

public enum Operators
{
    Addition, Substract, Multiplication, Division
}

最重要的部分,这是一个具体的工厂。看看这部分我设置了通用值。为什么?因为我认为这是实现具体价值观的最佳方式,我的意思是我现在不必投出任何价值。

public class BinaryFactory : ProblemBaseFactory<BinaryProblem, BinaryConfiguration>
{
    public BinaryFactory(BinaryConfiguration config) : base(config) { }

    public override BinaryProblem CreateProblem(BinaryConfiguration config)
    {
        var x = GenerateValueInRange(config.Range1);
        var y = GenerateValueInRange(config.Range2);

        var index = Random.Next(config.Operators.Count);
        var op = config.Operators[index];

        return new BinaryProblem(x, y, op, x + y);
    }

    private decimal GenerateValueInRange(Range<int> range)
    {
        return Random.Next(range.Min, range.Max);
    }
}

实施它是:

        BinaryConfiguration configuration = new BinaryConfiguration() {.. }
        IProblemFactory factory = new BinaryFactory(configuration);
        var a = factory.CreateProblem();

但是在这一点上,我猜这不是最好的设计..因为如果我想使用新的配置,我应该创建它的另一个实例,我认为这不是最好的。

我该如何改进?

1 个答案:

答案 0 :(得分:1)

作为一个起点,我建议您使用递归类型定义。试试这个:

public abstract class Problem<P, C>
    where P : Problem<P, C>
    where C : Configuration<P, C>
    { }

public abstract class Configuration<P, C>
    where P : Problem<P, C>
    where C : Configuration<P, C>
    { }

public interface IProblemFactory<P, C>
    where P : Problem<P, C>
    where C : Configuration<P, C>
{
    P CreateProblem(C configuration);
}

这有效地为您的类型实现了Gang of Four“Bridge”设计模式。

如果有帮助,请告诉我。