繁体   English   中英

在其getter中调用数据成员的setter

[英]Calling a data member's setter in its getter

这个问题有点类似于我在这个论坛上问的另一个问题

这是我要完成的工作。 我有以下课程:

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 ........
}

我想确保每次调用getLoginForm()方法时都不应返回null。 一种方法是确保在调用getLoginForm()方法之前调用setLoginForm()。

我可以在其getter方法中调用数据成员的setter吗? 在这种情况下:

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

我从未见过像这样的事情正在被实践。 这有效吗? 这样做的优点和缺点是什么?

感谢您的意见/建议!

通常的模式如下:

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;
    }

}

这会延迟创建表单,并禁止用户对其进行修改。 请注意,我为setter使用了正确的签名,通常是setXxx(T it)

是否有效? 当然。

这是个好主意吗? 很难说-取决于情况。

基本上,这是一个“懒惰”的吸气剂。 如果对象尚未初始化,请确保已初始化,然后将其返回。

无关,但我认为该方法的名称不正确,应该反映出更接近其功能的内容,例如initLoginFormfindLoginForm等。

从技术上讲,它是有效的,并且它是否有用,取决于情况……节省一些内存资源可能很有用,但是您应该做一个很小但可能非常有效的更改……(请参见下面的内容)

我想确保每次调用getLoginForm()方法时都不应返回null。

首先,您可能应该将setLoginForm()方法重命名为initLoginForm() 原因是setLoginForm()实际上不是设置方法,它用于初始化登录表单的资源。

设置员看起来像这样:

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

现在,你有它的方式就是你所谓setLoginForm()每次调用getLoginForm()这是不必要的。 您想要的是在返回LoginForm之前将其初始化 null ,以实例化LoginForm (这称为延迟初始化 )。

延迟初始化意味着我们直到第一次需要它们时才创建对象。 它是有用的内存保留技术,因为它避免了创建某些资源直到首次需要该资源时,从而释放了宝贵的内存空间。 当对象初始化非常昂贵时,它特别有用。

因此,您可以使自己的getter变得“懒惰”:

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

== null检查应该更改为,但是在您的系统设计中,您将检查“ Is LoginForm已实例化 ”。

我想更一般地说,您的代码可能如下所示:

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

这样,您仍然可以确保您的loginForm已初始化,但不会通过每次重新创建来浪费资源。

注意:由于您没有提供有关基础系统的任何规范以及如何设置登录表单,因此您是否允许null值,您可能使用的设计模式等。我只是对您所询问的内容提供了一个一般性的答案。 。 希望它会有所帮助:)

确定您可以做到,但这绝不是好主意。

通常,将在MVC概念下设计一个不错的应用程序:

MVC:模型-视图-控制器

模型 :您的对象,例如用户(属性和Getter + Setter),产品,类别等。 getter和Setters不应具有任何逻辑,而只能设置或获取值。

查看 :您的GUI

控制器 :执行逻辑,计算,数据库等的ManagedBean。

如果要检查AND / OR初始化任何值,请在Controller中而不是在Model中执行!

通常,setter方法需要使用参数来设置值:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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