简体   繁体   中英

Calling a data member's setter in its getter

This question is kind of linked to this other question I asked in this forum.

Here is what I am trying to accomplish. I have the following class:

public class LoginPage
{
    // Class Data
    private HtmlForm loginForm;

    // Calling the constructor of the parent class
    public LoginPage()
    {
        loginForm = null;
    }

    public void setLoginForm()
    {
        ...... logic to find the login form ........
    }

    public HtmlForm getLoginForm()
    {
        return loginForm;
    }

    ...... other login related methods ........
}

I want to ensure that every time a getLoginForm() method is called it should not return null. One way to do this is to ensure setLoginForm() is called before the getLoginForm() method is called.

Can i call the setter of a data member within its getter method. In this case:

    public HtmlForm getLoginForm()
    {
        setLoginForm()
        return loginForm;
    }

I have never seen some thing like this being practiced. Is this valid ? What are the merits and demerits of doing this ?

Appreciate your comments / suggestions !!!!

The usual pattern for this would be something like:

public class LoginPage {

    // Class Data
    private HtmlForm loginForm;

    // Calling the constructor of the parent class
    public LoginPage() {
        loginForm = null;
    }

    // Normal setter - NB: Private - so I am in complete control.
    private void setLoginForm(HtmlForm loginForm) {
        this.loginForm = loginForm;
    }

    private void initialiseLoginForm() {
        if ( loginForm == null ) {
            // Build a loginForm and use the private setter to set it.
            // NB: In a multi-threaded environment you would normally use some kind of synchronization.
            HtmlForm newForm;
            // ...
            setLoginForm(newForm);
        }
    }

    // Normal getter
    public HtmlForm getLoginForm() {
        initialiseLoginForm();
        return loginForm;
    }

}

This creates the form late and disallows users from modifying it. Note that I have used the correct signature for a setter which is usually setXxx(T it) .

Is it "valid"? Sure.

Is it a good idea? Hard to say–depends on the situation.

It's basically a "lazy" getter; if the object hasn't been initialized, make sure it is, then return it.

Unrelated but I'd argue the method is mis-named and should instead reflect something closer to what it's doing, eg, initLoginForm , findLoginForm , etc.

Technically it is valid, and as far as if it's useful, it depends on the situation... it could be useful to save some memory resources but you should make a small yet possibly very efficient change... (see bellow)

I want to ensure that every time a getLoginForm() method is called it should not return null.

First of all, you should probably rename the setLoginForm() method to something like initLoginForm() . The reason is that setLoginForm() isn't really a setter and it serves to initialize the resources of the login form.

A setter would look like this:

    public void setLoginForm(HtmlForm loginForm) {
       this.loginForm = loginForm; // set the login form
    }

Right now, the way you have it is you call setLoginForm() each time you call getLoginForm() which is unnecessary. What you want is to instantiate the LoginForm only if it is null before returning it (this is called lazy initialization ).

Lazy initializations means that we don't create objects until the first time we need them. It is useful memory conservation technique because it refrains from creating certain resources until the resource is first needed -- freeing valuable memory space. It is especially useful when object initialization is expensive.

So you make your getter be "lazy":

    public HtmlForm getLoginForm() {
        if(loginForm == null) { //first call to this method.
            loginForm = new HtmlForm();
        }
        return loginForm;
    }

The == null check should be the changed to however in your system design you would check " Is loginForm instantiated ".

I guess more general, your code could look like:

    public HtmlForm getLoginForm() {
        if(!isLoginFormInitialized()) { //initialize the login form if it isn't initialized
            initLoginForm();
        }
        return loginForm;
    }

This way you are still making sure your loginForm is initialized but you are not wasting resources by recreating it each time.

NOTE: Since you didn't provide any specifications of your underlying system and how you setup the login form, do you allow null values, what design patterns you might be using etc. I just provided a general answer to what seems like you are asking. Hopefully it helps :)

sure you could do it, but its not a goog idea.

in general, a nice Application would be designed under the MVC Concept:

MVC: Model-View-Controller

Model : your Objects like User(attributes and Getter + Setter), Product, Category,...etc. getter and Setters shouldn't have any Logic, just setting or getting values.

View : your GUI

Controller : ManagedBeans that do logics, calculating, DataBase, ....etc.

if you want to check AND / OR init any values, then do this in the Controller not in the Model!

Usually, a setter Method needs a paramater to set the value:

public void setData(DataType data ){
   this.data = data;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM