Reputation: 7278
I would like to have an interface for a problem called IProblem
. With two methods: Solve() and CheckArguments(). The Problem
class will implement the CheckArguments() function because it will be the same for all the problems. But then I have different types of problems like EasyProblem
and HardProblem
that have different implementations of Solve() method but the CheckArguments() method always be the same and I always want to use the base class Problem()'s implementation.
I would like to have correct modifiers and I'm a bit confused on which method being defined in which class/interface. Not to mention I also have a test project for both these functions.
Upvotes: 0
Views: 109
Reputation: 22436
The class structure has been shown by Matten very well.
As regards access modifiers: I'd propose a defensive approach, so that you use the most restrictive access modifier that solves the problem. It is easier to be less restrictive afterwards than to be more restrictive as you might have to explain to some users of your code why they cannot use it anymore.
So for the types (interface and classes): if you don't need them in other assemblies, rather define them as internal. If you want to access the types from your test project, you can use the InternalsVisibleTo attribute to be able to access them from specific assemblies. You add the attribute to the assembly containing the types and provide the name (and for strong named assemblies some additional data) of the test assembly as a parameter.
The same applies to the members. You can also think about implementing the interface explicitly, so you can access the methods only if you access the class via the interface.
Upvotes: 0
Reputation: 62248
You can try something like:
public interface ISupportArguments
{
bool CheckArguments();
}
public abstract class AbstractProblem : ISupportArguments
{
public bool CheckArguments() {
return true;
}
public abstract void SolveProblem();
}
so every your class derives from AbstractProblem
and override it's own version of
SolveProblem(..)
Upvotes: 3
Reputation: 17621
I'm not sure if your question is "what to use", but I'd suggest an interface and an abstract class:
public interface IProblem {
void Solve();
void CheckArguments();
}
public abstract class Problem : IProblem {
public abstract void Solve();
public void CheckArguments() {
...
}
}
public class EasyProblem : Problem
{
public override void Solve()
{
....
}
}
This way, check arguments is implemented in the base class, all derived classes implement IProblem and every derived class must implement Solve.
If you leave out the interface and only support classes which derive from Problem
, you'll make sure that a given class can't give it's own implementation of CheckArguments()
.
public abstract class Problem {
public abstract void Solve();
public void CheckArguments() {
...
}
}
public class EasyProblem : Problem
{
public override void Solve()
{
....
}
}
...
static Main(string[] args)
{
List<Problem> problemsToSolve = ...
foreach(var problem in problemsToSolve)
{
problem.CheckArguments();
problem.Solve();
}
}
Upvotes: 3