Reputation: 3239
I would like to use nested classes for a "developing state":
public class WebSvcClient : IDisposable
{
//
// 10 private fields required by all methods
...
public Profile Profile { get; private set; }
public void Authenticate()
{
this.Profile = new Profile();
}
public class Profile
{
// public methods that do require authentication
...
}
// public methods that don't require authentication
...
}
I can see several benefits:
Profile
makes sense only in the context of WebSvcClient
IDisposable
unitProfile
But is it considered good practice?
Upvotes: 1
Views: 95
Reputation: 7625
Consider using interfaces that represent state, and methods that can transition from one state to another:
public interface INew {
// transition to initialized state
IInitialized Init();
}
and
public interface IInitialized {
// connect to get a connected object
IConnected Connect(string connection);
}
and
public interface IConnected {
// disconnect reverts back in state
IInitialized Disconnect();
// methods only available when connected
bool GetValue(string name);
void SetValue(string name, bool value);
}
Etc..
You can implement these interfaces on a common class, or use a different class for every state. You will need some kind of factory to create the initial instance.
This works well when you are in full control of the actual state (no unexpected disconnect etc..).
This way you are telling the users of your API what they need to do, in what order, to get access to the desired methods. You can use 'fluent' code to use this:
var newMachine = Factory.NewMachine();
var connected = newMachine
.Init()
.Connect(connectionString);
connected.GetValue("test");
...
connected.Disconnect();
Upvotes: 1
Reputation: 273264
I don't think there's any gain here.
- Encapsulation, Profile makes sense only in the context of WebSvcClient
But using private fields in another class, even when it's nested, breaks encapsulation.
- Single IDisposable unit
It causes more problems then it solves here. What if other code keeps a Profile around after the Service was disposed?
- Lack of need for 3rd class just to pass the private fields to Profile
Ok, maybe. That class would have been messy anyway.
- No pollution of namespace
That's not really an issue anyway.
As an alternative, use two interfaces, or at least one for the Profile part. Implement the relevant members explicit so that they are only available through an IProfile
reference.
This can be circumvented with casting, but if that's a problem you should speak with your team. It would matter for a library, but it shouldn't for an Application.
Upvotes: 1
Reputation: 511
There are no benefits:
Upvotes: 1