您的位置:首页 > 编程语言 > Java开发

The Genesis of Java Design Patterns

2015-07-30 16:50 816 查看
The Genesis of Java Design Patterns

The idea of patterns and a pattern language was introduced by Christopher Alexander, a building architect as a means of applying
certain solutions over and over again to the same or similar problems. He also combined these existing solutions to create new solutions to new problems. Later, Ward Cunningham and Kent Beck developed five patterns to use in interaction design and finally
in 1994 Erich Gamma, Richard Helm, John Vlissides, and Ralph Johnson published the classic book Design Patterns: Elements of Reusable ObjectOriented Software, that documented patterns that has become a software industry standard.

We will describe how you can use patterns to help you create an architecture. Instead of using the pattern sat the object or class
level, which is the custom, we will abstract them to a higher level. Initially we will focus on the Gang of Four (GoF) patterns, as described in the classic book, Design Patterns: Elements of Reusable Object-Oriented Software and then move on to the core JEE
patterns, as described in the book, Core JEE Patterns, Crupi, et al. As an architect, we look for your knowledge of patterns to arrive at the following level:

Be able to describe each of the Gang of Four design patterns
Be able to describe each of the Core JEE patterns
Categorize a pattern as a Core JEE pattern or GoF design pattern based on the name
Understand the basics of applying patterns

Gang of Four Patterns

The GoF patterns are categorized into three categories, as follows:

Creational Patterns

Creational patterns are used to support the creation of objects in a system. They allow objects to be created in a system without
needing to identify a specific class type in the code, thus avoiding the need to write large, complex code to instantiate an object. Creational patterns achieve this by leveraging the subclass of the class to create the objects. This may limit the type or
number of objects that can be created within a system. The Creational patterns are Abstract Factory, Builder, Factory Method, Prototype, and Singleton.

Abstract Factory Pattern

The Abstract Factory pattern provides an interface for creating a family of related or dependent objects without specifying their
concrete classes. Given a set of related abstract classes, the Abstract Factory pattern provides the means to create instances of these abstract classes from a matched set of concrete subclasses. The Abstract Factory pattern is shown in the figure below:.



Figure: Abstract Factory

The Abstract Factory pattern uses an abstract class to determines the appropriate concrete class to instantiate in order to create
a set of concrete products implementing a standard interface. The client only interacts with the product interfaces and the Abstract Factory class. The client never knows about the concrete construction classes provided in this pattern. This pattern is similar
to the Factory Method pattern, except that it creates families of related objects.

Benefits

The benefits from using the Abstract Factory pattern are the following:

Isolates the concrete classes from client
Allows for exchanging product families easy
Promotes consistency among products by implementing a common interface

When to Use

The Abstract Factory pattern should be applied in the following situations:

When the system should be independent of how its products are created, composed, and represented.
When the system needs to be configured with one of multiple families of products such as for Microsoft Windows , Linux or Apple OSX classes.
When the family of related product objects are designed to be used together, and it is necessary to enforce this constraint. This is one of the key reasons for the existence of this pattern; otherwise, you could use a Factory Method.
When you want to provide a class library of products and only reveal their interfaces, not their implementations.

Builder Pattern



Figure:Builder Pattern

The Builder pattern allows you to create the complex objects one step at a time. Other patterns can build the object in a single
step.

Benefits

The benefits from using the Builder pattern are the following:

It isolates the code for construction and representation
It gives you greater control over the construction process

When to Use

The Builder pattern should be applied in the following situations:

When the algorithm for creating a complex object should be independent of both the parts that make up the object and how these parts are assembled.
When the construction process must allow different representations of the constructed object.

Factory Method Pattern

The Factory Method pattern defines an interface for creating an object, but lets the subclasses determine which class to instantiate.
The Factory Method allows a class to defer instantiation to subclasses. This is very is useful for constructing individual objects for a specific purpose without requiring the requestor to know the specific class being instantiated. This enables you to introduce
new classes without the need to modify the code since the new class only implements the interface so it can be used by the client. The figure below shows the Factory Method pattern:



Figure: Factory Method Pattern

Benefits

The benefits from using the Factory Method pattern are the following:

It eliminates the need to bind application classes into your code. The code relates only to the interface and you can work with any classes that implement the relevant interface.
It enables subclasses to provide an extended version of an object, since it is more flexible to create an object inside a class than to create an object directly in the client.

When to Use

The Factory Method pattern should be applied in the following situations:

When a class cannot anticipate the class of objects it must create.
When a class wants its subclasses to specify the objects it creates.
When classes delegate responsibility to one of several helper subclasses, and you want to localize the knowledge of which helper subclass is the delegate.

Prototype Pattern

The Prototype pattern is used by an object to create objects by cloning an existing object. It does this without knowing their exact
class or the details of how to create them. Instead it specifies the kinds of objects to create using a prototypical instance and then creates new objects by copying this prototype. The Prototype pattern works by giving prototypical objects to an object and
then initiates the creation of objects. The object that initiates the target object creation by asking the prototypical objects to make copies of themselves. The Prototype pattern makes creating objects dynamically easier by defining classes whose objects
can duplicate themselves. The Prototype pattern is shown in the figure below:



Figure:Prototype Pattern

Benefits

The benefits from using the Prototype pattern are the following:

It can add and remove products at run time
It specifies new objects by varying values
It specifies new objects by varying structure
It reduces subclasses
It configures an application with classes dynamically

When to Use

The Prototype pattern should be applied in the following situations:

When the classes to instantiate are specified at run time by dynamic loading for example.

When instances of a class can have one of only a few different combinations of state

Singleton Pattern

The Singleton pattern ensures that there is only one instance of a class and that provides a global point of access to the class.
It ensures that all objects using an instance of this class use the same instance. The figure below shows the Singleton pattern:



Figure:Singleton Pattern

Benefits

The benefits from using the Singleton pattern are the following:

It controlled access to sole instance
It reduces the name space
It permits refinement of operations and representation
It permits a variable number of instances More flexible than class operations

When to Use

The Singleton pattern should be applied in the following situation:

When there must be exactly one instance of a class.

Structural Patterns

Adapter Pattern

Adapter pattern acts as an intermediary between two classes, converting the interface of one class in order that it can be used with
another. This pattern enables classes with incompatible interfaces to work together. The Adapter pattern allows classes with incompatible interfaces to work together by wrapping its own interface around that of an already existing class. It provides the functionality
of an interface without having to know the class used to implement that interface. The figure below illustrates the Adapter pattern:



Figure:Adapter Pattern

Benefits

The benefits from using the Adaptor pattern are the following:

It facilitates communication and interaction between two or more incompatible objects
It improves the reusability of legacy functionality

When to Use

The Adaptor pattern should be applied in the following situation:

When you want to use an existing class, and its interface does not match the interface you need.

When interface translation among multiple sources must occur.

Bridge Pattern

The Bridge pattern divides a complex component into two separate but related inheritance hierarchies: the functional abstraction
and the internal implementation. This makes it easier to change either aspect of the component so that the two can vary independently.

The Bridge pattern is useful when there is a hierarchy of abstractions and a corresponding hierarchy of implementations. Rather than
combining the abstractions and implementations into many distinct classes, the Bridge pattern implements the abstractions and implementations as independent classes allowing them to be combined dynamically. The figure below shows the Bridge pattern:



Figure:Bridge Pattern

Benefits

The benefits from using the Bridge pattern are the following:

It enables you to separate the interface from the implementation
It improves extensibility
It hides implementation details from clients

When to Use

The Bridge pattern should be applied in the following situation:

When you want to avoid a permanent binding between an abstraction and its implementation.
When both the abstractions and their implementations should be extensible using subclasses.
When changes in the implementation of an abstraction should have no impact on clients; that is, you should not have to recompile their code.

Composite Pattern

The Composite pattern composes one-or-more similar objects such that they can be manipulated as one object. It enables you to create
hierarchical tree structures of varying complexity, while also allowing every element in the structure to operate with a uniform interface. The Composite pattern combines objects into tree structures representing either the whole hierarchy or a part of the
hierarchy allowing clients to treat individual objects and compositions of objects uniformly. The figure below illustrates the Composite pattern:



Figure:Composite Pattern

Benefits

The benefits from using the Composite pattern are the following:

Defines class hierarchies consisting of primitive objects and composite objects
Makes it easier to add new kinds of components
Provides flexibility of structure and a manageable interface

When to Use

The Composite pattern should be applied in the following situation:

When you want to represent the whole hierarchy or a part of the hierarchy of objects.
When you want clients to be able to ignore the difference between compositions of objects and individual objects.
When the structure can have any level of complexity and is dynamic.

Decorator Pattern

The Decorator pattern enables you to dynamically add or remove object functionality without changing the external appearance or function
of the object. It changes the functionality of an object in a manner transparent to its clients by using an instance of a subclass of the original class to delegate operations to the original object. The Decorator pattern attaches additional responsibilities
to an object dynamically to provide a flexible alternative to changing object functionality without using static inheritance. The figure below illustrates the Decorator pattern:



Figure:Decorator Pattern

Benefits

The benefits from using the Decorator pattern are the following:

It has more flexibility than static inheritance
It avoids feature-laden classes high up in the hierarchy
It simplifies coding because you write a series of classes, each targeted at a specific part of the functionality, rather than coding all behavior into the object

When to Use

The Decorator pattern should be applied in the following situation:

When you want to add responsibilities to individual objects dynamically and transparently without affecting other objects.
When you want to add responsibilities to the object that you might want to change in the future.
When extension by static subclassing is impractical.



Figure:Facade Pattern

Benefits

The benefits from using the Facade pattern are the following:

It provides a simple interface to a complex system without reducing the options provided by the system
It shields clients from subsystem components
It promotes weak coupling between the subsystem and its clients

It translates the client requests to the subsystems that can fulfill those requests

When to Use

The Facade pattern should be applied in the following situation:

You want to provide a simple interface to a complex subsystem.
There are many dependencies between clients and the implementation classes of an abstraction.
You want to layer your subsystems.

Flyweight Pattern

The Flyweight pattern reduces the number of low-level, detailed objects within a system by sharing objects. If instances of a class
that contain the same information can be used interchangeably, the Flyweight pattern allows a program to avoid the expense of multiple instances that contain the same information by sharing one instance. The figure below illustrates the Flyweight pattern.



Figure:Flyweight Pattern

Benefits

The benefits from using the Flyweight pattern are the following:

It reduces in the number of objects to handle
It reduces in memory and on storage devices, if the objects are persisted

When to Use

The Flyweight pattern should be applied in the following situation:

When the application uses a large number of objects.
When storage costs are high because of the quantity of objects.

Proxy Pattern

The Proxy pattern provides a surrogate or placeholder object to control access to the original object. There are several types of
implementations of the Proxy pattern, with the Remote proxy and Virtual proxy being the most common. The figure below illustrates the Proxy pattern.



Figure:Proxy Pattern

Benefits

The benefits from using the Proxy pattern are the following:

It allows remote proxies to hide an object resides in a different address space.
It allows virtual proxies to perform optimizations, such as creating an object on demand.

When to Use

The Proxy pattern should be applied in the following situation:

When you need a more versatile or sophisticated reference to an object than a simple pointer.

Behavioral Patterns

Behavioral patterns focus on algorithms and the assignments of responsibilities between objects. These patterns shape the patterns
of communication and characterize complex control flow through a system. By optimizing how state and behavior are transferred and modified, you can simplify, optimize, and increase the maintainability of an application.

The Behavioral patterns are Chain of Responsibility, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy,
Template Method, and Visitor

Chain of Responsibility Pattern

The Chain of Responsibility pattern provides for loose coupling. It establishes a chain within a system, so that a message can either
be handled at the level where it is first received, or be directed to an object that can handle it. The figure below illustrates the Chain of Responsibility pattern.



Figure:Chain of Responsibility

Benefits

The benefits from using the Chain of Responsibility pattern are the following:

It reduces coupling
It increases flexibility in assigning responsibilities to objects
It allows a set of classes to behave as a whole, because events produced in one class can be sent on to other handler classes within the composite

When to Use

The Chain of Responsibility pattern should be applied in the following situation:

When you want to issue a request to one of several objects without specifying the receiver explicitly.
When the set of objects that can handle a request should be specified dynamically.

Command Pattern

The Command pattern encapsulates a request in an object, which enables you to store the command, pass the command to a method, and
return the command like any other object. The figure below illustrates the Command pattern.



Figure:Command Pattern

Benefits

The benefits from using the Command pattern are the following:
It separates the object that invokes the operation from the one that knows how to perform it.

When to Use

The Command pattern should be applied in the following situation:

When you want to parameterize objects by an action to perform.
When you specify, queue, and execute requests at different times.
When you must support undo, logging, or transactions.

Interpreter Pattern

The Interpreter pattern interprets a language to define a representation for its grammar along with an interpreter that uses the
representation to interpret sentences in the language. The figure below illustrates the Interpreter pattern.



Figure:Interpreter Pattern

Benefits

The benefits from using the Interpreter pattern are the following:

The implementation of the grammar is easy.

When to Use

The Interpreter pattern should be applied in the following situation:

When the grammar of the language is simple.
When efficiency is not a critical concern.

Iterator Pattern

The Iterator pattern provides a consistent way to sequentially access items in a collection that is independent of and separate from
the underlying collection. The figure below illustrates the Iterator pattern.



Figure:Iterator Pattern

Benefits

The benefits from using the Iterator pattern are the following:

It supports variations in the traversal of a collection
It simplifies the interface of the collection

When to Use

The Iterator pattern should be applied in the following situation:

When support of multiple traversals of objects in a collection
In order to provide a uniform interface for traversing different structures in a collection

Mediator Pattern

The Mediator pattern simplifies communication among objects in a system by introducing a single object that manages message distribution
among other objects. The Mediator pattern promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently. The figure below illustrates the Mediator pattern.



Figure:Mediator Pattern

Benefits

The benefits from using the Mediator pattern are the following:

It decouples colleagues
It simplifies object protocols
It centralizes control
The individual components become simpler and easier to manage since they no longer need to directly pass messages to each other.
Components are more generic, because they no longer need to contain logic to deal with their communication with other components.

When to Use

The Mediator pattern should be applied in the following situation:

When a set of objects communicate in well-defined but complex ways.

Memento Pattern



Figure:Memento Pattern

Benefits

The benefits from using the Memento pattern are the following:

It preserves encapsulation boundaries
It simplifies the originator

When to Use

The Memento pattern should be applied in the following situation:

Observer Pattern

The Observer pattern provides a way for a component to flexibly broadcast messages to interested receivers. It defines a one-to-many
dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. The figure below illustrates the Observer pattern.



Figure:Observer Pattern

Benefits

The benefits from using the Observor pattern are the following:

It abstracts coupling between subject and observer
It supports for broadcast communication

When to Use

The Observor pattern should be applied in the following situation:

When an object should be able to notify other objects without making assumptions about the identity of those objects.

State Pattern

The State pattern allows an object to alter its behavior when its internal state changes. The object appears to change its class.
The figure below illustrates the State pattern.



Figure:State Pattern

Benefits

The benefits from using the State pattern are the following:

It localizes state-specific behavior and partitions behavior for different states
It makes state transitions explicit

When to Use

The State pattern should be applied in the following situation:

Strategy Pattern

The Strategy pattern defines a group of classes that represent a set of possible behaviors. These behaviors can then be used in an
application to change its functionality. The figure below illustrates the Strategy pattern.



Figure:Strategy Pattern

Benefits

The benefits from using the Strategy pattern are the following:

It provides an alternative to subclassing
It defines each behavior in its own class, which eliminates conditional statements

When to Use

The Strategy pattern should be applied in the following situation:

When many related classes differ only in their behavior.
When you need different variants of an algorithm.
When an algorithm uses data unknown to clients.

Template Method Pattern



Figure:Template Method

Benefits

The benefits from using the Template Method pattern are the following:

It is a fundamental technique for reusing code

When to Use

The Template Method pattern should be applied in the following situation:

When you want to implement the invariant parts of an algorithm once and use subclasses to implement the behavior that can vary.
When common behavior among subclasses should be factored and localized in a common class to avoid code duplication.

Visitor Pattern

The Visitor pattern provides a maintainable, easy way to represent an operation to be performed on the elements of an object structure.
The Visitor pattern lets you define a new operation without changing the classes of the elements on which it operates. The figure below illustrates the Visitor pattern.



Figure:Visitor Pattern

Benefits

The benefits from using the Visitor pattern are the following:

It makes adding new operations easy
It gathers related operations and separates unrelated ones

When to Use

The Visitor pattern should be applied in the following situation:

When an object structure contains many classes of objects with differing interfaces, and you want to perform operations on these objects that depend on their concrete classes.
When classes defining the object structure rarely change, but you often want to define new operations over the structure.

Design Patterns Applied - Java EE Patterns

The Core JEE patterns are widely used in organizations architecting Java EE systems. They were the result of the experiences and
a knowledge base which had built up around the use of a Java EE platform. After the initial set of patterns were developed, a new set of patterns were added when Java EE was extended to cover web services. There are also a number of patterns that have become
obsolete with new technologies introduced in Java EE 5.

Presentation Tier

Presentation tier patterns are used to organize components for improving re-use when presenting data to the client tier. It is not
required to apply all of these patterns in the presentation tier as some of the patterns overlap in providing a similar solution to a common problem.

Intercepting Filter

The Intercepting Filter pattern provides the ability to manipulate a request prior to processing or to manipulate the response before
sending the results of the request. The figure below illustrates the Intercepting Filter pattern.



Figure:Intercepting Filter Patterns

Benefits

The benefits from using the Intercepting Filter pattern are the following:

It centralizes pre-processing of requests
It centralizes post-processing of responses

When to Use

The Intercepting Filter pattern should be applied in the following situation:

When you need to pre-process a request or response.
When you need to post-process a request or response.

Context Object

The Context Object pattern is used to encapsulate the specifics of protocol implementation to be shared. The figure below illustrates
the Context Object pattern.



Figure:Context Object Pattern

Benefits

The benefits from using the Context Object pattern are the following:

It improves reusability and maintainability
It allows code to be portable across operating systems

When to Use

The Context Object pattern should be applied in the following situation:

When components need access to system information
In order to decouple application from underlining protocols and system interfaces

Front Controller

The Front Controller pattern creates central control logic for presentation request handling. The Front Controller is different from
the Intercepting Filter in that the Front Controller is determining processing based on the request and an Intercepting Filter is modifying the request. The figure below illustrates the Front Controller pattern.



Figure:Front Controller Pattern

Benefits

The benefits from using the Front Controller pattern are the following:

It centralizes control logic
It improves reusability
It improves separation of concerns

When to Use

The Front Controller pattern should be applied in the following situation:

When you apply common logic to multiple requests
In order to separate processing logic from view

Application Controller

The Application Controller pattern is used to centralize retrieval and invocation of request-processing components, such as commands
and views. The figure below illustrates the Application Controller.



Figure:Application Controller Pattern

Benefits

The benefits from using the Application Controller pattern are the following:

It improves extensibility
It improves separation of concerns

When to Use

The Application Controller pattern should be applied in the following situation:

In order to apply common control logic

When you have centralized view management

View Helper

The View Helper pattern separates the processing logic from the view. The figure below illustrates the View Helper pattern.



Figure:View Helper Pattern

Benefits

The benefits from using the View Helper pattern are the following:

It separates logic from the view

When to Use

The View Helper pattern should be applied in the following situation:

In order to encapsulate view-processing logic

Composite View

The Composite View pattern combines simple views into a more complex view without handling the content or layout. The figure below
illustrates the Composite View pattern.



Figure:Composite View Pattern

Benefits

The benefits from using the Composite View pattern are the following:

It code duplication is reduced because you can create common headers, footers, and other components.
It views can be changed based on access authorization.

When to Use

The Composite View pattern should be applied in the following situation:

When you want common view components.
When you view component changes based on authorization.

Dispatcher View

The Dispatcher View pattern handles the request and generates a response while managing limited business processing. The figure below
illustrates the Dispatcher View pattern.



Figure:Dispatcher View Pattern

Benefits

The benefits from using the Dispatcher View pattern are the following:

It separates processing logic from view
It improves reusability

When to Use

The Dispatcher View pattern should be applied in the following situation:

When you have static views.
When you have limited business processing.

Service to Worker

The Service to Worker pattern performs request handling and invokes business logic before control is passed to the view. The figure
below illustrates the Service to Worker pattern.



Figure:Service to Worker Pattern

Benefits

The benefits from using the Service to Worker pattern are the following:

It improves separation of concerns

When to Use

The Service to Worker pattern should be applied in the following situation:

In order to centralize business logic for requests

Business Tier

Business tier patterns create a loose coupling among the business logic, presentation, and resources.

Business Delegate

The Business Delegate pattern hides the complexity of remote communication with business components from the client. The figure below
illustrates the Business Delegate pattern.



Figure:Business Delegate Pattern

Benefits

The benefits from using the Business Delegate pattern are the following:

It minimizes coupling of clients to business services
It hides remoteness
It improves performance

When to Use

The Business Delegate pattern should be applied in the following situation:

When you want to encapsulate access to business services from multiple client types
In order to translate exceptions into application exceptions Hide details of service creation

Service Locator

The Service Locator pattern uses a consistent approach to locating business components regardless of the type of components. The
figure below illustrates the Service Locator pattern.



Figure:Service Locator Pattern

Benefits

The benefits from using the Service Locator pattern are the following:

It standardizes the approach to retrieving business components

When to Use

The Service Locator pattern should be applied in the following situation:

When you have many different business services that are located in different ways.



Figure:Session Facade Pattern

Benefits

The benefits from using the Session Facade pattern are the following:

It reduces the number of calls to the business component from the client
It reduces coupling between the tiers
It improves performance by reducing fine-grained calls from client
It provides a cleaner API to the client

When to Use

The Session Facade pattern should be applied in the following situation:

When you have a series of calls to make to business components from the client.

Application Service



Figure:Application Service Pattern

Benefits

The benefits from using the Application Service pattern are the following:

It centralizes and improves reusability of business logic

When to Use

The Application Service pattern should be applied in the following situation:

Business Object

The Business Object pattern separates business data from logic. The figure below illustrates the Business Object pattern.



Figure:Business Object Pattern

Benefits

The benefits from using the Business Object pattern are the foll
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: