Примеры шаблонов проектирования GoF в основных библиотеках Java

Я изучаю шаблоны проектирования Java GoF, и я хочу увидеть некоторые примеры из реальной жизни. Каковы некоторые хорошие примеры этих шаблонов проектирования в основных библиотеках Java?

7 Solutions collect form web for “Примеры шаблонов проектирования GoF в основных библиотеках Java”

Вы можете найти обзор многих шаблонов проектирования в Википедии . В нем также упоминается, какие шаблоны упоминаются GoF. Я опишу их здесь и попытаюсь назначить как можно больше реализаций шаблонов, найденных в API Java SE и Java EE.


Создание шаблонов

Абстрактная фабрика (распознаваемая методами создания, возвращающая сам завод, который, в свою очередь, может использоваться для создания другого абстрактного / интерфейса)

  • javax.xml.parsers.DocumentBuilderFactory#newInstance()
  • javax.xml.transform.TransformerFactory#newInstance()
  • javax.xml.xpath.XPathFactory#newInstance()

Builder (распознаваемый с помощью методов создания, возвращающих сам экземпляр)

  • java.lang.StringBuilder#append() (несинхронизировано)
  • java.lang.StringBuffer#append() (синхронизировано)
  • java.nio.ByteBuffer#put() (также на CharBuffer , ShortBuffer , IntBuffer , LongBuffer , FloatBuffer и DoubleBuffer )
  • javax.swing.GroupLayout.Group#addComponent()
  • Все реализации java.lang.Appendable
  • java.util.stream.Stream.Builder

Фабричный метод (распознаваемый методами создания, возвращающий реализацию абстрактного / интерфейсного типа)

  • java.util.Calendar#getInstance()
  • java.util.ResourceBundle#getBundle()
  • java.text.NumberFormat#getInstance()
  • java.nio.charset.Charset#forName()
  • java.net.URLStreamHandlerFactory#createURLStreamHandler(String) (возвращает одноэлементный объект для каждого протокола)
  • java.util.EnumSet#of()
  • javax.xml.bind.JAXBContext#createMarshaller() и другие подобные методы

Прототип (распознаваемый с помощью методов создания, возвращающих другой экземпляр самого себя с теми же свойствами)

  • java.lang.Object#clone() (class должен реализовать java.lang.Cloneable )

Синглтон (распознаваемый методами создания, возвращающий один и тот же экземпляр (обычно сам по себе) каждый раз)

  • java.lang.Runtime#getRuntime()
  • java.awt.Desktop#getDesktop()
  • java.lang.System#getSecurityManager()

Структурные структуры

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

  • java.util.Arrays#asList()
  • java.util.Collections#list()
  • java.util.Collections#enumeration()
  • java.io.InputStreamReader(InputStream) (возвращает Reader )
  • java.io.OutputStreamWriter(OutputStream) (возвращает Writer )
  • javax.xml.bind.annotation.adapters.XmlAdapter#marshal() и #unmarshal()

Мост (распознаваемый методами создания, использующий экземпляр другого абстрактного / интерфейса и возвращающий реализацию собственного абстрактного / интерфейса, который делегирует / использует данный экземпляр)

  • Никто еще не приходит на ум. Фиктивным примером будет new LinkedHashMap(LinkedHashSet, List) который возвращает немодифицируемую связанную карту, которая не клонирует элементы, а использует их. Однако java.util.Collections#newSetFromMap() и singletonXXX() приближаются.

Композитный (распознаваемый поведенческими методами, принимающий экземпляр одного абстрактного / типа интерфейса в древовидную структуру)

  • java.awt.Container#add(Component) (практически весь Swing)
  • javax.faces.component.UIComponent#getChildren() (практически во всем пользовательском интерфейсе JSF, таким образом)

Decorator (распознается с помощью методов создания, используя экземпляр того же абстрактного типа / интерфейса, который добавляет дополнительное поведение)

  • Все подclassы java.io.InputStream , OutputStream , Reader и Writer имеют конструктор с экземпляром того же типа.
  • java.util.Collections , checkedXXX() , synchronizedXXX() и unmodifiableXXX() .
  • javax.servlet.http.HttpServletRequestWrapper и HttpServletResponseWrapper
  • javax.swing.JScrollPane

Фасад (распознаваемый поведенческими методами, который внутренне использует экземпляры различных независимых типов абстрактных / интерфейсов)

  • javax.faces.context.FacesContext , он внутренне использует среди прочих абстрактные / интерфейсные типы LifeCycle , ViewHandler , NavigationHandler и многие другие, без которых enduser должен беспокоиться об этом (которые, однако, могут быть отменены при инъекции).
  • javax.faces.context.ExternalContext , который внутренне использует ServletContext , HttpSession , HttpServletRequest , HttpServletResponse и т. д.

Flyweight (узнаваемый с помощью методов создания, возвращающих кешированный экземпляр, немного «многотонную» идею)

  • java.lang.Integer#valueOf(int) (также в Boolean , Byte , Character , Short , Long и BigDecimal )

Прокси (распознаваемый с помощью методов создания, который возвращает реализацию данного абстрактного / интерфейса, который, в свою очередь, делегирует / использует другую реализацию данного типа абстрактного / интерфейса)

  • java.lang.reflect.Proxy
  • java.rmi.*
  • javax.ejb.EJB ( пояснение здесь )
  • javax.inject.Inject ( объяснение здесь )
  • javax.persistence.PersistenceContext

Поведенческие модели

Цепь ответственности (распознаваемая поведенческими методами, которая (косвенно) вызывает тот же метод в другой реализации того же абстрактного / интерфейса в очереди)

  • java.util.logging.Logger#log()
  • javax.servlet.Filter#doFilter()

Command (распознается поведенческими методами в абстрактном / интерфейсном типе, который вызывает метод в реализации другого абстрактного / типа интерфейса, который был инкапсулирован реализацией команды во время его создания)

  • Все реализации java.lang.Runnable
  • Все реализации javax.swing.Action

Интерпретатор (распознаваемый поведенческими методами, возвращающий структурно различный экземпляр / тип данного экземпляра / типа; обратите внимание, что parsing / форматирование не является частью шаблона, определяющим шаблон и как его применять)

  • java.util.Pattern
  • java.text.Normalizer
  • Все подclassы java.text.Format
  • Все подclassы javax.el.ELResolver

Итератор (распознаваемый поведенческими методами, последовательно возвращающий экземпляры другого типа из очереди)

  • Все реализации java.util.Iterator (таким образом, среди других также java.util.Scanner !).
  • Все реализации java.util.Enumeration

Посредник (распознаваемый поведенческими методами, принимающий экземпляр другого абстрактного / типа интерфейса (обычно с использованием шаблона команды), который делегирует / использует данный экземпляр)

  • java.util.Timer (все методы scheduleXXX() )
  • java.util.concurrent.Executor#execute()
  • java.util.concurrent.ExecutorService ( invokeXXX() и submit() )
  • java.util.concurrent.ScheduledExecutorService (все методы scheduleXXX() )
  • java.lang.reflect.Method#invoke()

Memento (распознаваемый поведенческими методами, который внутренне изменяет состояние всего экземпляра)

  • java.util.Date (методы setter делают это, Date внутренне представляется long значением)
  • Все реализации java.io.Serializable
  • Все реализации javax.faces.component.StateHolder

Observer (или Публикация / Подписка) (распознается поведенческими методами, которые вызывают метод на экземпляре другого абстрактного / типа интерфейса, в зависимости от собственного состояния)

  • java.util.Observer / java.util.Observable (редко используется в реальном мире)
  • Все реализации java.util.EventListener (практически все Swing)
  • javax.servlet.http.HttpSessionBindingListener
  • javax.servlet.http.HttpSessionAttributeListener
  • javax.faces.event.PhaseListener

State (узнаваемый поведенческими методами, который изменяет свое поведение в зависимости от состояния экземпляра, который можно контролировать извне)

  • javax.faces.lifecycle.LifeCycle#execute() (управляемый FacesServlet , поведение зависит от текущей фазы (состояния) жизненного цикла JSF)

Страtagsя (распознаваемая поведенческими методами в абстрактном / интерфейсном типе, который вызывает метод в реализации другого абстрактного / типа интерфейса, который был передан как аргумент метода в реализацию страtagsи)

  • java.util.Comparator#compare() , выполненный среди других Collections#sort() .
  • javax.servlet.http.HttpServlet , методы service() и all doXXX() принимают HttpServletRequest и HttpServletResponse и разработчик должен обрабатывать их (и не захватывать их как переменные экземпляра!).
  • javax.servlet.Filter#doFilter()

Метод шаблона (распознаваемый поведенческими методами, которые уже имеют поведение по умолчанию, определенное абстрактным типом)

  • Все не абстрактные методы java.io.InputStream , java.io.OutputStream , java.io.Reader и java.io.Writer .
  • Все не абстрактные методы java.util.AbstractList , java.util.AbstractSet и java.util.AbstractMap .
  • javax.servlet.http.HttpServlet , все методы doXXX() по умолчанию отправляют сообщение об ошибке HTTP 405 «Method Not Allowed». Вы можете реализовать ни одного или любого из них.

Посетитель (распознаваемый двумя разными типами абстрактных / интерфейсов, которые определяют методы, которые берут каждый другой абстрактный тип / тип интерфейса, на самом деле называет метод другого, а другой выполняет желаемую страtagsю на нем)

  • javax.lang.model.element.AnnotationValue и AnnotationValueVisitor
  • javax.lang.model.element.Element и ElementVisitor
  • javax.lang.model.type.TypeMirror и TypeVisitor
  • java.nio.file.FileVisitor и SimpleFileVisitor
  • javax.faces.component.visit.VisitContext и VisitCallback
  1. Схема наблюдателя на протяжении всего колебания ( Observable , Observer )
  2. MVC также в качелях
  3. Шаблон адаптера: InputStreamReader и OutputStreamWriter ПРИМЕЧАНИЕ. ContainerAdapter , ComponentAdapter , FocusAdapter , KeyAdapter , MouseAdapter не являются адаптерами; они фактически являются объектами Null. Плохой выбор именования Sun.
  4. Рисунок Decorator ( BufferedInputStream может украшать другие streamи, такие как FilterInputStream )
  5. AbstractFactory Pattern для AWT Toolkit и Swing подключаемые classы look-and-feel
  6. java.lang.Runtime#getRuntime() – Singleton
  7. ButtonGroup для медиатора
  8. Action , AbstractAction может использоваться для разных визуальных представлений для выполнения того же кода -> Command pattern
  9. Interned Strings или CellRender в JTable для Flyweight Pattern (Также подумайте о различных пулах – пулы streamов, пулы подключений, пулы объектов EJB – Flyweight действительно посвящен управлению общими ресурсами)
  10. Модель событий Java 1.0 является примером цепочки ответственности, а также фильтров сервлета.
  11. Итератор в структуре коллекций
  12. Вложенные контейнеры в AWT / Swing используют композитный шаблон
  13. Менеджеры макетов в AWT / Swing являются примером страtagsи

и многие другие, я думаю

  1. Flyweight используется с некоторыми значениями Byte, Short, Integer, Long и String.
  2. Фасад используется во многих местах, но наиболее очевидным является интерфейс Scripting.
  3. Singleton – java.lang.Runtime приходит на ум.
  4. Абстрактная фабрика – также скрипты и API JDBC.
  5. Команда – Отменить / Редактировать TextComponent.
  6. Interpreter – RegEx (java.util.regex. ) И SQL (java.sql. ) API.
  7. Прототип – не 100% уверен, что этот счет, но я думаю, метод clone() может быть использован для этой цели.

RMI основан на прокси.

Должна быть указана одна из них для большинства 23 шаблонов в GoF:

  1. Абстрактная фабрика: все интерфейсы java.sql получают свои конкретные реализации из JDBC JAR при регистрации драйвера.
  2. Builder: java.lang.StringBuilder.
  3. Фабричный метод: XML-заводы, в частности.
  4. Прототип: Возможно, clone (), но я не уверен, что я его покупаю.
  5. Синглтон: java.lang.System
  6. Адаптер: classы адаптеров в java.awt.event, например, WindowAdapter.
  7. Мост: classы коллекции в java.util. Список реализован ArrayList.
  8. Композитный: java.awt. java.awt.Component + java.awt.Container
  9. Декоратор: весь пакет java.io.
  10. Фасад: ExternalContext ведет себя как фасад для выполнения файлов cookie, сеанса и подобных операций.
  11. Вес мухи: целое, персонаж и т. Д.
  12. Прокси: пакет java.rmi
  13. Цепь ответственности: фильтры сервлета
  14. Команда: элементы меню Swing
  15. Переводчик: прямо в JDK, но JavaCC, безусловно, использует это.
  16. Итератор: интерфейс java.util.Iterator; не может быть яснее этого.
  17. Посредник: JMS?
  18. Memento:
  19. Наблюдатель: java.util.Observer/Observable (плохо сделано, хотя)
  20. Состояние:
  21. Страtagsя:
  22. Шаблон:
  23. Посетитель:

Я не могу придумать примеры на Java для 10 из 23, но я посмотрю, смогу ли я сделать лучше завтра. Это то, что для редактирования.

Шаблон Abstract Factory используется в разных местах. Например, DatagramSocketImplFactory , PreferencesFactory . Есть еще много – найдите Javadoc для интерфейсов, которые имеют слово «Factory» в их имени.

Также есть немало примеров шаблона Factory.

Несмотря на то, что я вроде как сломанные часы с этим, Java XML API использует Factory много. Я имею в виду просто посмотреть на это:

 Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(source); String title = XPathFactory.newInstance().newXPath().evaluate("//title", doc); 

…и так далее и тому подобное.

Кроме того, различные Буферы (StringBuffer, ByteBuffer, StringBuilder) используют Builder.

  • Заводской метод

java.util.Collection # Итератор – хороший пример метода Factory. В зависимости от конкретного подclassа Collection, который вы используете, он создаст реализацию Iterator. Поскольку и суперclassы Factory (Collection), и созданный Iterator являются интерфейсами, их иногда путают с AbstractFactory. Большинство примеров для AbstractFactory в принятом ответе (BalusC) являются примерами Factory , упрощенной версии Factory Method, которая не является частью исходных шаблонов GoF. В Facory иерархия classов Factory рухнула, и фабрика использует другие средства для выбора возвращаемого продукта.

  • Абстрактная фабрика

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

  • Каков пример Принципа замещения Лискова?
  • Когда следует использовать «это» в classе?
  • Что такое инверсия контроля?
  • Каковы различия между типами () и isinstance ()?
  • Интерфейс vs Базовый class
  • Когда вы должны использовать class vs struct в C ++?
  • Как сравнивать объекты по нескольким полям
  • Что делает ключевое слово static в classе?
  • Перегрузка метода для нулевого аргумента
  • Интерфейс против абстрактного classа (общий OO)
  • Почему я должен использовать список инициализации членов?
  • Зачем использовать геттеры и сеттеры / аксессоры?
  • Давайте будем гением компьютера.