As far as I can tell, your example closely matches the strong coupling, as it is defined in Wikipedia:
Strong coupling occurs when a dependent class contains a pointer directly to a concrete class which provides the required behavior. The dependency cannot be substituted, or its "signature" changed, without requiring a change to the dependent class. Loose coupling occurs when the dependent class contains a pointer only to an interface, which can then be implemented by one or many concrete classes. The dependent class's dependency is to a "contract" specified by the interface; a defined list of methods and/or properties that implementing classes must provide. Any class that implements the interface can thus satisfy the dependency of a dependent class without having to change the class. This allows for extensibility in software design; a new class implementing an interface can be written to replace a current dependency in some or all situations, without requiring a change to the dependent class; the new and old classes can be interchanged freely. Strong coupling does not allow this...
Let's look at the code from the perspective of above definition:
- check
dependent class contains a pointer directly to a concrete class which provides the required behavior
In your example, dependent class is RegistrationPage
and direct pointer to a concrete class it contains is RegistrationData regData
.
- check
dependency cannot be substituted, or its "signature" changed, without requiring a change to the dependent class
In your example, one would have to change RegistrationPage
in order to use some other source than RegistrationData
class to pass the data to enterFirstName
and other methods.
In layman terms, RegistrationPage
"knows" quite a lot about RegistrationData
- it knows that such a class exists and it knows essential members of this class. This kind coupling is anything but loose.
I assume that I need interface of RegistrationData class to be used in RegistrationPage class. Is not it?
Interface of RegistrationData would make it loosely coupled. As for whether you need it or not, it depends on the context and largely, also on your personal / team preferences. For example as explained in my other answer, I would likely try to avoid having such interface if RegistrationData was a single implementation.
I am indeed asking suggestion for redesign now and please let me know if I need to add more details to question.
This means your original question whether it's loose coupling is solved right? As for redesign, that would be a different question, consider posting it separately.