公共静态工厂方法

2022-09-02 10:32:21

首先,如果这是一个非常愚蠢的问题,请原谅我,我只是想学习这门语言的核心。我正在阅读有效的Java,第一章讨论了静态工厂方法与构造函数。他们的优点和缺点。令我感到困惑的是:

  1. 静态工厂方法返回的对象的类是非公共的 - 它到底是什么意思?
  2. 与构造函数不同,静态工厂方法不需要在每次调用时都创建新对象 - 这是如何发生的?我调用工厂方法只是为了获取一个新对象,我们是否放置了一个检查工厂方法来检查对象是否已经存在?

谢谢。


答案 1

静态工厂方法返回的对象的类是非公共的 - 它到底是什么意思?

这意味着静态工厂方法返回的对象的实际类可以是声明类型的子类,并且此子类不必是公共的。这只是客户端代码不应关注的另一个实现细节。

与构造函数不同,静态工厂方法不需要在每次调用它们>创建新对象 - 这是如何发生的?我调用工厂方法只是为了获取一个新对象,我们是否放置了一个检查工厂方法来检查对象是否已经存在?

是的,这是可以做到这一点的一种方式。但实际上,一切皆有可能。


答案 2

首先,感谢您在Java-lit中的选择:布洛赫的书是一本出色的入门书。

为了回答你的第二个问题(“与构造函数不同,静态工厂方法不需要在每次调用时都创建新对象”),重要的是要意识到Bloch在这里说的是,对于静态工厂,你可以选择:返回一个新对象或返回一个预先存在的对象。这完全取决于你想做什么。

例如,假设您有一个非常简单的值类 Money 类型。静态工厂方法可能应该返回一个新实例,即具有特定货币值的新对象。所以,像这样:

public class Money { 

    private Money(String amount) { ... } /* Note the 'private'-constructor */

    public static Money newInstance(String amount) {
        return new Money(amount);
    }

}

但是,假设您有一些对象来管理某些资源,并且您希望通过某个 ResourceManager 类同步对该资源的访问。在这种情况下,您可能希望静态工厂方法将自身的相同实例返回给每个人 - 强制每个人经历相同的实例,以便该1个实例可以控制该过程。这遵循单例模式。像这样:

public ResourceManager {

    private final static ResourceManager me = new ResourceManager();

    private ResourceManager() { ... } /* Note the 'private'-constructor */

    public static ResourceManager getSingleton() {
        return ResourceManager.me;
    }
}

上述方法强制您的用户只能使用单个实例,从而允许您精确控制谁(以及何时)有权访问您正在管理的任何内容。


要回答你的第一个问题,请考虑以下(诚然,这不是最好的例子,它非常特别):

public class Money {

    private Money(String amount) { ... }


    public static Money getLocalizedMoney( MoneyType localizedMoneyType, String amount ) { 
        switch( localizedMoneyType ) {
            case MoneyType.US:
                return new Money_US( amount );
            case MoneyType.BR:
                return new Money_BR( amount );
            default:
                return new Money_US( amount );
        }
    }
}

public class Money_US extends Money { ... }

public class Money_BR extends Money { ... }

请注意我现在如何执行此操作:

Money money = Money.getLocalizedMoney( user_selected_money_type );
saveLocalizedMoney( money );

同样,这是一个非常人为的例子,但希望它能帮助你或多或少地看到布洛赫在这一点上得到了什么。

其他答案都很好 - 我只是认为,作为一个初学者,有时看到一些实际的代码会有所帮助。


推荐