2

私は数学の問題のためのソフトウェアを作成しています。ご存知のように、数学の問題には多くの種類があります。

私のソフトウェアでは、いくつかの問題はXmlファイル(リポジトリ)から取得され、別の問題はファクトリによって生成される可能性があります(乱数、ご存知のとおり)。

たとえば、バイナリの問題を追加として作成している場合、最初のオプションを選択すると、ファイルを取得してそれらのいくつかを選択するクラスを作成できます。または、2番目のものを選択した場合、問題をランダムに生成できます。

x = random.Next(y, z);
y = random.Next(y, z);

return new BinaryProblem(x, y);

そんな感じ。

だから私は今このデザインを開発しました、私は戦略パターンを構築したと思います。

public interface IProblemService
{
    IEnumerable<Problem> GetProblems();
}

public class ProblemService : IProblemService
{
    private readonly IService service;

    public ProblemService(IService service)
    {
        this.service = service;
    }

    public IService Service
    {
        get { return service; }
    }

    public IEnumerable<Problem> GetProblems()
    {
        return this.service.GetProblems();
    }
}

/* =====================================================*/
CONCRETE CLASSES

public interface IService
{
    IEnumerable<Problem> GetProblems();
}

// When I want to generate random problems
public abstract class FactoryService : IService
{
    public IEnumerable<Problem> GetProblems();
    public abstract Generate();
}

// When I want to get problems through a XML file
public class RepositoryService : IService
{
    public abstract IEnumerable<Problem> GetProblems();
    void Submit(IEnumerable<Problem> problems);
}

サービスでは、サービスがファクトリであるかリポジトリであるかを知る必要があるため、IServiceをパブリックとして配置しました。これがリポジトリになる場合は、ファイルにいくつかの問題を送信します。

私はそのデザインに確信が持てません。私は冗長だと思いますが、これは最善の方法ではありません。

あなたはそれを改善するためにあなたの意見やアイデアを与えることができますか?

編集:私が最初のオプションで意味したのは:

    public IEnumerable<Problem> GetProblems()
    {
        if (model == null)
        {
            model = new List<Problem>();

            // Dummy Data.
            model.Add(new SimplifyProblem() { Id = "1", Expression = "8 ÷ 2 x 5 ÷ 10", Result1 = 2 });
            model.Add(new SimplifyProblem() { Id = "2", Expression = "20 ÷ 2 x 5 - 2", Result1 = 48 });
            model.Add(new SimplifyProblem() { Id = "3", Expression = "15 ÷ 5 + 3", Result1 = 6 });
            model.Add(new SimplifyProblem() { Id = "4", Expression = "6 + 4² ÷ 8 - 2", Result1 = 6 });
            model.Add(new SimplifyProblem() { Id = "5", Expression = "8 + 2 x 4", Result1 = 40 });
            model.Add(new SimplifyProblem() { Id = "6", Expression = "8 + 4 x (5 - 3)", Result1 = 16 });
            model.Add(new SimplifyProblem() { Id = "7", Expression = "8 - 3 + 5", Result1 = 10 });
            // ...
        }

        return model;
    }
4

2 に答える 2

1

IProblemServiceなぜ2つの別々のインターフェースがあるのか​​わかりませんIService。私には、彼らは同じことをしているように見えます。

ランダムな問題の生成(「ファクトリ」部分)を、実際に問題を返すクラス(「リポジトリ」部分)から分離します。

public interface IProblemRepository {
  IEnumerable<Problem> LoadProblems();
}

public class XmlProblemRepository : IProblemRepository {
  ...
}

public class InMemoryProblemRepository : IProblemRepository {
  private readonly IEnumerable<Problem> problems;

  public InMemoryProblemRepository(IEnumerable<Problem> problems) {
    this.problems = problems;
  }

  public IEnumerable<Problem> LoadProblems() {
    return problems;
  }
}

public class RandomProblemFactory {
  public IEnumerable<Problem> GenerateProblems(int count) {
    ...
  }
}

次に、XMLファイルからロードできます。

repository = new XmlProblemRepository("problems.xml");

または、ファクトリを使用して問題を生成し、メモリ内リポジトリからそれらを調達することができます。

factory = new RandomProblemFactory();
problems = factory.GenerateProblems(10);
repository = new InMemoryProblemRepository(problems);
于 2012-07-10T04:00:28.510 に答える
0

問題のさまざまなソース(Xmlファイル、データベース、メモリ)を用意し、コードを永続性に依存しないようにしたいようです。もしそうなら、私はIServiceファクトリクラスにインターフェイスを実装しません。ランダムな問題の生成のためだけにファクトリを保持します。インターフェイスに追加Submitします:

public interface IService
{
    IEnumerable<Problem> GetProblems();
    void Submit(IEnumerable<Problem>);
}

クラスはXmlRepositoryService、Xmlファイルから/へのデータを取得/保存します。

public class XmlRepositoryService : IService
{
    public IEnumerable<Problem> GetProblems()
    {
      //get the problems from the Xml file
    }

    public void Submit(IEnumerable<Problem> problems)
    {
      //save problems to the xml file
    }
}

インメモリリポジトリクラスは、問題のリストを格納します。

public class MemoryRepositoryService : IService
{
    private List<Problem> problemList = new List<Problem>();

    public IEnumerable<Problem> GetProblems()
    {
      return problemList;
    }

    public void Submit(IEnumerable<Problem> problems)
    {
      problemList.AddRange(problems.ToList());
    }
}

ProblemFactoryクラスにはGenerateRandomメソッドのみがあります。

public class ProblemFactory
{
  public static Problem GenerateRandom()
  {
    var x = random.Next(y, z);
    var y = random.Next(y, z);

    return new BinaryProblem(x, y);
  }
}

これを使用するには、リポジトリクラスをインスタンス化し、問題を生成し、それをリストに追加して、リストをリポジトリに送信します。

var problems = new List<Problems>();
var problem = ProblemFactory.GenerateRandom();
problems.Add(problem);
var repository = new MemoryRepositoryService(); //or XmlRepositoryService
repository.Submit(problems);
于 2012-07-10T04:10:52.407 に答える