When to declare methods as private - oop

I am looking for specific and exact rules to determine how a method's visibility can be declared. This is not language agnostic, it applies to the standard OOP languages.

A good rule to follow would be:
Members should not have more accessibility than they need.
Start with private and make them more accessible as the need arises.

Basically:
Public is for when the method must be accessible by an outside class. Something like getState() would fit here.
Private is for when the method should not be accessible by any other class, something like changeState(...). Generally this relates to the actual alteration of an object's contents - maybe you'll have a public setX(int x) that just calls the private setXInternal(int x), that way you can have extra type-checking/safety/etc. To be safe you might as well make everything private until it has to be otherwise.
Protected is basically "public to child classes, private otherwise". Could go either way.

With any class/object there are:
1. things it does (behaviours)
2. how it does them (implementation)
The world cares about the behaviour of your object. It shouldn't (often) care about how it achieves this behaviour under the hood. Keep implementation details private, and expose behaviours.

Any kind of operation which does not define behaviour of particular object directly but is useful during implementation of object's behaviour is a candidate for private member function.

I think the helpfulness of the public, protected and private keywords is just to make the code more clear.
So you would use public for the API of a class, private to make it clear how to do NOT extend a class and protected in every other case.
A common pragmatic approach is never use private and to use just public or protected.

Public for things that are part of the public API.
Protected for non-public functions that you want subclasses to be able to call.
Private if you don't want subclasses mucking around with said method (or to even know of its existence).
In C, C++, and C# don't forgot to mark a method virtual if you want a child class to be able to override it.

Related

VB.Net Public Property

Using code analysis on my program I often get this warning:
CA1051 : Microsoft.Design : Because field 'Form1.Testcode' is visible outside of its declaring type, change its accessibility to private and add a property, with the same accessibility as the field has currently, to provide access to it.
So it tells me to either change the code from this: Public Testcode As String
To this: Public Property Testcode As String
Or to this:
Private _testcode
Public Property Testcode As Object
Get
Return _testcode
End Get
Set(value As Object)
_testcode = value
End Set
End Property
So my question is, what is the difference between the 2 code suggestions.
Is one faster than the other or does it prevent bugs or anything else? I've been using the first code since ever and never had issues with it neither feeling lags or something else.
Saying I want my program to be as fast as possible should I change the Code that I have to the Property code and if yes, which to choose?
The point of properties is that they behave like fields from the outside but like methods from the inside. In fact, once your code is compiled, the getter and setter of your property actually are methods. Java doesn't support properties but even there the convention is to declare a field private and then declare two methods for getting and setting the field value.
Always use properties to expose data publicly. If nothing else, it means that you can bind objects of that type because properties support data-binding while fields do not. It also makes it far less likely that you will need to change the type interface if you need to change the implementation later.
As for how to implement the property, always use an auto-property, i.e. the one-line option, unless you need to add extra code to do things like validation or raise an event. If you write an auto-property, the private field is still created behind the scenes - you can even access it in code - and the compiler still creates the getter and setter methods. In short, prefer this:
Public Property Data As SomeType
to this:
Private _data As SomeType
Public Property Data As SomeType
Get
Return _data
End Get
Set
_data = value
End Set
End Property
An example of a situation that would require the full property is below:
Private _number As Integer
Property Number As Integer
Get
Return _number
End Get
Set
'Validation
If Value < 0 Then
Throw New ArgumentOutOfRangeException("value", $"'Number' must not be less than zero.")
End If
If _number <> Value Then
_number = Value
'Change notification.
OnNumberChanged(EventArgs.Empty)
End If
End Set
End Property
Public Event NumberChanged As EventHandler
Protected Overridable Sub OnNumberChanged(e As EventArgs)
RaiseEvent NumberChanged(Me, e)
End Sub
Is one faster than the other? No.
Does it prevent bugs or anything else? Yep.
In VB, Public Testcode As String and Public Property Testcode As String look pretty much the same. But let's put the syntax aside, we are speaking about member variables and properties here.
Member variables are variables you have to use in your classes when they have to "live" as long as the class instance does. It is basically the same as every other variable but without defined context (say the end of a method for example). You'd use them typically to hold kind of a state like whether the user had confirmed a message or anything like that. If this kind of information is important for the logic of your class but not for others, you have a perfect candidate for a member variable.
Properties are not very different here and can technically be used the same. However they are part of an external interface. If you have to hold information that is important to your class and to other classes (using your class) as well, you have a perfect candidate for a property. This could be the border color of a button for example. Other classes might set the color by a given design and the button itself needs it to render the border accordingly, of course. Public methods and properties build the interface other parties can interact with. There are some useful answers here on StackOverflow, I'll link them below instead of copying their content.
Why should we care?
So we're basically talking about encapsulation and information hiding. But let's look at that in a more practical example.
Look at your desktop PC. Turn it around and take a look at all the connectors it exposes. This is the public interface of the machine. That's what you as a consumer of the machine can interact with. You see USB ports, HDMI connectors and so on. You don't need to know the internals of the machine to understand where you can connect a mouse to or how you can attach your HDMI-to-DisplayPort adapter. In fact, it would be very confusing if every internal connector would be available to you on the backside of your PC. It would add so much unneeded clutter and it would make things dangerous, too. Because you'd have no chance to know what all these pins and connectors are made for. The hardware manufacturers could not rely on expected conditions because anyone might have messed things up unknowingly from the outside.
Everything you as a consumer can interact with is made public with the interface of standard connectors. Everything the machine needs to work internally is kept away from you to avoid confusion about things you don't need to know about and make sure noone messes with the internal state the machine has to rely on.
So you could say "lets do everything public because I have no secrets" but in fact that would make the class very hard to understand from the outside. It would make it easy to break things unknowingly by setting members from external code which your class handles internally and has to rely on.
Another aspect we as software developers have to keep in mind: Maintainability. If you have a lot of public members, you are pretty locked when doing refactoring because you'll never know how anyone out there is using them. Keeping a clean interface to the outside is important to be able to change things internally later on.
See:
Internal applications - why not make everything public?
Why shouldn't I be using public variables in my Java class?
See Auto-Implemented Properties:
When you write code for an auto-implemented property, the Visual Basic
compiler automatically creates a private field to store the property
variable in addition to creating the associated Get and Set
procedures.
So using the shorthand notation:
Public Property Testcode As String
Results in the same code as the longer verbose property, WHEN YOU COMPILE.
There is no difference in the end.

Can I change a private methods visibility in order to unit test them

I see in this answer that for Java you can set the visibility of a private method to "true" in a unit test in order to test the method. Is there something like this available for VBA, so that I can unit test private methods using RD-VBA?
If not, and I have a class that works out some logic in three private methods and give it back to a return value, am I doomed to only give a input value and test the return value, without being able to test the three private methods doing the heave lifting in between?
You shouldn't need to write tests for private methods, regardless of the language. You test your public API, what's private is implementation detail that isn't relevant.
If it is relevant and important enough to be tested on its own, then you should extract that private method to another class, and expose it as a public member of that class.
For example once I had a form and I wanted to limit user input in a textbox to numeric characters, and since I'm reusing that logic elsewhere then instead of treating it as an implementation detail of my form, I extracted a AsciiInputValidator class, and its public IsValidNumericValue method could be tested in every possible way as its own SUT.
Don't test private methods: the public ones invoke them anyway.
Unfortunately the Extract Class refactoring feature is not implemented as of this writing, so for now Rubberduck can't do this automatically for you... but it's definitely in-scope and if you're reading this and you're up for a bit of a C# metaprogramming challenge, go for it, pull requests are always welcome!
Can you add a public wrapper like
public sub testPrivateSub(param1,param2...)
PrivateSub(param1,param2....)
end sub
private sub PrivateSub(param1,param2....)
....
end sub

Does this Public Method Which Calls a Private Method Contain Unnecessary Redundancy?

Let's say I have a public method as shown below:
public void startService(int intParam1, int intParam2, boolean booleanParam) {
setupService(intParam1, intParam2, booleanParam); // call private method to perform prerequisites
// perform remaining logic to start service here
}
This method has a call to a private method inside the same class which has the same interface as the public method which calls it. The public startService() method is the only consumer of the private setupService() method.
Would it have been a better idea to just get rid of the private setupService() method call and just replace it with setupService()'s implementation? In this case it appears there is some redundancy that may be unnecessary but I'd like to get some professional opinions. I've run into this several times in my career but usually looked the other way in fear of breaking something.
I've encountered this often too.
I ask myself:
Is the private function doing too many things that could be further broken up into functions? If so, then I would much rather get rid of the single private function and call the smaller functions from within the public function. This makes the code more readable because you can at once glance see what the public method is doing. This goes well towards making code self-documenting too.
Is there a possiblity of a future use-case where that single private function might be used again? If not, then it is not needed to be made private at the moment. However, it can get difficult in the future if a part of the code in your public function has to be used by other functions (more testing during the transition).
All in all, it comes down to having optimal modularity in your functions. If the private function cannot be further broken down into independent functions, then I would just get rid of it and put its code as is in the public method.

Sharing variable data between forms other than a Global Variable Class in Win Forms vb.net application

Currently in a Win Form application, im using a Global Variable Class which contains variables that are used to to share data. My question is, what other ways are there to achieve this? Best practises? and why?
Globals are bad for many reasons, but probably the most glaring reason is because, ideally speaking, every time you call the same method, passing it the same parameters, it should always do the same thing with the same results. Globals brake that rule. Suddenly your code starts behaving in unpredictable ways because something wasn't initialized properly somewhere else, or some global got modified incorrectly.
The best way I've found to get rid of the need for globals is to adhere to the principles of dependency injection (DI). There is much material on the topic online, but in a nutshell, rather than having classes reach out to create or find their dependencies on their own, they should simply request that the dependencies be provided to them, often in the constructor. Anything that you are accessing via global variables would, by definition, be considered dependencies of the classes that access them. Therefore, instead of, for instance, having a global settings object, like this:
Global settings As New Settings()
And then a class that uses it like this:
Public Class MyClass
Public Sub DoSomething()
If settings.SomethingEnabled Then
' ...
End If
End Sub
End Class
You would instead, do it like this:
Public Class MyClass
Public Sub New(settings As Settings)
_settings = settings
End Sub
Private _settings As Settings
Public Sub DoSomething()
If _settings.SomethingEnabled Then
' ...
End If
End Sub
End Class
This makes your code much cleaner, more flexible, and more reliable. It also makes the code far more testable too, which is a great added benefit.
Data should be shared according to how it is going to be used. If a variable is required across the entire application then it can be seen to have global scope and a global variable concept (e.g. public static shared) may well be appropriate.
Often this is not the case however as global variables should really be avoided (check out here and here for more reasoning)
Data should be encapsulated at the level it is required - for example if a form has data / variables within it that are applicable to it's function but where other forms need to now the value, this would be the ideal case for a public readonly property on the form, which would mask the actual detail of the variable from the rest of the aplication.

Testing private methods, clarification needed

In my src, there exist a class which contains a method
public static boolean doExtensionsMatch(String s, String t) {
There is nothing wrong with it, except that there is no need for it to be public. It is used inside the class where it is declared.
It is public however, since some time ago, i felt this method needed to be tested directly and thus, private visibility did not work for me.
At this point:
I'd rather not throw away those tests. If i make the method private however, tests will become unusable.
I would rather for tests to remain in it's current src-test folder, thus maintaining separate locations for source and tests
So, you tell me, what should i do?
Should i change the method to private and delete the tests?
You test interface to prove that class behaves as it should.
So private methods don't need to be tested as long as they aren't accessible. And even more - you shouldn't care of how interface does its work, you should be fine with just the results.
You test the behaviour, not the implementation.
I would suggest using partial classes. If your test classes are partial classes of the class to be tested they will have access to all methods and variables whether or not they are public.