Class design: clearing state
I am designing a class library which will be used like this:
Engine eng = new Engine();
eng.AddPart(part).AddPart(otherPart).Run();
The problem with the class is that the parts are kept by the engine so if you want Run
it with some other parts you will need to remove the ones that you have already added. There are several possible solutions but I am not sure which one is the best.
1.
Ignore it in class library, the users will call new
every time they need to discard old parts.
2.
Automatically discard parts when Run
is called
3.
Add Clear
method
4.
Instead of returning current object from the AddPart
method (return this
) return new instance of Engine
and do not modify the current one.
5.
Implement IDisposable
so that the user can wrap it in using statement even though no resources are hold that need to be disposed. Users will use it like this:
Engine eng = new Engine();
using(eng)
{
eng.AddPart(part).Run();
}
The disadvantage of the second one is that it users might need to reuse the same one and will not expect that parts are cleared. The third one is nice but users might forget to call Clear
method. The fourth option will allocate many inst开发者_如何学运维ances and the fifth one is unintuitive.
Any suggestions?
The Clear()
method is the most appropriate choice here; either that, or just require that the user create a new Engine
. Clear()
makes the behavior of your library most obvious.
You could also consider overloading the Run()
method to accept one or several Parts. This version of Run()
would simply execute the parts, not hold onto them.
IMO you should add a Clear
method to make the interface complete.
However, to me it doesn't sound very logical that the same engine object be reused with different configurations. I think that if a client wants a different engine, he should create a separate engine instance.
This could in fact be turned into a Builder.
You could have a remove method that takes a part as a parameter and only remove that part from the engine. Implementing IComparable on each part.
Engine eng = new Engine();
eng.AddPart(part).AddPart(otherPart).Run();
should be the same as:
Engine eng = new Engine();
eng.AddPart(part);
eng.AddPart(otherPart);
eng.Run();
Run() shouldn't do any other thing, and perhaps this class could handle concurrency as well.
So, I think first is the best.
精彩评论