How do you clear instance variables of inherited instances?

I worked with some abstract classes, and feels something, but I'm not sure what to do with it. Here is a simple example to explain my question:

public abstract class Data { protected Boolean _Connected = false; public abstract void Connect(); public abstract void Disconnect(); public Boolean Connected { get { return _Connected; } } } public class SqlServerData : Data { public override void Connect() { // code to connect to sql server _Connected = true; } public override void Disconnect() { if (_Connected) { // code to disconnect from sql server _Connected = false; } } } 

I have a couple of design issues.

  • Nothing in this project forces the new Data implementation to do anything with the instance variable _connected. If other classes using the Data class rely on the Connected property, this may be inaccurate.

  • This may confuse someone new to this code. This example is pretty simple, but if there are more instance variables in the abstract class and other instance variables in the SqlServerData class, it will be harder to know where the variables are defined.

So my question is, should it be reorganized, and if so, how?

+4
source share
3 answers

Implement a state machine (connected or not connected and transitions between these states) in the base class, so the derived class does not need to worry about this part. Provide protected methods for the actual functionality, so the derived class can easily fill the "holes":

 public abstract class Data { private bool connected; public bool Connected { get { return connected; } } public void Connect() { OnConnect(); connected = true; } public void Disconnect() { if (connected) { OnDisconnect(); connected = false; } } protected virtual void OnConnect() { } protected virtual void OnDisconnect() { } } 

and

 public class SqlServerData : Data { protected override void OnConnect() { // code to connect to sql server } protected override void OnDisconnect() { // code to disconnect from sql server } } 
+6
source

The problem is that you want the logic to control the _connected flag, which should be common to all subclasses, but at the same time retain the ability of each subclass to provide its own implementation of what happens when you actually call Connect () and disconnect ( ) For this, I would recommend what is called the Template method template , so that the abstract base class can still retain some control over the logic used in the method. The way this works is pretty simple, just structure your class like this:

 public void Connect() { if(!_connected) { ExecuteConnect(); _connected = true; } } public void Disconnect() { if(_connected) { ExecuteDisconnect(); _connected = false; } } protected abstract void ExecuteConnect(); protected abstract void ExecuteDisconnect(); 

Now in the base classes, you can override the Execute * methods (I'm sure the naming convention can be improved) so that you can provide new implementations for connecting and disconnecting, while maintaining control over the general algorithm.

+3
source

I would prefer to make the Connected property abstract and omit the protected field.

The disadvantage of protected fields is that the base and children must use it in a coordinated manner, thereby holding them together stronger.

But having a protected field can save you a few simple lines of code. It depends on the real problem, but usually I would prefer to write a few more lines of code and then enter the link.

0
source

Source: https://habr.com/ru/post/1391886/


All Articles