在getter中调用数据成员的setter

时间:2014-09-23 14:59:57

标签: java

这个问题与我在这个论坛上提到的其他question有关。

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

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

我从未见过这样的事情。 这有效吗?这样做有什么优点和缺点?

感谢您的意见/建议!!!!

4 个答案:

答案 0 :(得分:4)

通常的模式是:

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

}

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

答案 1 :(得分:1)

它是否有效"?肯定。

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

它基本上是一个"懒惰"吸气;如果对象尚未初始化,请确保它已经初始化,然后将其返回。

不相关,但我认为该方法的名称错误,应反映出与其正在做的事情更接近的事情,例如initLoginFormfindLoginForm等。

答案 2 :(得分:1)

从技术上讲它是有效的,并且只要它有用,它取决于具体情况......保存一些内存资源可能很有用,但你应该做一个小但可能非常有效的改变。 (见下文)

  

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

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

setter看起来像这样:

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

现在,您拥有它的方式是每次拨打setLoginForm()时都拨打getLoginForm(),这是不必要的。你想要的只是在LoginForm null之前实例化 public HtmlForm getLoginForm() { if(loginForm == null) { //first call to this method. loginForm = new HtmlForm(); } return loginForm; } 才能返回它(这称为lazy initialization)。

延迟初始化意味着我们不会在第一次需要时创建对象。 它是有用的内存保护技术,因为它在首次需要资源之前不会创建某些资源 - 释放宝贵的内存空间。当对象初始化很昂贵时,它特别有用。

所以你让你的傻瓜变得懒惰":

== null

public HtmlForm getLoginForm() { if(!isLoginFormInitialized()) { //initialize the login form if it isn't initialized initLoginForm(); } return loginForm; } 检查应该更改为,但是在您的系统设计中,您需要检查" 是否实例化loginForm "。

我想更一般,你的代码看起来像:

loginForm

通过这种方式,您仍然可以确保null已初始化,但每次都不会通过重新创建来浪费资源。

注意:由于您没有提供基础系统的任何规范以及如何设置登录表单,您是否允许{{1}}值,您可能采用哪种设计模式使用等我只是提供了一个似乎你要问的一般答案。希望它有所帮助:)

答案 3 :(得分:0)

确定你能做到,但这不是一个goog的想法。

一般来说,一个不错的应用程序将在 MVC 概念下设计:

MVC:模型 - 视图 - 控制器

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

查看:您的GUI

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

如果你想检查和/或初始化任何值,那么在Controller中不在模型中执行此操作!

通常,setter方法需要一个参数来设置值:

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