GoF Java 디자인 패턴을 배우고 있으며 실제 사례를보고 싶습니다. Java 핵심 라이브러리에서 이러한 디자인 패턴의 좋은 예는 무엇입니까?
답변
Wikipedia 에서 많은 디자인 패턴에 대한 개요를 찾을 수 있습니다 . 또한 GoF에서 언급 한 패턴을 언급합니다. 여기에 그것들을 요약하고 Java SE 및 Java EE API에서 모두 가능한 한 많은 패턴 구현을 할당하려고합니다.
창조 패턴
추상 팩토리 (공장 자체를 반환하는 생성 방법으로 인식 가능하며 다른 추상 / 인터페이스 유형을 만드는 데 사용될 수 있음)
javax.xml.parsers.DocumentBuilderFactory#newInstance()
javax.xml.transform.TransformerFactory#newInstance()
javax.xml.xpath.XPathFactory#newInstance()
빌더 (인스턴스 자체를 리턴하는 작성 메소드로 인식 가능)
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()
(클래스가 구현해야 함java.lang.Cloneable
)
싱글 톤 ( 매번 동일한 인스턴스 (보통 자체)을 리턴하는 작성 메소드로 인식 가능 )
구조 패턴
어댑터 ( 다른 추상 / 인터페이스 유형 의 인스턴스를 가져 오고 주어진 인스턴스 를 장식 / 재정의 하는 자체 / 다른 추상 / 인터페이스 유형의 구현을 리턴하는 작성 메소드로 인식 가능 )
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<K>, List<V>)
변경 불가능한 연결 항목을 복제하지 않는지도 만 돌려 사용 을.java.util.Collections#newSetFromMap()
및singletonXXX()
방법은 그러나 가까이 온다.
컴포지트 ( 동일한 추상 / 인터페이스 유형 의 인스턴스를 트리 구조로 가져가는 동작 방식으로 인식 가능 )
java.awt.Container#add(Component)
(실제로 스윙 전체에)javax.faces.component.UIComponent#getChildren()
(실제로 JSF UI 전체에서)
데코레이터 ( 동작을 추가하는 동일한 추상 / 인터페이스 유형 의 인스턴스를 생성하는 생성 방법으로 인식 가능 )
- 모든 서브 클래스
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
최종 사용자가 걱정하지 않아도됩니다 (그러나 주입으로 재정의 할 수 있음).javax.faces.context.ExternalContext
내부적으로 사용되는ServletContext
,HttpSession
,HttpServletRequest
,HttpServletResponse
, 등
Flyweight (캐시 된 인스턴스를 리턴하는 작성 메소드, 약간 “멀티 톤”아이디어로 인식 가능)
프록시 (주어진 추상 / 인터페이스 유형 의 다른 구현을 위임 / 사용 하는 주어진 추상 / 인터페이스 유형의 구현을 리턴하는 작성 메소드로 인식 가능 )
java.lang.reflect.Proxy
java.rmi.*
javax.ejb.EJB
( 여기 설명 )javax.inject.Inject
( 여기 설명 )javax.persistence.PersistenceContext
행동 패턴
책임 사슬 ( 큐에서 동일한 추상 / 인터페이스 유형 의 다른 구현 에서 동일한 메소드를 간접적으로 호출하는 행동 메소드로 인식 가능 )
명령 ( 생성하는 동안 명령 구현 으로 캡슐화 된 다른 추상 / 인터페이스 유형 의 구현에서 메소드를 호출하는 추상 / 인터페이스 유형의 동작 메소드로 인식 가능 )
- 의 모든 구현
java.lang.Runnable
- 의 모든 구현
javax.swing.Action
해석기 ( 특정 인스턴스 / 유형 의 구조적으로 다른 인스턴스 / 유형을 리턴하는 행동 방법으로 인식 가능 ; 구문 분석 / 포맷팅은 패턴의 일부가 아니며 패턴을 판별하고 적용하는 방법에 유의하십시오)
java.util.Pattern
java.text.Normalizer
- 의 모든 서브 클래스
java.text.Format
- 의 모든 서브 클래스
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
(세터 메소드Date
는 내부적으로long
값으로 표시됩니다 )- 의 모든 구현
java.io.Serializable
- 의 모든 구현
javax.faces.component.StateHolder
관찰자 (또는 공개 / 구독) ( 자체 상태에 따라 다른 추상 / 인터페이스 유형 의 인스턴스에서 메소드를 호출하는 동작 메소드로 인식 가능 )
java.util.Observer
/java.util.Observable
(실제로는 거의 사용되지 않음)java.util.EventListener
(실제로 Swing 전체에 걸쳐) 의 모든 구현javax.servlet.http.HttpSessionBindingListener
javax.servlet.http.HttpSessionAttributeListener
javax.faces.event.PhaseListener
상태 (외부 적으로 제어 할 수있는 인스턴스 상태에 따라 동작을 변경하는 동작 방법으로 인식 가능)
javax.faces.lifecycle.LifeCycle#execute()
(에 의해 제어되는FacesServlet
동작은 JSF 수명주기의 현재 단계 (상태)에 따라 다름)
전략 ( 전략 구현에 메소드 인수로 전달 된 다른 추상 / 인터페이스 유형 의 구현에서 메소드를 호출하는 추상 / 인터페이스 유형의 행동 메소드로 인식 가능 )
java.util.Comparator#compare()
다른 사람에 의해 실행됩니다Collections#sort()
.javax.servlet.http.HttpServlet
,service()
및 모든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”오류를 응답으로 보냅니다. 당신은 그들 중 어느 것도 또는 자유롭게 구현할 수 없습니다.
방문자는 (두 가지 recognizeable 의해 다른 각각 얻어 정의 방법 갖는 추상 / 인터페이스 타입 다른 추상 / 인터페이스 타입을 상기 하나 실제로 다른 방법 및 다른 실행하는 것이 바람직한 전략에 호출)
답변
- 전체 스윙에서 관찰자 패턴 (
Observable
,Observer
) - 스윙에도 MVC
- 어댑터 패턴 : InputStreamReader와의 OutputStreamWriter의 참고 :
ContainerAdapter
,ComponentAdapter
,FocusAdapter
,KeyAdapter
,MouseAdapter
입니다 하지 어댑터; 그것들은 실제로 널 오브젝트입니다. Sun의 이름이 잘못 지정되었습니다. - 데코레이터 패턴 (
BufferedInputStream
와 같은 다른 스트림을 장식 할 수 있음FilterInputStream
) - AWT 툴킷 및 Swing 플러그 가능 Look & Feel 클래스의 AbstractFactory 패턴
java.lang.Runtime#getRuntime()
싱글턴입니다ButtonGroup
중재자 패턴Action
,AbstractAction
동일한 코드를 실행하는 다른 시각적 표현에 사용될 수있다 -> 커맨드 패턴- Flyweight 패턴을위한 JTable의 Interned Strings 또는 CellRender
- Java 1.0 이벤트 모델은 서블릿 필터와 마찬가지로 책임 체인의 예입니다.
- 컬렉션 프레임 워크의 반복자 패턴
- AWT / Swing의 중첩 컨테이너는 복합 패턴을 사용합니다.
- AWT / Swing의 레이아웃 관리자는 전략의 예입니다
그리고 더 많은 것 같아
답변
- Flyweight 는 Byte, Short, Integer, Long 및 String의 일부 값과 함께 사용됩니다.
- Facade 는 여러 곳에서 사용되지만 가장 분명한 것은 Scripting 인터페이스입니다.
- 싱글 톤-java.lang. 런타임이 떠 오릅니다.
- Abstract Factory- 스크립팅 및 JDBC API.
- 명령 -TextComponent의 실행 취소 / 다시 실행
- 해석기 -RegEx (java.util.regex. ) 및 SQL (java.sql. ) API.
- 프로토 타입 -이 숫자가 100 % 확실하지는 않지만이
clone()
방법으로 사용할 수 있다고 생각합니다.
답변
RMI는 프록시를 기반으로합니다.
GoF에서 23 가지 패턴 중 하나를 인용 할 수 있어야합니다.
- Abstract Factory : java.sql 인터페이스는 드라이버가 등록 될 때 JDBC JAR에서 구체적으로 구현됩니다.
- 빌더 : java.lang.StringBuilder.
- 팩토리 메소드 : XML 팩토리 등.
- 프로토 타입 : 아마도 clone ()이지만 그것을 구입하고 있는지 확실하지 않습니다.
- 싱글 톤 : java.lang.System
- 어댑터 : java.awt.event의 어댑터 클래스 (예 : WindowAdapter)
- 브릿지 : java.util의 콜렉션 클래스. ArrayList로 구현 된 목록입니다.
- 복합 : java.awt. java.awt.Component + java.awt.Container
- 데코레이터 : 모든 java.io 패키지.
- 외관 : ExternalContext 는 쿠키, 세션 범위 및 유사한 작업을 수행하기위한 외관으로 동작합니다.
- 플라이급 : 정수, 문자 등
- 프록시 : java.rmi 패키지
- 책임의 사슬 : 서블릿 필터
- 명령 : 스윙 메뉴 항목
- 통역사 : JDK에는 직접적으로는 없지만 JavaCC는 이것을 확실히 사용합니다.
- 반복자 : java.util.Iterator interface; 그보다 더 명확하지 않습니다.
- 중재자 : JMS?
- 기념물:
- 관찰자 : java.util.Observer/Observable (나쁜 짓이지만)
- 상태:
- 전략:
- 주형:
- 방문객:
23 개 중 10 개에 대한 Java 예제는 생각할 수 없지만 내일 더 잘할 수 있는지 볼 수 있습니다. 그것이 편집을위한 것입니다.
답변
추상 팩토리 패턴은 다양한 장소에서 사용됩니다. 예, DatagramSocketImplFactory
, PreferencesFactory
. 이름에 “Factory”라는 단어가있는 인터페이스에 대한 Javadoc을 더 많이 검색합니다.
또한 팩토리 패턴의 인스턴스도 상당히 있습니다.
답변
이 시계로 고장난 시계이지만 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 # Iterator는 팩토리 메소드의 좋은 예입니다. 사용하는 Collection의 구체적 서브 클래스에 따라 Iterator 구현이 작성됩니다. Factory 슈퍼 클래스 (Collection)와 생성 된 Iterator는 모두 인터페이스이기 때문에 때때로 AbstractFactory와 혼동됩니다. 허용 된 답변 (BalusC)에서 AbstractFactory에 대한 대부분의 예제는 Factory Go의 패턴이 아닌 Factory Method의 단순화 된 버전 인 Factory의 예제입니다 . Facory에서 팩토리 클래스 계층 구조가 축소되고 팩토리는 다른 방법을 사용하여 반품 할 제품을 선택합니다.
- 추상 공장
추상 팩토리에는 각각 다른 제품을 생성하는 여러 팩토리 메소드가 있습니다. 한 공장에서 생산 된 제품은 함께 사용하도록 고안되었습니다 (프린터와 카트리지는 동일한 (추상) 공장에서 제조하는 것이 좋습니다). 위의 답변에서 언급했듯이 플랫폼마다 다른 AWT GUI 구성 요소 제품군은 이에 대한 예입니다 (구현 방법은 Gof에 설명 된 구조와 다릅니다).