Во-первых, спасибо за ваш выбор в Java-lit: книга Блоха — отличный учебник для начинающих.
Чтобы ответить на ваш второй вопрос («в отличие от конструкторов, статические фабричные методы не обязаны создавать новый объект каждый раз, когда они вызываются»), важно понимать, что здесь Блох говорит, что со статической фабрикой у вас есть вариант: возврат нового объекта или возврат ранее существовавшего. Все зависит от того, что вы хотите сделать.
Например, предположим, что у вас есть действительно простой класс значений типа Money. Ваш статический фабричный метод, вероятно, должен возвращать новый экземпляр, то есть новый объект с определенным значением Money. Ну вот так:
public class Money {
private Money(String amount) { ... } /* Note the 'private'-constructor */
public static Money newInstance(String amount) {
return new Money(amount);
}
}
Но допустим, у вас есть какой-то объект, который управляет каким-то ресурсом, и вы хотите синхронизировать доступ к этому ресурсу через какой-то класс ResourceManager. В этом случае вы, вероятно, захотите, чтобы ваш статический фабричный метод возвращал всем один и тот же экземпляр самого себя, заставляя всех проходить через один и тот же экземпляр, чтобы этот 1 экземпляр мог контролировать процесс. Это соответствует шаблону singleton. Что-то вроде этого:
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 );
Опять же, действительно надуманный пример, но, надеюсь, он поможет вам более или менее увидеть, к чему Блох пришел с этой точки зрения.
Другие ответы были хорошими - я просто думаю, что, как новичок, иногда полезно увидеть реальный код.
person
Bane
schedule
02.11.2010