У меня действительно нет большого опыта использования шаблонов проектирования.Я думаю, мне нужно использовать Abstract Factory Pattern
в моей ситуации.
Я создаю систему для генерирования математических задач.Разработчик должен реализовать два интерфейса:
- Проблема: содержит свойства, для которых требуется сгенерированная проблема.
- Конфигурация: это параметры диапазона или условия для создания проблемы.
- Фабрика: он отвечает за создание новой Задачи.
Что это значит?Это значит, как черный ящик.Для ввода - Configuration
, а для вывода - Problem
, интерфейс посередине - заводской.
Здесь у меня есть интерфейс и маркерные интерфейсы:
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);
}
Тогда у меня есть реализация всего этого.Например, это модуль для бинарных проблем типа 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();
Но на данный момент, я думаю, это не лучший дизайн ... потому что, если я хочу использовать новую конфигурацию, я должен создать еще один экземпляр, и я предположил, что это не самая лучшая вещь.
Какя могу улучшить это?