I find myself often adding more and more methods to a specific class, is this class heading in an unmaintainable direction? Or is this class fine even if it has 50 or more methods?
let's call the class PowerSource182
, it handles the details of creating commands that are sent to a "PowerSource182" power supply (an external device), allowing for the rest of the code to simply call myPowerSource.Operate()
. This piece of equipment has hundreds of commands, and I only implement a subset of these commands, but have needed to expand the subset repeatability as commands become needed.
Each addition is still cohesive to the class's intended scope of responsibility, further more they are so cohesive I don't see it reasonable to separate them into smaller groups.
Here is a example of what PowerSource182
looks like, here I use a IInstrument
which is a class that simple handles write, read, and query commands to a serial port, gpib, or some other communication protocol.
public class PowerSource182
{
IInstrument _instrument;
public PowerSource(IInstrument instrument)
{
_instrument = instrument;
Reset();
}
public void Reset()
{
_instrument.Command("*RST");
}
public void StandBy()
{
_instrument.Command("STBY");
}
public void Operate()
{
_instrument.Command("OPER");
}
public string GetFaults()
{
return _instrument.Query("FAULTS?");
}
public enum InternalConstant
{
L1S = 1,
L2S = 2,
L3S = 3,
L4S = 4,
L5S = 5,
L6S = 6,
}
public void SetInternalConstant(InternalConstant internalConstant, double value)
{
_instrument.Command($"seticon {internalConstant.ToString()}, {value}");
}
public enum Function
{
VOLTS = 0,
AMPS = 1,
}
public void SetOutput(Function func, double value, double frequency = 0)
{
string funcString = funcString.First().ToString();
_instrument.Command($"OUT {value} {funcString}, {frequency} HZ");
}
public enum Events
{
OPC = 1,
TEX = 2,
LOP = 4,
DFT = 8,
PMW = 16,
}
public bool GetEventStatusRegister(Events e)
{
int mask = (int)e;
int eventStatusRegister = int.Parse(_instrument.Query("*ESR?"));
bool result = (eventStatusRegister & mask) == mask;
return result;
}
}
This example is not the actual source, but I hope it illustrates the problem.
2 Answers 2
If by adding new methods you mean to add new responsibilities to the class then you might consider using the Chain of Responsibility Pattern.
But if adding new methods is simply a matter of updates then you might use partial classes to divide your class into smaller chunks of code for improved readability.
This is opinion-based, and you could break up the class with other classes, but you shouldn't really get hung-up on number of lines of code. What you should focus on is using the "Don't repeat yourself" (DRY) principle, and keeping this to a single responsibility. If that still results in a lot of code per class, then it's just the nature of the beast.
///<summary>... (see page X of Y manual)
.GetFaults()
at any point? Can I callReset()
before callingOperate()
?