Когда и как использовать конструктор
Foo bar = new Foo();
И когда и как использовать getInstance () (статические фабричные методы)
Foo bar = Foo.getInstance();
В чем разница между этими двумя? Я всегда использовал конструктор, но когда лучше использовать getInstance()
?
getInstance()
или пишете метод под названиемgetInstance()
?Foo.newInstance()
.Foo.getInstance()
- это соглашение о получении одноэлементного экземпляра класса. Вам следует исправить свой пример и использоватьFoo.newInstance()
вместо него.Ответы:
Кажется, что все сосредоточены на синглтонах, в то время как я думаю, что на самом деле вопрос заключается в конструкторских и статических фабричных методах .
Это на самом деле Пункт 1: Рассмотрят статические фабричные методы вместо конструкторов в Effective Java Джошуа Блох:
Достоинства (цитата из книги):
Недостатки (все еще цитирую книгу):
источник
protected
позволять создавать подклассы, но получает ли клиентский код какое-либо реальное преимущество от создания нового объекта и вызова его конструктора по сравнению с вызовом статического фабричного метода? Мне кажется, что вызов связанного конструктора семантически является методом экземпляра, тогда как последовательность «создать унифицированный объект и вызвать его конструктор» семантически эквивалентна вызову статического метода фабрики.У вас есть два вопроса: когда я должен позвонить в
getInstance()
метод, и когда я должен создать один?Если вы решаете, вызывать ли
getInstance()
метод, это просто. Вам просто нужно прочитать документацию по классу, чтобы узнать, когда его следует вызывать. Например,NumberFormat
предоставляет конструктор и наgetInstance()
метод;getInstance()
метод даст вам локализованыNumberFormat
. СCalendar
другой стороны, конструктор защищен. Вы должны позвонить,getInstance()
чтобы получить его.Если вы решаете, создавать ли
getInstance()
метод, вам нужно решить, чего вы пытаетесь достичь. Либо вы не хотите, чтобы люди вызывали ваш конструктор (вы создаете синглтон или фабрику ), либо вы не возражаете (какNumberFormat
указано выше, где они инициализируют некоторые объекты для удобства вызывающего).Короче говоря? Не беспокойтесь о создании
getInstance()
методов в вашем собственном коде. Если наступит время, когда они будут полезны, ты узнаешь. И вообще, если вы можете вызвать конструктор класса, вы, вероятно, должны это делать, даже если класс предоставляетgetInstance()
метод.источник
Использование методов getInstance:
Но в большинстве случаев ваш объект будет простым POJO, и использование общедоступных конструкторов является наиболее практичным и очевидным решением.
U1: getInstance из другого класса
Чтобы вернуть экземпляр другого класса:
public class FooFactory { public static Foo getInstance() { return new Foo(); } }
NumberFormat.getInstance
методы делают это, поскольку они фактически возвращают экземплярыDecimalFormat
.U2: Проблемы синглтона
Одноэлементный шаблон ограничивает многие преимущества объектно-ориентированного программирования. Синглтоны обычно имеют частные конструкторы, поэтому вы не можете их расширять. Поскольку вы будете обращаться к нему через его метод getInstance и не будете ссылаться на какой-либо интерфейс, вы не сможете заменить его на другую реализацию.
источник
Если вы можете использовать оба, то это звучит как плохо реализованный шаблон singleton .
Используйте второй вариант, если вы намереваетесь иметь только один экземпляр класса в вашей системе, и тогда сделайте конструктор закрытым.
Используйте первый, чтобы позволить построить несколько объектов класса.
НО не давайте вашему классу обе возможности.
Не допускайте чрезмерного использования синглтонов, используйте их только в том случае, если в системе действительно должен существовать только один экземпляр, иначе вы ограничите возможности повторного использования вашего класса в других проектах. Звучит интересно иметь возможность вызывать getInstance из любого места в вашем проекте, но из этого неясно, кто на самом деле владеет этим экземпляром: никто и / или все. Если в проекте много синглтонов, можно поспорить, что система плохо спроектирована (обычно). Синглтоны следует использовать с осторожностью, применимы те же советы, что и для глобальных переменных.
источник
Один случай, когда я всегда предпочитаю статическую фабрику обычному конструктору, - это когда я знаю, что создание объекта будет медленным. Я выполняю простую инициализацию конструктора, но если мне нужно создать что-то тяжелое, я использую статический метод и документирую его поведение.
источник
Синглтоны - это зло. Проблемы, которые я видел вокруг этого, связаны не с повторным использованием или расширяемостью системы (хотя я мог видеть, как это могло произойти), а тем более, что я не могу сосчитать, сколько раз я видел неясные ошибки в системы, возникающие из одиночных элементов.
Если вам действительно нужно использовать синглтон, убедитесь, что его область действия очень узкая, т.е. разумно ограничьте количество других объектов в вашей системе, которые о нем знают.
источник