4
\$\begingroup\$

This morning I decided to write this question: https://stackoverflow.com/questions/11727571/are-there-problems-if-i-have-a-verbose-datatype/11727723#11727723

I don't really explain my scenario about how am I accesing through the nested dictionaries. I decided to have the default alias (IDictionary<string, IDictionary<Levels, IList<Problem>>>) but I'm thinking that's not a good option right now.

I'm gonna show some parts of my code:

ProblemBaseFactory

public abstract class ProblemBaseFactory : IProblemFactory
{
    private IDictionary<string, IDictionary<Levels, IList<Problem>>> problemDictionaryPackages;

    protected ProblemBaseFactory()
    {
        problemDictionaryPackages = new Dictionary<string, IDictionary<Levels, IList<Problem>>>();
    }

    protected IDictionary<string, IDictionary<Levels, IList<Problem>>> ProblemDictionaryPackages
    {
        get { return problemDictionaryPackages; }
    }

    public abstract IEnumerable<Levels> AvailableLevels(string packageName);
    public abstract IEnumerable<Problem> LoadProblems(ProblemFactoryProperties properties);
}

RuleProblemFactory

public abstract class RuleProblemFactory : ProblemBaseFactory
{
    private IDictionary<string, IDictionary<Levels, IList<ProblemRule>>> ruleDictionaryPackages;
    private IRuleAlgorithmSelector ruleAlgorithmSelector;
    private IList<Problem> temp;

    protected RuleProblemFactory()
        : this(new Dictionary<string, IDictionary<Levels, IList<ProblemRule>>>(), new SequentialRuleSelector())
    {
    }

    protected RuleProblemFactory(IRuleAlgorithmSelector ruleAlgorithmSelector)
        : this(new Dictionary<string, IDictionary<Levels, IList<ProblemRule>>>(), ruleAlgorithmSelector)
    {
    }

    protected RuleProblemFactory(IDictionary<string, IDictionary<Levels, IList<ProblemRule>>> ruleDictionary,
        IRuleAlgorithmSelector ruleAlgorithmSelector)
    {
        this.ruleDictionaryPackages = ruleDictionary;
        this.ruleAlgorithmSelector = ruleAlgorithmSelector;

        LoadBankOfRules();
    }

    protected IDictionary<string, IDictionary<Levels, IList<ProblemRule>>> RuleDictionaryPackages
    {
        get { return ruleDictionaryPackages; }
    }

    public override IEnumerable<Problem> LoadProblems(ProblemFactoryProperties properties)
    {
        // does exist the package name?
        if (!ProblemDictionaryPackages.ContainsKey(properties.NamePackage))
            throw new InvalidOperationException("namePackage");

        IDictionary<Levels, IList<Problem>> problemPackage = this.ProblemDictionaryPackages[properties.NamePackage];

        // does exist the list
        if (!problemPackage.ContainsKey(properties.Difficulty))
            problemPackage.Add(properties.Difficulty, new List<Problem>());

        temp = problemPackage[properties.Difficulty];

        if (temp.Count >= properties.Quantity)
            return temp;
        else
            return GenerateProblems(properties);
    }

    private IEnumerable<Problem> GenerateProblems(ProblemFactoryProperties properties)
    {

        ruleAlgorithmSelector.Rules = ruleDictionaryPackages[properties.NamePackage][properties.Difficulty];

        ...
    }

    public override IEnumerable<Levels> AvailableLevels(string name)
    {
        return ruleDictionaryPackages[name].Keys;
    }
}

Sometimes I guess is difficult to readability. What do you recomend me to to mantain a better readability?

\$\endgroup\$
1
  • 1
    \$\begingroup\$ For readabilitiy I prefer the curly brackets in conditions and loops, one place I saw you could use var. I dont mind the nested IDictionary's, if you did wrap them up in another class would that abstraction yield any benefit in your scenario? \$\endgroup\$
    – Jeremy Thompson
    Jul 30 '12 at 22:56
2
\$\begingroup\$

IDictionary<string, IDictionary<Levels, IList<ProblemRule>>> is difficult to understand and maintain. I don't know enough about your problem domain to give you reasonably sounding names for classes, but I'll try.

In your LoadProblems method, I see you set the IDictionary<Levels, IList<ProblemRule>> to a variable named problemPackage, so I would create a class ProblemPackage, containing a list of ProblemRules per Level (I would drop the 's' in Levels) and move the related logic there.

In ProblemBaseFactory you end up with a IDictionary<string, ProblemPackage>. ProblemPackage will have a IDictionary<Level, ProblemRules> and the class ProblemRules will be an easy wrapper around a IList<ProblemRule>.

If you try to delegate the work to these classes, the readability will almost certainly go up.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.