2012-07-10 6 views
2

Je crée un logiciel pour les problèmes de maths. Comme vous le savez, il existe plusieurs types de problèmes mathématiques.Comment améliorer cette conception (motif)?

Dans mon logiciel, certains problèmes proviennent d'un fichier XML (référentiel) et d'autres peuvent être générés par une usine (nombres aléatoires, vous le savez). Par exemple, si je crée des problèmes binaires en tant qu'additions, si je choisis la première option, je peux avoir une classe où obtenir trois fichiers et en choisir quelques-uns. Ou si je choisis le second, je peux générer les problèmes comme aléatoires:

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

return new BinaryProblem(x, y); 

Quelque chose comme ça.

J'ai donc développé ce design en ce moment, je suppose que j'ai construit un modèle de stratégie.

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

Dans le service que je mis IService en public parce que, je dois savoir si le service est une usine ou un dépôt. Dans le cas où ce sera un référentiel, je soumettrais quelques problèmes au fichier.

Je ne suis pas convaincu de la conception. Je suppose que je suis redondant et ce n'est pas la meilleure façon de le faire. Pouvez-vous donner votre avis ou des idées pour l'améliorer?

EDIT: Ce que je voulais dire la première option est la suivante:

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; 
    } 
+0

Qu'en est-il considérer problème spécifique (dépôt), un cas particulier de problème aléatoire? Le problème aléatoire nécessite également une description en plus de la partie du nombre aléatoire, non? – nhahtdh

+0

Oui, c'est, comme une configuration .. Je ommite que –

+0

Ce que je voulais dire, c'est que, vous pouvez mettre le problème à travers un "pipeline": premier fetch de XML, puis générer un problème aléatoire. Ensuite, vous n'avez pas besoin de 2 classes pour étendre l'interface IService. – nhahtdh

Répondre

1

Je ne sais pas pourquoi vous avez deux interfaces distinctes, IProblemService et IService; pour moi, il semble qu'ils font la même chose.

Je séparerais la génération de problèmes aléatoires (la partie « usine ») de la classe qui retourne effectivement les problèmes (la partie « référentiel »):

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) { 
    ... 
    } 
} 

Vous pouvez ensuite charger à partir d'un fichier XML fichier:

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

ou vous pouvez générer des problèmes en utilisant l'usine et les approvisionner à partir d'un dépôt en mémoire:

factory = new RandomProblemFactory(); 
problems = factory.GenerateProblems(10); 
repository = new InMemoryProblemRepository(problems); 
+0

Quoi qu'il en soit, j'ai ajouté quelques informations sur l'option du référentiel (la première) –

+0

Notez que mon utilisation de "repository" est quelque peu différente. 'IProblemRepository' ressemble plus à votre' IProblemService' d'origine. – casablanca

+0

J'aime cette idée, que je prévoyais est de stocker celui-ci dans un conteneur et je suis presque avec ce design, je peux accomplir .. aussi, je déclare des classes abstraites comme XmlProblemRep .. et FactoryPro .. avec méthodes abstraites. –

0

Il semble que vous vouliez avoir différentes sources de problèmes (fichier Xml, base de données, mémoire) et rendre votre code ignorant la persistance. Si oui, je ne mettrais pas en œuvre l'interface IService dans la classe d'usine. Conservez l'usine uniquement pour la génération de problèmes aléatoires.Je voudrais ajouter Submit à l'interface:

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

La classe XmlRepositoryService obtiendrait/enregistrer des données de/vers le fichier 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 
    } 
} 

La classe de stockage en mémoire stockerait une liste de problèmes:

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

la classe ProblemFactory aurait la méthode GenerateRandom seulement:

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

    return new BinaryProblem(x, y); 
    } 
} 

Pour l'utiliser, juste instancier une classe référentiel, générer un problème, l'ajouter à une liste et soumettre la liste au référentiel:

var problems = new List<Problems>(); 
var problem = ProblemFactory.GenerateRandom(); 
problems.Add(problem); 
var repository = new MemoryRepositoryService(); //or XmlRepositoryService 
repository.Submit(problems); 
Questions connexes