Doubt about how to organize my classes

2019-05-04 02:29发布

问题:

Here is only an example from my code. I'm looking for a good way to maintain my classes in order and following some OOP rules.

This my abstract class Problem:

public abstract class Problem<T> : IEquatable<T>
{
    public abstract int ResultCount { get; }
    protected abstract bool CheckTheAnswer(params object[] results);
    public abstract bool Equals(T other);
}

Below is one class which derives from Problem, Arithetic class contains all the necessary that contains in a math problem, and how to resolve it:

public enum Operations
{
    Addition, Subtraction, Multiplication, Division
}

public class Arithmetic : Problem<Arithmetic>
{
    public decimal Number1
    {
        get;
        set;
    }

    public Operations Operation
    {
        get;
        set;
    }

    public decimal Number2
    {
        get;
        set;
    }

    public override int ResultCount
    {
        get { return 1; }
    }

    protected override bool CheckTheAnswer(params object[] results)
    {
        if (results.Length != ResultCount)
            throw new ArgumentException("Only expected " + ResultCount + " arguments.");

        decimal result = (decimal)results[0];

        switch (Operation)
        {
            case Operations.Addition:
                return Number1 + Number2 == result;
            case Operations.Subtraction:
                return Number1 - Number2 == result;
            case Operations.Multiplication:
                return Number1 * Number2 == result;
            case Operations.Division:
                return Number1 / Number2 == result;
            default:
                throw new Exception("Operator unexpected");
        }
    }

    public override bool Equals(Arithmetic other)
    {
        if (other == null)
            return false;

        return this.Number1 == other.Number1 && Number2 == other.Number2;
    }
}

public class Addition : Arithmetic
{
    public Addition(decimal addend1, decimal addend2)
        : base()
    {
        Number1 = addend1;
        Number2 = addend2;
        Operation = Operations.Addition;
    }
}

// Subtraction, Multiplication and Divison here

Then I have another class which generate an Arithmetic problem, it receives a Tuple where contains some properties that indicates the conditions

interface IProblemFactory<T> where T : Problem<T>
{
    T Create();
}

public class ArithmeticProblemFactory : IProblemFactory<Arithmetic>
{
    private Tuple<Operations, Range, Range> _condition;

    public ArithmeticProblemFactory(Tuple<Operations, Range, Range> condition)
    {
        this._condition = condition;
    }

    public Arithmetic Create()
    {
        Operations operation = _condition.Item1;
        decimal a = _condition.Item2.GetNumber();
        decimal b = _condition.Item3.GetNumber();

        switch (operation)
        {
            case Operations.Addition:
                return new Addition(a, b);
            case Operations.Subtraction:
                return new Subtraction(a, b);
            case Operations.Multiplication:
                return new Multiplication(a, b);
            case Operations.Division:
                return new Division(a, b);
            default:
                throw new Exception("Operator unexpected");
        }
    }
}

The thing is... I need to have more properties, like Result (in Arithmetic class only needs 1, in comparison 2 numbers we need two properties result), problem number, time (seconds) to resolve the problem.

The question is, I don't know where I should put these properties. One way it'll be adding some of them in Problem class, or create another class something like these:

ArithmeticProblem

  • Problem Problem <-- Here is Arithmetic class

  • Result

  • Time

  • Problem number

I only want to organize my classes as must be. Thanks in advance.

回答1:

You can have different classes for result and in your Arithmetic class accept result type as generic:

public class Arithmetic < TResult> : ...

and Addition can be as bellow:

public class Addition : Arithmetic <decimal>
...

but if the number of parameters (like result, time, ...) are not fixed (dynamic) you can have a dictionary and store them in dictionary (their type) and write specific action and set them as value of dictionary.



回答2:

I would suggest placing the Result, Time (to generate or solve), and Problem Number all inside the problem class. Each problem will have its own result, time, and number; they may as well be included. This relieves you of linking another class to each problem as well as having an all-inclusive problem class.



标签: c# oop