2010-11-16 2 views
13

Я знаком с идеей и преимущества статического фабричного метода, как описано в Effective Java Джошуа Блоха:Реалистичный вариант использования для статического метода фабрики?

  • фабричные методы имеют имена, так что вы можете иметь более одного фабричный метод с той же подписью, в отличие от конструкторы.
  • Методам фабрики не нужно создавать новый объект; они могут вернуть ранее созданный объект. Это полезно для неизменяемых объектов или объектов ценности.
  • Способы фабрики могут возвращать объект любого подтипа возвращаемого типа, в отличие от конструкторов.

Теперь я пытаюсь объяснить статические методы фабрики для тех, кто изучает принципы Java и OO. Она лучше учится на конкретных сценариях вместо абстракций. Если она увидит образец на работе, решая какую-то проблему, она это получит. Но ей сложнее прочитать абстрактный список характеристик, как указано выше, чтобы понять, как применять шаблон.

Можете ли вы помочь мне придумать реалистичный пример использования статического заводского метода, который делает его преимущества понятными, но который еще достаточно прост, чтобы показать кого-то во вводном классе Java?

У этого человека есть опыт программирования в PL/SQL, но он никогда не разбирался в учениях ООП.

+0

Проверено это? http://stackoverflow.com/questions/929021/what-are-static-factory-methods-in-java –

ответ

15

Используйте javax.swing.BorderFactory в качестве примера всех трех точек.

Этот класс используется для создания границ для качания объектов. Эти пограничные объекты могут быть легко использованы повторно, и этот заводский метод позволяет это. Вот the javadoc. Этот завод является отличным примером всех трех точек:

  • Есть несколько статических методов с разными именами, как createEmptyBorder() и createEtchedBorder().
  • Эти методы возвращают ранее созданные объекты, когда это возможно. Весьма часто, что одна и та же граница будет использоваться во всех приложениях.
  • Border сам по себе является интерфейсом, поэтому все объекты, созданные на этом заводе, фактически являются классами, реализующими этот интерфейс.
+1

Это отличный пример. –

+0

@Erick Мне понравился ваш пример. Но книга также подразумевает это приложение: одно применение этой гибкости заключается в том, что API может возвращать объекты без , что делает их классы общедоступными. Но в вашем примере, все классы являются общедоступными. Итак, есть ли такой пример, который также охватывает это приложение? – dosdebug

4

В учебнике пример вашей второй точки Integer.valueOf(int) (аналогично для Boolean, Short, Long, Byte). Для значений параметров от -128 до 127 этот метод возвращает экземпляр кэширования вместо создания нового Integer. Это делает (авто) бокс/распаковку более реалистичным для типичных значений.

Вы не можете сделать это с new Integer() поскольку JLS требует, чтобы new создайте новый экземпляр каждый раз, когда он вызывается.

3

Не было бы Calendar.getInstance() быть хорошим exmaple? Он создает в зависимости от языка календарь BuddhistCalendar, JapaneseImperialCalendar или по умолчанию GregorianCalendar.

+0

-1 Это не ответ, это вопрос. –

0

Вот один, который я должен был сделать некоторое время назад. На собеседовании меня попросили запрограммировать колоду карт, где их можно перетасовать. Действительно простая проблема.Я создал:

Card: 
    suit 
    rank 

Deck: 
    card[] 

Я считаю, что отличительным фактором является то, что во всех случаях может быть только 52 карты. Поэтому я создал конструктор для Card() private и вместо этого создал статическое значение factoryOf (suit, rank). Это позволило мне кэшировать 52 карты и сделать неизменным. Он преподавал много важных базовых уроков в этих книгах.

  1. неизменны
  2. создание управления объекта
  3. статические методы
  4. возможно подклассов и вернуть карту из другого источника. (Я этого не делал)

Это похоже на булевский и байт, за исключением того, что я использовал общий пример домашней работы, чтобы показать, почему его важно контролировать экземпляры. Я также создал вспомогательную функцию для колоды, называемой newDeck(), потому что я хотел показать экземпляр, где конструктору может не понадобиться быть приватным, но было бы неплохо иметь вспомогательную статическую фабрику.

Надеюсь, это поможет!

+0

В этом конкретном примере я мог бы даже перечислить перечисление, поскольку во время компиляции известно, что каждый отдельный экземпляр вашего класса может быть создан. –

+0

Я действительно сделал перечисление! Я сделал два, три, четыре ... Джек, королева, король и туз. Я также создал сердца, клубы, пики и бриллианты. Это сработало отлично, потому что во время компиляции было проверено статически и мои параметры для valueOf (ранжирование ранга, костюм костюма). Очень просто, но все же много учит программированию OO. –

0

Простой случай. Предположим, у вас есть класс, который управляет каким-то принтером, но ему все равно, является ли это epson, canon или что-то еще. Итак, вы просто создаете интерфейс Printer, создаете некоторые его реализации и создаете класс, который имеет только один метод: createPrinter.

Таким образом, код будет просто: код

public interface Printer { 
     print(); 
    } 

    class CanonPrinter implements Printer { 
     print() { 
    // ... 
     } 
    } 


    public PrinterFactory { 

    Printer createPrinter() { 
    if (...) { 
     return new CanonPrinter(); 
    } else { 
     return new EpsonPrinter(); 
    } 
} 
} 

клиента:

Printer printer = PrinterFactory.createPrinter(); 
printer.print(); 

Здесь абстрагироваться вы clinet кода от каких-либо подробностей того, что принтеров вы можете работать с или, как они управляют печатями , Это PrinterFactory, который заботится о том, какой принтер выбрать, например, в случае сбоев.

4

Мой текущий любимый пример этого рисунка Guava's ImmutableList. Экземпляры этого могут быть созданы только статическими фабриками или строителями. Вот несколько способов, как это выгодно:

  • Поскольку ImmutableList не выставляет никаких public или protected конструкторов, он может быть подклассы в пакете, не позволяя пользователь подкласса (и потенциально нарушить свою гарантию неизменности).
  • Учитывая, что его фабричные методы могут возвращать специализированные подклассы, не выставляя их типы.
  • Свой метод ImmutableList.of() фабрики возвращает экземпляр singleton . Это демонстрирует, как статический заводский метод не нуждается в создании нового экземпляра, если ему это не нужно.
  • Свой метод ImmutableList.of(E) возвращает экземпляр SingletonImmutableList, который оптимизирован, потому что он будет удерживать ровно ровно один элемент.
  • Большинство других методов завода возвращают RegularImmutableList.
  • Его статический заводский метод также не всегда должен создавать новый экземпляр ... если задано Collection, оно само является ImmutableList, оно может просто вернуть это!
+0

ОК Я буду кусать. Что конкретно делать с пустым неизменным списком? –

+2

@Chris: То же самое происходит с, скажем, 'Collections.emptyList()' (который также является неизменным синглтоном). Когда метод, возвращающий 'List', не имеет каких-либо данных для возврата, он всегда должен возвращать пустой' List', а не 'null'. Поскольку пустая, неизменяемая коллекция никогда не может хранить какие-либо данные, экземпляр singleton может использоваться везде, где это необходимо. Кроме того, этот экземпляр может быть как можно более легким, так как он даже не нуждается в каких-либо структурах данных, чтобы держать что-либо. – ColinD

Смежные вопросы