The fact that your methods return void lead me to believe that you may have your responsibilities turned around. I think it may be better to think about this as having each of your classes implement an interface, IProcessable
, that defines a Process
method. Then each class would know how to manipulate it's own data. This, I think, is less coupled than having a class which manipulates data inside each object. Assuming all of theses classes derive from the same base class you could put the pieces of the processing algorithm that are shared in the base class.
This is slightly different than the case where you may have multiple algorithms that operate on identical data. If you need this sort of functionality then you may still want to implement the interface, but have the Process
method take a strategy type parameter and use a factory to create an appropriate strategy based on its type. You'd end up having a strategy class for each supported algorithm and data class pair this way, but you'd be able keep the code decoupled. I'd probably only do this if the algorithms were reasonably complex so that separating the code makes it more readable. If it's just a few lines that are different, using the switch statement on the strategy type would probably suffice.
With regard to web methods, I think I'd have a different signature per class. Getting the data across the wire correctly will be much easier if the methods take concrete classes of the individual types so it knows how to serialize/deserialize it properly. Of course, on the back end the web methods could use the approach described above.
public interface IProcessable
{
public void Process() {....}
}
public abstract class ProcessableBase : IProcessable
{
public virtual void Process()
{
... standard processing code...
}
}
public class FooProcessable : ProcessableBase
{
public override void Process()
{
base.Process();
... specific processing code
}
}
...
IProcessable foo = new FooProcessable();
foo.Process();
Implementing the strategy-based mechanism is a little more complex.
Web interface, using data access objects
[WebService]
public class ProcessingWebService
{
public void ProcessFoo( FooDataObject foo )
{
// you'd need a constructor to convert the DAO
// to a Processable object.
IProcessable fooProc = new FooProcessable( foo );
fooProc.Process();
}
}