Design Pattern 简明教程
Design Pattern Quick Guide
设计模式代表了经验丰富的面向对象软件开发人员所使用的最佳实践。设计模式是软件开发人员在软件开发过程中面对的一般问题的解决方案。这些解决方案是由众多软件开发人员经过相当长一段时间通过反复试验获得的。
Design patterns represent the best practices used by experienced object-oriented software developers. Design patterns are solutions to general problems that software developers faced during software development. These solutions were obtained by trial and error by numerous software developers over quite a substantial period of time.
What is Gang of Four (GOF)?
1994 年,埃里希·伽马、理查德·海尔姆、拉尔夫·约翰逊和约翰·弗利斯德斯四位作者出版了一本名为 Design Patterns - Elements of Reusable Object-Oriented Software 的书,这开启了软件开发中设计模式的概念。
In 1994, four authors Erich Gamma, Richard Helm, Ralph Johnson und John Vlissides published a book titled Design Patterns - Elements of Reusable Object-Oriented Software which initiated the concept of Design Pattern in Software development.
这些作者被统称为 Gang of Four (GOF) 。根据这些作者,设计模式主要基于面向对象设计下列原则。
These authors are collectively known as Gang of Four (GOF). According to these authors design patterns are primarily based on the following principles of object orientated design.
-
Program to an interface not an implementation
-
Favor object composition over inheritance
Usage of Design Pattern
设计模式在软件开发中有两种主要用法。
Design Patterns have two main usages in software development.
Common platform for developers
设计模式提供一个标准术语,并且针对特定场景。例如,单例设计模式表示使用单一对象,因此,所有熟悉单一设计模式的开发人员都将使用单一对象,并且他们可以互诉该程序遵循单例模式。
Design patterns provide a standard terminology and are specific to particular scenario. For example, a singleton design pattern signifies use of single object so all developers familiar with single design pattern will make use of single object and they can tell each other that program is following a singleton pattern.
Best Practices
设计模式历经了很长时间的演变,并且他们针对软件开发中所面临的某些问题提供了最佳解决方案。学习这些模式有助于缺乏经验的开发人员以一种轻松快捷的方式学习软件设计。
Design patterns have been evolved over a long period of time and they provide best solutions to certain problems faced during software development. Learning these patterns helps un-experienced developers to learn software design in an easy and faster way.
Types of Design Pattern
根据设计模式参考手册 Design Patterns - Elements of Reusable Object-Oriented Software ,有 23 种设计模式。这些模式可以分类为三类:创建型模式、结构型模式和行为型模式。我们还将讨论另一类设计模式:J2EE 设计模式。
As per the design pattern reference book Design Patterns - Elements of Reusable Object-Oriented Software , there are 23 design patterns. These patterns can be classified in three categories: Creational, Structural and behavioral patterns. We’ll also discuss another category of design patterns: J2EE design patterns.
S.N. |
Pattern & Description |
1 |
Creational Patterns These design patterns provides way to create objects while hiding the creation logic, rather than instantiating objects directly using new operator. This gives program more flexibility in deciding which objects need to be created for a given use case. |
2 |
Structural Patterns These design patterns concern class and object composition. Concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionalities. |
3 |
Behavioral Patterns These design patterns are specifically concerned with communication between objects. |
4 |
J2EE Patterns These design patterns are specifically concerned with the presentation tier. These patterns are identified by Sun Java Center. |
Factory Pattern
工厂模式是 Java 中使用最广泛的设计模式之一。这种设计模式属于创建模式,因为该模式提供了创建对象的最佳方法之一。
Factory pattern is one of the most used design patterns in Java. This type of design pattern comes under creational pattern as this pattern provides one of the best ways to create an object.
在工厂模式中,我们创建对象,而不向客户端公开创建逻辑,并使用通用接口引用新创建的对象。
In Factory pattern, we create object without exposing the creation logic to the client and refer to newly created object using a common interface.
Implementation
我们将创建 Shape 接口和实现 Shape 接口的具体类。作为下一步,将工厂类 ShapeFactory 定义为。
We’re going to create a Shape interface and concrete classes implementing the Shape interface. A factory class ShapeFactory is defined as a next step.
我们的演示类 FactoryPatternDemo 将使用 ShapeFactory 获取 Shape 对象。它将向 ShapeFactory 传递信息(CIRCLE/RECTANGLE/SQUARE)来获取它需要的对象类型。
FactoryPatternDemo, our demo class will use ShapeFactory to get a Shape object. It will pass information (CIRCLE / RECTANGLE / SQUARE) to ShapeFactory to get the type of object it needs.
Step 2
创建实现相同接口的具体类。
Create concrete classes implementing the same interface.
Rectangle.java
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Inside Rectangle::draw() method.");
}
}
Square.java
public class Square implements Shape {
@Override
public void draw() {
System.out.println("Inside Square::draw() method.");
}
}
Circle.java
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Inside Circle::draw() method.");
}
}
Step 3
创建工厂来根据给定的信息生成具体类的对象。
Create a Factory to generate object of concrete class based on given information.
ShapeFactory.java
public class ShapeFactory {
//use getShape method to get object of type shape
public Shape getShape(String shapeType){
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("CIRCLE")){
return new Circle();
} else if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
} else if(shapeType.equalsIgnoreCase("SQUARE")){
return new Square();
}
return null;
}
}
Step 4
使用工厂获取具体类的对象,方法是传递类型等信息。
Use the Factory to get object of concrete class by passing an information such as type.
FactoryPatternDemo.java
public class FactoryPatternDemo {
public static void main(String[] args) {
ShapeFactory shapeFactory = new ShapeFactory();
//get an object of Circle and call its draw method.
Shape shape1 = shapeFactory.getShape("CIRCLE");
//call draw method of Circle
shape1.draw();
//get an object of Rectangle and call its draw method.
Shape shape2 = shapeFactory.getShape("RECTANGLE");
//call draw method of Rectangle
shape2.draw();
//get an object of Square and call its draw method.
Shape shape3 = shapeFactory.getShape("SQUARE");
//call draw method of square
shape3.draw();
}
}
Design Pattern - Abstract Factory Pattern
抽象工厂模式围绕超级工厂进行,该超级工厂创建其他工厂。该工厂也称为工厂之工厂。这种设计模式属于创建模式,因为该模式提供了创建对象的最佳方法之一。
Abstract Factory patterns work around a super-factory which creates other factories. This factory is also called as factory of factories. This type of design pattern comes under creational pattern as this pattern provides one of the best ways to create an object.
在抽象工厂模式中,一个接口负责创建工厂相关对象,而无需明确指定它们的类。每个生成的工厂都可以按照工厂模式提供对象。
In Abstract Factory pattern an interface is responsible for creating a factory of related objects without explicitly specifying their classes. Each generated factory can give the objects as per the Factory pattern.
Implementation
我们将创建一个形状接口和一个实现它的具体类。我们创建 AbstractFactory 抽象工厂类作为下一步。定义工厂类 ShapeFactory,它扩展了 AbstractFactory。创建了一个工厂创建器/生成器类 FactoryProducer。
We are going to create a Shape interface and a concrete class implementing it. We create an abstract factory class AbstractFactory as next step. Factory class ShapeFactory is defined, which extends AbstractFactory. A factory creator/generator class FactoryProducer is created.
AbstractFactoryPatternDemo,我们的演示类使用 FactoryProducer 获取 AbstractFactory 对象。它将信息(形状的 CIRCLE / RECTANGLE / SQUARE)传递给 AbstractFactory 以获取它需要的对象类型。
AbstractFactoryPatternDemo, our demo class uses FactoryProducer to get a AbstractFactory object. It will pass information (CIRCLE / RECTANGLE / SQUARE for Shape) to AbstractFactory to get the type of object it needs.
Step 1
为形状创建一个接口。
Create an interface for Shapes.
Shape.java
public interface Shape {
void draw();
}
Step 2
创建实现相同接口的具体类。
Create concrete classes implementing the same interface.
RoundedRectangle.java
public class RoundedRectangle implements Shape {
@Override
public void draw() {
System.out.println("Inside RoundedRectangle::draw() method.");
}
}
RoundedSquare.java
public class RoundedSquare implements Shape {
@Override
public void draw() {
System.out.println("Inside RoundedSquare::draw() method.");
}
}
Rectangle.java
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Inside Rectangle::draw() method.");
}
}
Step 3
创建一个抽象类来获取普通和圆形形状对象的工厂。
Create an Abstract class to get factories for Normal and Rounded Shape Objects.
AbstractFactory.java
public abstract class AbstractFactory {
abstract Shape getShape(String shapeType) ;
}
Step 4
创建扩展 AbstractFactory 的工厂类以根据给定的信息生成具体类的对象。
Create Factory classes extending AbstractFactory to generate object of concrete class based on given information.
ShapeFactory.java
public class ShapeFactory extends AbstractFactory {
@Override
public Shape getShape(String shapeType){
if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
}else if(shapeType.equalsIgnoreCase("SQUARE")){
return new Square();
}
return null;
}
}
RoundedShapeFactory.java
public class RoundedShapeFactory extends AbstractFactory {
@Override
public Shape getShape(String shapeType){
if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new RoundedRectangle();
}else if(shapeType.equalsIgnoreCase("SQUARE")){
return new RoundedSquare();
}
return null;
}
}
Step 5
创建一个工厂生成器/生产者类通过传递诸如形状的信息来获取工厂。
Create a Factory generator/producer class to get factories by passing an information such as Shape
FactoryProducer.java
public class FactoryProducer {
public static AbstractFactory getFactory(boolean rounded){
if(rounded){
return new RoundedShapeFactory();
}else{
return new ShapeFactory();
}
}
}
Step 6
使用 FactoryProducer 获取 AbstractFactory 以通过传递诸如类型的信息来获取具体类的工厂。
Use the FactoryProducer to get AbstractFactory in order to get factories of concrete classes by passing an information such as type.
AbstractFactoryPatternDemo.java
public class AbstractFactoryPatternDemo {
public static void main(String[] args) {
//get shape factory
AbstractFactory shapeFactory = FactoryProducer.getFactory(false);
//get an object of Shape Rectangle
Shape shape1 = shapeFactory.getShape("RECTANGLE");
//call draw method of Shape Rectangle
shape1.draw();
//get an object of Shape Square
Shape shape2 = shapeFactory.getShape("SQUARE");
//call draw method of Shape Square
shape2.draw();
//get shape factory
AbstractFactory shapeFactory1 = FactoryProducer.getFactory(true);
//get an object of Shape Rectangle
Shape shape3 = shapeFactory1.getShape("RECTANGLE");
//call draw method of Shape Rectangle
shape3.draw();
//get an object of Shape Square
Shape shape4 = shapeFactory1.getShape("SQUARE");
//call draw method of Shape Square
shape4.draw();
}
}
Singleton Pattern
单例模式是 Java 中最简单的设计模式之一。这种设计模式属于创建模式,因为此模式提供了创建对象的最佳方式之一。
Singleton pattern is one of the simplest design patterns in Java. This type of design pattern comes under creational pattern as this pattern provides one of the best way to create an object.
此模式涉及一个负责创建自己对象的单个类,同时确保只创建一个对象。此类提供了一种访问其唯一对象的方法,该对象可以直接访问而无需实例化该类的对象。
This pattern involves a single class which is responsible to creates own object while making sure that only single object get created. This class provides a way to access its only object which can be accessed directly without need to instantiate the object of the class.
Implementation
我们准备创建一个 SingleObject 类。SingleObject 类的构造函数为私有,并且有它自己的一个静态实例。
We’re going to create a SingleObject class. SingleObject class have its constructor as private and have a static instance of itself.
SingleObject 类提供一个静态方法来将它的静态实例提供给外部世界。SingletonPatternDemo,我们的演示类将使用 SingleObject 类来获取一个 SingleObject 对象。
SingleObject class provides a static method to get its static instance to outside world. SingletonPatternDemo, our demo class will use SingleObject class to get a SingleObject object.
Step 1
创建单例类。
Create a Singleton Class.
SingleObject.java
public class SingleObject {
//create an object of SingleObject
private static SingleObject instance = new SingleObject();
//make the constructor private so that this class cannot be
//instantiated
private SingleObject(){}
//Get the only object available
public static SingleObject getInstance(){
return instance;
}
public void showMessage(){
System.out.println("Hello World!");
}
}
Step 2
获取 Singleton 类的唯一对象。
Get the only object from the singleton class.
SingletonPatternDemo.java
public class SingletonPatternDemo {
public static void main(String[] args) {
//illegal construct
//Compile Time Error: The constructor SingleObject() is not visible
//SingleObject object = new SingleObject();
//Get the only object available
SingleObject object = SingleObject.getInstance();
//show the message
object.showMessage();
}
}
Builder Pattern
建造者模式使用简单对象和逐步方法构建复杂对象。此类设计模式属于创建模式,该模式提供创建对象的最佳方法之一。
Builder pattern builds a complex object using simple objects and using a step by step approach. This type of design pattern comes under creational pattern as this pattern provides one of the best ways to create an object.
建造者类逐步构建最终对象。此建造者独立于其他对象。
A Builder class builds the final object step by step. This builder is independent of other objects.
Implementation
我们考虑了一家快餐店的商业案例,其典型餐点可能是一份汉堡和一杯冷饮。汉堡可以选择素食汉堡或鸡肉汉堡,并用包装纸包装。冷饮可以选择可乐或百事可乐,并装在瓶子里。
We’ve considered a business case of fast-food restaurant where a typical meal could be a burger and a cold drink. Burger could be either a Veg Burger or Chicken Burger and will be packed by a wrapper. Cold drink could be either a coke or pepsi and will be packed in a bottle.
我们将创建一个 Item 接口,表示食品,如汉堡和冷饮,以及实现 Item 接口的具体类。还将创建一个 Packing 接口,表示食品包装,以及实现 Packing 接口的具体类。包装纸将用来包装汉堡,瓶子将用来包装冷饮。
We’re going to create an Item interface representing food items such as burgers and cold drinks and concrete classes implementing the Item interface and a Packing interface representing packaging of food items and concrete classes implementing the Packing interface as burger would be packed in wrapper and cold drink would be packed as bottle.
然后,我们创建一个具有 Item 的 ArrayList 的 Meal 类和一个 MealBuilder,通过组合 Item 来构建不同类型的 Meal 对象。我们的演示类 BuilderPatternDemo 将使用 MealBuilder 来构建一个 Meal。
We then create a Meal class having ArrayList of Item and a MealBuilder to build different types of Meal object by combining Item. BuilderPatternDemo, our demo class will use MealBuilder to build a Meal.
Step 1
创建一个表示食品和包装的 Item 接口。
Create an interface Item representing food item and packing.
Item.java
public interface Item {
public String name();
public Packing packing();
public float price();
}
Packing.java
public interface Packing {
public String pack();
}
Step 2
创建实现 Packing 接口的具体类。
Create concreate classes implementing the Packing interface.
Wrapper.java
public class Wrapper implements Packing {
@Override
public String pack() {
return "Wrapper";
}
}
Bottle.java
public class Bottle implements Packing {
@Override
public String pack() {
return "Bottle";
}
}
Step 3
创建实现 Item 接口的抽象类,提供默认功能。
Create abstract classes implementing the item interface providing default functionalities.
Burger.java
public abstract class Burger implements Item {
@Override
public Packing packing() {
return new Wrapper();
}
@Override
public abstract float price();
}
ColdDrink.java
public abstract class ColdDrink implements Item {
@Override
public Packing packing() {
return new Bottle();
}
@Override
public abstract float price();
}
Step 4
创建扩展 Burger 和 ColdDrink 类的具体类
Create concrete classes extending Burger and ColdDrink classes
VegBurger.java
public class VegBurger extends Burger {
@Override
public float price() {
return 25.0f;
}
@Override
public String name() {
return "Veg Burger";
}
}
ChickenBurger.java
public class ChickenBurger extends Burger {
@Override
public float price() {
return 50.5f;
}
@Override
public String name() {
return "Chicken Burger";
}
}
Coke.java
public class Coke extends ColdDrink {
@Override
public float price() {
return 30.0f;
}
@Override
public String name() {
return "Coke";
}
}
Pepsi.java
public class Pepsi extends ColdDrink {
@Override
public float price() {
return 35.0f;
}
@Override
public String name() {
return "Pepsi";
}
}
Step 5
创建包含上述定义的 Item 对象的 Meal 类。
Create a Meal class having Item objects defined above.
Meal.java
import java.util.ArrayList;
import java.util.List;
public class Meal {
private List<Item> items = new ArrayList<Item>();
public void addItem(Item item){
items.add(item);
}
public float getCost(){
float cost = 0.0f;
for (Item item : items) {
cost += item.price();
}
return cost;
}
public void showItems(){
for (Item item : items) {
System.out.print("Item : "+item.name());
System.out.print(", Packing : "+item.packing().pack());
System.out.println(", Price : "+item.price());
}
}
}
Step 6
创建 MealBuilder 类,这是负责创建 Meal 对象的实际构造器类。
Create a MealBuilder class, the actual builder class responsible to create Meal objects.
MealBuilder.java
public class MealBuilder {
public Meal prepareVegMeal (){
Meal meal = new Meal();
meal.addItem(new VegBurger());
meal.addItem(new Coke());
return meal;
}
public Meal prepareNonVegMeal (){
Meal meal = new Meal();
meal.addItem(new ChickenBurger());
meal.addItem(new Pepsi());
return meal;
}
}
Step 7
BuiderPatternDemo 使用 MealBuider 来演示构建器模式。
BuiderPatternDemo uses MealBuider to demonstrate builder pattern.
BuilderPatternDemo.java
public class BuilderPatternDemo {
public static void main(String[] args) {
MealBuilder mealBuilder = new MealBuilder();
Meal vegMeal = mealBuilder.prepareVegMeal();
System.out.println("Veg Meal");
vegMeal.showItems();
System.out.println("Total Cost: " +vegMeal.getCost());
Meal nonVegMeal = mealBuilder.prepareNonVegMeal();
System.out.println("\n\nNon-Veg Meal");
nonVegMeal.showItems();
System.out.println("Total Cost: " +nonVegMeal.getCost());
}
}
Prototype Pattern
原型模式是指在考虑性能的情况下创建副本对象。此类设计模式属于创建模式,因为此模式提供了创建对象的最佳方式之一。
Prototype pattern refers to creating duplicate object while keeping performance in mind. This type of design pattern comes under creational pattern as this pattern provides one of the best way to create an object.
此模式涉及实现一个原型接口,该接口告诉克隆当前对象。当直接创建对象代价高昂时,将使用此模式。例如,在代价高昂的数据库操作之后要创建对象。我们可以缓存该对象,在下一次请求时返回其克隆,并在需要时及时更新数据库,从而减少对数据库的调用。
This pattern involves implementing a prototype interface which tells to create a clone of the current object. This pattern is used when creation of object directly is costly. For example, a object is to be created after a costly database operation. We can cache the object, returns its clone on next request and update the database as as and when needed thus reducing database calls.
Implementation
我们将创建一个抽象类 Shape 和扩展 Shape 类的具体类。接下来定义一个 ShapeCache 类,它将 shape 对象存储在哈希表中,并在请求时返回它们的克隆。
We’re going to create an abstract class Shape and concrete classes extending the Shape class. A class ShapeCache is defined as a next step which stores shape objects in a Hashtable and returns their clone when requested.
我们的演示类 PrototypPatternDemo 将使用 ShapeCache 类获取 Shape 对象。
PrototypPatternDemo, our demo class will use ShapeCache class to get a Shape object.
Step 1
创建一个实现 Clonable 接口的抽象类。
Create an abstract class implementing Clonable interface.
Shape.java
public abstract class Shape implements Cloneable {
private String id;
protected String type;
abstract void draw();
public String getType(){
return type;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Object clone() {
Object clone = null;
try {
clone = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return clone;
}
}
Step 2
创建一个扩展上述类的具体类。
Create concrete classes extending the above class.
Rectangle.java
public class Rectangle extends Shape {
public Rectangle(){
type = "Rectangle";
}
@Override
public void draw() {
System.out.println("Inside Rectangle::draw() method.");
}
}
Square.java
public class Square extends Shape {
public Square(){
type = "Square";
}
@Override
public void draw() {
System.out.println("Inside Square::draw() method.");
}
}
Circle.java
public class Circle extends Shape {
public Circle(){
type = "Circle";
}
@Override
public void draw() {
System.out.println("Inside Circle::draw() method.");
}
}
Step 3
创建一个从数据库中获取具体对象并将它们存储在哈希表中的类。
Create a class to get concreate classes from database and store them in a Hashtable.
ShapeCache.java
import java.util.Hashtable;
public class ShapeCache {
private static Hashtable<String, Shape> shapeMap
= new Hashtable<String, Shape>();
public static Shape getShape(String shapeId) {
Shape cachedShape = shapeMap.get(shapeId);
return (Shape) cachedShape.clone();
}
// for each shape run database query and create shape
// shapeMap.put(shapeKey, shape);
// for example, we are adding three shapes
public static void loadCache() {
Circle circle = new Circle();
circle.setId("1");
shapeMap.put(circle.getId(),circle);
Square square = new Square();
square.setId("2");
shapeMap.put(square.getId(),square);
Rectangle rectangle = new Rectangle();
rectangle.setId("3");
shapeMap.put(rectangle.getId(),rectangle);
}
}
Step 4
PrototypePatternDemo 使用 ShapeCache 类从存储在哈希表中的形状中获取克隆。
PrototypePatternDemo uses ShapeCache class to get clones of shapes stored in a Hashtable.
PrototypePatternDemo.java
public class PrototypePatternDemo {
public static void main(String[] args) {
ShapeCache.loadCache();
Shape clonedShape = (Shape) ShapeCache.getShape("1");
System.out.println("Shape : " + clonedShape.getType());
Shape clonedShape2 = (Shape) ShapeCache.getShape("2");
System.out.println("Shape : " + clonedShape2.getType());
Shape clonedShape3 = (Shape) ShapeCache.getShape("3");
System.out.println("Shape : " + clonedShape3.getType());
}
}
Adapter Pattern
适配器模式充当两个不兼容接口之间的桥梁。此类设计模式属于结构模式,因为此模式结合了两个独立接口的功能。
Adapter pattern works as a bridge between two incompatible interfaces. This type of design pattern comes under structural pattern as this pattern combines the capability of two independent interfaces.
该模式包含一个负责加入独立或不兼容接口的功能的单一类。一个真实生活中的例子可能是充当存储卡和笔记本电脑之间的适配器的读卡器。你将存储卡插入读卡器,然后将读卡器插入笔记本电脑,以便可以通过笔记本电脑读取存储卡。
This pattern involves a single class which is responsible to join functionalities of independent or incompatible interfaces. A real life example could be a case of card reader which acts as an adapter between memory card and a laptop. You plugins the memory card into card reader and card reader into the laptop so that memory card can be read via laptop.
我们通过以下示例展示适配器模式的使用,其中音频播放器设备只能播放 mp3 文件,并且想使用能够播放 vlc 和 mp4 文件的高级音频播放器。
We are demonstrating use of Adapter pattern via following example in which an audio player device can play mp3 files only and wants to use an advanced audio player capable of playing vlc and mp4 files.
Implementation
我们有 MediaPlayer 接口和一个实现了 MediaPlayer 接口的具体类 AudioPlayer。AudioPlayer 默认可以播放 mp3 格式的音频文件。
We’ve an interface MediaPlayer interface and a concrete class AudioPlayer implementing the MediaPlayer interface. AudioPlayer can play mp3 format audio files by default.
我们有另一个接口 AdvancedMediaPlayer 和实现了 AdvancedMediaPlayer 接口的具体类。这些类可以播放 vlc 和 mp4 格式的文件。
We’re having another interface AdvancedMediaPlayer and concrete classes implementing the AdvancedMediaPlayer interface.These classes can play vlc and mp4 format files.
我们希望 AudioPlayer 也可以播放其他格式。为了实现此目的,我们创建了一个实现了 MediaPlayer 接口并使用 AdvancedMediaPlayer 对象播放所需格式的适配器类 MediaAdapter。
We want to make AudioPlayer to play other formats as well. To attain this, we’ve created an adapter class MediaAdapter which implements the MediaPlayer interface and uses AdvancedMediaPlayer objects to play the required format.
AudioPlayer 使用适配器类 MediaAdapter,将其传递所需的音频类型,而不知道可以播放所需格式的实际类。我们的演示类 AdapterPatternDemo 将使用 AudioPlayer 类播放各种格式。
AudioPlayer uses the adapter class MediaAdapter passing it the desired audio type without knowing the actual class which can play the desired format. AdapterPatternDemo, our demo class will use AudioPlayer class to play various formats.
Step 1
为媒体播放器和高级媒体播放器创建接口。
Create interfaces for Media Player and Advanced Media Player.
MediaPlayer.java
public interface MediaPlayer {
public void play(String audioType, String fileName);
}
AdvancedMediaPlayer.java
public interface AdvancedMediaPlayer {
public void playVlc(String fileName);
public void playMp4(String fileName);
}
Step 2
创建实现了 AdvancedMediaPlayer 接口的具体类。
Create concrete classes implementing the AdvancedMediaPlayer interface.
VlcPlayer.java
public class VlcPlayer implements AdvancedMediaPlayer{
@Override
public void playVlc(String fileName) {
System.out.println("Playing vlc file. Name: "+ fileName);
}
@Override
public void playMp4(String fileName) {
//do nothing
}
}
Mp4Player.java
public class Mp4Player implements AdvancedMediaPlayer{
@Override
public void playVlc(String fileName) {
//do nothing
}
@Override
public void playMp4(String fileName) {
System.out.println("Playing mp4 file. Name: "+ fileName);
}
}
Step 3
创建实现了 MediaPlayer 接口的适配器类。
Create adapter class implementing the MediaPlayer interface.
MediaAdapter.java
public class MediaAdapter implements MediaPlayer {
AdvancedMediaPlayer advancedMusicPlayer;
public MediaAdapter(String audioType){
if(audioType.equalsIgnoreCase("vlc") ){
advancedMusicPlayer = new VlcPlayer();
} else if (audioType.equalsIgnoreCase("mp4")){
advancedMusicPlayer = new Mp4Player();
}
}
@Override
public void play(String audioType, String fileName) {
if(audioType.equalsIgnoreCase("vlc")){
advancedMusicPlayer.playVlc(fileName);
}else if(audioType.equalsIgnoreCase("mp4")){
advancedMusicPlayer.playMp4(fileName);
}
}
}
Step 4
创建实现了 MediaPlayer 接口的具体类。
Create concrete class implementing the MediaPlayer interface.
AudioPlayer.java
public class AudioPlayer implements MediaPlayer {
MediaAdapter mediaAdapter;
@Override
public void play(String audioType, String fileName) {
//inbuilt support to play mp3 music files
if(audioType.equalsIgnoreCase("mp3")){
System.out.println("Playing mp3 file. Name: "+ fileName);
}
//mediaAdapter is providing support to play other file formats
else if(audioType.equalsIgnoreCase("vlc")
|| audioType.equalsIgnoreCase("mp4")){
mediaAdapter = new MediaAdapter(audioType);
mediaAdapter.play(audioType, fileName);
}
else{
System.out.println("Invalid media. "+
audioType + " format not supported");
}
}
}
Step 5
使用 AudioPlayer 播放不同类型的音频格式。
Use the AudioPlayer to play different types of audio formats.
AdapterPatternDemo.java
public class AdapterPatternDemo {
public static void main(String[] args) {
AudioPlayer audioPlayer = new AudioPlayer();
audioPlayer.play("mp3", "beyond the horizon.mp3");
audioPlayer.play("mp4", "alone.mp4");
audioPlayer.play("vlc", "far far away.vlc");
audioPlayer.play("avi", "mind me.avi");
}
}
Bridge Pattern
桥用于我们需要将抽象与其实现分离的地方,以便两者可以独立变化。这种设计模式属于结构模式,因为此模式通过在实现类和抽象类之间提供一个桥结构来分离它们。
Bridge is used where we need to decouple an abstraction from its implementation so that the two can vary independently. This type of design pattern comes under structural pattern as this pattern decouples implementation class and abstract class by providing a bridge structure between them.
此模式涉及充当桥接器的接口,该接口使具体类的功能独立于界面实现者类。两种类型的类在不影响彼此的情况下可以在结构上进行更改。
This pattern involves an interface which acts as a bridge which makes the functionality of concrete classes independent from interface implementer classes. Both types of classes can be altered structurally without affecting each other.
我们通过以下示例演示如何使用桥接模式,其中可以使用相同的抽象类方法和不同的桥接实现者类以不同的颜色绘制圆。
We are demonstrating use of Bridge pattern via following example in which a circle can be drawn in different colors using same abstract class method but different bridge implementer classes.
Implementation
我们有一个充当桥式实现者和具体类 RedCircle、GreenCircle(实现 DrawAPI 接口)的 DrawAPI 接口。Shape 是一个抽象类,并会使用 DrawAPI 对象。我们的演示类 BridgePatternDemo 会使用 Shape 类绘制不同颜色的圆。
We’ve an interface DrawAPI interface which is acting as a bridge implementer and concrete classes RedCircle, GreenCircle implementing the DrawAPI interface. Shape is an abstract class and will use object of DrawAPI. BridgePatternDemo, our demo class will use Shape class to draw different colored circle.
Step 1
创建桥接实现器接口。
Create bridge implementer interface.
DrawAPI.java
public interface DrawAPI {
public void drawCircle(int radius, int x, int y);
}
Step 2
创建实现 DrawAPI 接口的具体桥接实现器类。
Create concrete bridge implementer classes implementing the DrawAPI interface.
RedCircle.java
public class RedCircle implements DrawAPI {
@Override
public void drawCircle(int radius, int x, int y) {
System.out.println("Drawing Circle[ color: red, radius: "
+ radius +", x: " +x+", "+ y +"]");
}
}
GreenCircle.java
public class GreenCircle implements DrawAPI {
@Override
public void drawCircle(int radius, int x, int y) {
System.out.println("Drawing Circle[ color: green, radius: "
+ radius +", x: " +x+", "+ y +"]");
}
}
Step 3
使用 DrawAPI 接口创建抽象类 Shape。
Create an abstract class Shape using the DrawAPI interface.
Shape.java
public abstract class Shape {
protected DrawAPI drawAPI;
protected Shape(DrawAPI drawAPI){
this.drawAPI = drawAPI;
}
public abstract void draw();
}
Step 4
使用 Gemini 实现 Shape 接口的具体类。
Create concrete class implementing the Shape interface.
Circle.java
public class Circle extends Shape {
private int x, y, radius;
public Circle(int x, int y, int radius, DrawAPI drawAPI) {
super(drawAPI);
this.x = x;
this.y = y;
this.radius = radius;
}
public void draw() {
drawAPI.drawCircle(radius,x,y);
}
}
Step 5
使用 Shape 和 DrawAPI 类绘制不同颜色的圆。
Use the Shape and DrawAPI classes to draw different colored circles.
BridgePatternDemo.java
public class BridgePatternDemo {
public static void main(String[] args) {
Shape redCircle = new Circle(100,100, 10, new RedCircle());
Shape greenCircle = new Circle(100,100, 10, new GreenCircle());
redCircle.draw();
greenCircle.draw();
}
}
Filter/Criteria Pattern
过滤模式或条件模式是一种设计模式,它允许开发人员使用不同的条件对一组对象进行过滤,并通过逻辑操作以解耦的方式对它们进行链接。这种类型的设计模式属于结构模式,因为该模式将多个条件组合在一起以获取单个条件。
Filter pattern or Criteria pattern is a design pattern that enables developers to filter a set of objects, using different criteria, chaining them in a decoupled way through logical operations. This type of design pattern comes under structural pattern as this pattern is combining multiple criteria to obtain single criteria.
Implementation
我们将创建 Person 对象、Criteria 接口和实现此接口的具体类,以便过滤 Person 对象列表。CriteriaPatternDemo 我们的演示类使用 Criteria 对象根据各种条件及其组合来过滤 Person 对象列表。
We’re going to create a Person object, Criteria interface and concrete classes implementing this interface to filter list of Person objects. CriteriaPatternDemo, our demo class uses Criteria objects to filter List of Person objects based on various criteria and their combinations.
Step 1
创建要应用条件的类。
Create a class on which criteria is to be applied.
Person.java
public class Person {
private String name;
private String gender;
private String maritalStatus;
public Person(String name,String gender,String maritalStatus){
this.name = name;
this.gender = gender;
this.maritalStatus = maritalStatus;
}
public String getName() {
return name;
}
public String getGender() {
return gender;
}
public String getMaritalStatus() {
return maritalStatus;
}
}
Step 2
创建 Criteria 接口。
Create an interface for Criteria.
Criteria.java
import java.util.List;
public interface Criteria {
public List<Person> meetCriteria(List<Person> persons);
}
Step 3
创建实现 Criteria 接口的具体类。
Create concrete classes implementing the Criteria interface.
CriteriaMale.java
import java.util.ArrayList;
import java.util.List;
public class CriteriaMale implements Criteria {
@Override
public List<Person> meetCriteria(List<Person> persons) {
List<Person> malePersons = new ArrayList<Person>();
for (Person person : persons) {
if(person.getGender().equalsIgnoreCase("MALE")){
malePersons.add(person);
}
}
return malePersons;
}
}
CriteriaFemale.java
import java.util.ArrayList;
import java.util.List;
public class CriteriaFemale implements Criteria {
@Override
public List<Person> meetCriteria(List<Person> persons) {
List<Person> femalePersons = new ArrayList<Person>();
for (Person person : persons) {
if(person.getGender().equalsIgnoreCase("FEMALE")){
femalePersons.add(person);
}
}
return femalePersons;
}
}
CriteriaSingle.java
import java.util.ArrayList;
import java.util.List;
public class CriteriaSingle implements Criteria {
@Override
public List<Person> meetCriteria(List<Person> persons) {
List<Person> singlePersons = new ArrayList<Person>();
for (Person person : persons) {
if(person.getMaritalStatus().equalsIgnoreCase("SINGLE")){
singlePersons.add(person);
}
}
return singlePersons;
}
}
AndCriteria.java
import java.util.List;
public class AndCriteria implements Criteria {
private Criteria criteria;
private Criteria otherCriteria;
public AndCriteria(Criteria criteria, Criteria otherCriteria) {
this.criteria = criteria;
this.otherCriteria = otherCriteria;
}
@Override
public List<Person> meetCriteria(List<Person> persons) {
List<Person> firstCriteriaPersons = criteria.meetCriteria(persons);
return otherCriteria.meetCriteria(firstCriteriaPersons);
}
}
OrCriteria.java
import java.util.List;
public class AndCriteria implements Criteria {
private Criteria criteria;
private Criteria otherCriteria;
public AndCriteria(Criteria criteria, Criteria otherCriteria) {
this.criteria = criteria;
this.otherCriteria = otherCriteria;
}
@Override
public List<Person> meetCriteria(List<Person> persons) {
List<Person> firstCriteriaItems = criteria.meetCriteria(persons);
List<Person> otherCriteriaItems = otherCriteria.meetCriteria(persons);
for (Person person : otherCriteriaItems) {
if(!firstCriteriaItems.contains(person)){
firstCriteriaItems.add(person);
}
}
return firstCriteriaItems;
}
}
Step4
使用不同的标准及其组合来筛选人员。
Use different Criteria and their combination to filter out persons.
CriteriaPatternDemo.java
import java.util.ArrayList;
import java.util.List;
public class CriteriaPatternDemo {
public static void main(String[] args) {
List<Person> persons = new ArrayList<Person>();
persons.add(new Person("Robert","Male", "Single"));
persons.add(new Person("John","Male", "Married"));
persons.add(new Person("Laura","Female", "Married"));
persons.add(new Person("Diana","Female", "Single"));
persons.add(new Person("Mike","Male", "Single"));
persons.add(new Person("Bobby","Male", "Single"));
Criteria male = new CriteriaMale();
Criteria female = new CriteriaFemale();
Criteria single = new CriteriaSingle();
Criteria singleMale = new AndCriteria(single, male);
Criteria singleOrFemale = new OrCriteria(single, female);
System.out.println("Males: ");
printPersons(male.meetCriteria(persons));
System.out.println("\nFemales: ");
printPersons(female.meetCriteria(persons));
System.out.println("\nSingle Males: ");
printPersons(singleMale.meetCriteria(persons));
System.out.println("\nSingle Or Females: ");
printPersons(singleOrFemale.meetCriteria(persons));
}
public static void printPersons(List<Person> persons){
for (Person person : persons) {
System.out.println("Person : [ Name : " + person.getName()
+", Gender : " + person.getGender()
+", Marital Status : " + person.getMaritalStatus()
+" ]");
}
}
}
Step 5
验证输出。
Verify the output.
Males:
Person : [ Name : Robert, Gender : Male, Marital Status : Single ]
Person : [ Name : John, Gender : Male, Marital Status : Married ]
Person : [ Name : Mike, Gender : Male, Marital Status : Single ]
Person : [ Name : Bobby, Gender : Male, Marital Status : Single ]
Females:
Person : [ Name : Laura, Gender : Female, Marital Status : Married ]
Person : [ Name : Diana, Gender : Female, Marital Status : Single ]
Single Males:
Person : [ Name : Robert, Gender : Male, Marital Status : Single ]
Person : [ Name : Mike, Gender : Male, Marital Status : Single ]
Person : [ Name : Bobby, Gender : Male, Marital Status : Single ]
Single Or Females:
Person : [ Name : Robert, Gender : Male, Marital Status : Single ]
Person : [ Name : Diana, Gender : Female, Marital Status : Single ]
Person : [ Name : Mike, Gender : Male, Marital Status : Single ]
Person : [ Name : Bobby, Gender : Male, Marital Status : Single ]
Person : [ Name : Laura, Gender : Female, Marital Status : Married ]
Composite Pattern
在我们需要将一组对象与单个对象类似地处理时,使用合成模式。合成模式按照树形结构组成对象以表示部分和整体层次结构。这类设计模式是结构模式,因为该模式创建组对象的树形结构。
Composite pattern is used where we need to treat a group of objects in similar way as a single object. Composite pattern composes objects in term of a tree structure to represent part as well as whole hierarchy . This type of design pattern comes under structural pattern as this pattern creates a tree structure of group of objects.
此模式创建一个类,其中包含它自己的一组对象。该类提供了修改其相同对象组的方法。
This pattern creates a class contains group of its own objects. This class provides ways to modify its group of same objects.
我们正在使用以下示例演示合成模式的使用,展示组织的员工层次结构。
We are demonstrating use of Composite pattern via following example in which show employees hierarchy of an organization.
Implementation
我们有一个类 Employee,它充当合成模式的执行者类。我们的演示类 CompositePatternDemo 将使用 Employee 类添加部门级别层次结构并打印所有员工。
We’ve a class Employee which acts as composite pattern actor class. CompositePatternDemo, our demo class will use Employee class to add department level hierarchy and print all employees.
Step 1
创建具有员工对象列表的 Employee 类。
Create Employee class having list of Employee objects.
Employee.java
import java.util.ArrayList;
import java.util.List;
public class Employee {
private String name;
private String dept;
private int salary;
private List<Employee> subordinates;
// constructor
public Employee(String name,String dept, int sal) {
this.name = name;
this.dept = dept;
this.salary = sal;
subordinates = new ArrayList<Employee>();
}
public void add(Employee e) {
subordinates.add(e);
}
public void remove(Employee e) {
subordinates.remove(e);
}
public List<Employee> getSubordinates(){
return subordinates;
}
public String toString(){
return ("Employee :[ Name : "+ name
+", dept : "+ dept + ", salary :"
+ salary+" ]");
}
}
Step 2
使用 Employee 类创建和打印员工层次结构。
Use the Employee class to create and print employee hierarchy.
CompositePatternDemo.java
public class CompositePatternDemo {
public static void main(String[] args) {
Employee CEO = new Employee("John","CEO", 30000);
Employee headSales = new Employee("Robert","Head Sales", 20000);
Employee headMarketing = new Employee("Michel","Head Marketing", 20000);
Employee clerk1 = new Employee("Laura","Marketing", 10000);
Employee clerk2 = new Employee("Bob","Marketing", 10000);
Employee salesExecutive1 = new Employee("Richard","Sales", 10000);
Employee salesExecutive2 = new Employee("Rob","Sales", 10000);
CEO.add(headSales);
CEO.add(headMarketing);
headSales.add(salesExecutive1);
headSales.add(salesExecutive2);
headMarketing.add(clerk1);
headMarketing.add(clerk2);
//print all employees of the organization
System.out.println(CEO);
for (Employee headEmployee : CEO.getSubordinates()) {
System.out.println(headEmployee);
for (Employee employee : headEmployee.getSubordinates()) {
System.out.println(employee);
}
}
}
}
Step 3
验证输出。
Verify the output.
Employee :[ Name : John, dept : CEO, salary :30000 ]
Employee :[ Name : Robert, dept : Head Sales, salary :20000 ]
Employee :[ Name : Richard, dept : Sales, salary :10000 ]
Employee :[ Name : Rob, dept : Sales, salary :10000 ]
Employee :[ Name : Michel, dept : Head Marketing, salary :20000 ]
Employee :[ Name : Laura, dept : Marketing, salary :10000 ]
Employee :[ Name : Bob, dept : Marketing, salary :10000 ]
Decorator Pattern
装饰器模式允许添加新功能而不改变现有对象的结构。此类设计模式是结构模式,因为此模式充当现有类的包装器。
Decorator pattern allows to add new functionality an existing object without altering its structure. This type of design pattern comes under structural pattern as this pattern acts as a wrapper to existing class.
此模式创建一个装饰器类,它包装原始类并提供附加功能,保持类方法签名不变。
This pattern creates a decorator class which wraps the original class and provides additional functionality keeping class methods signature intact.
我们正在通过以下示例演示装饰器模式的使用,在该示例中我们将用某种颜色装饰一个形状而不更改形状类。
We are demonstrating use of Decorator pattern via following example in which we’ll decorate a shape with some color without alter shape class.
Implementation
我们将创建一个 Shape 接口以及实现 Shape 接口的具体类。然后我们创建了一个抽象装饰类 ShapeDecorator,它实现了 Shape 接口,并具有形状对象作为其实例变量。
We’re going to create a Shape interface and concrete classes implementing the Shape interface. We then create a abstract decorator class ShapeDecorator implementing the Shape interface and having Shape object as its instance variable.
RedShapeDecorator 是一个具体类,实现了 ShapeDecorator。
RedShapeDecorator is concrete class implementing ShapeDecorator.
DecoratorPatternDemo 是我们的演示类,它将使用 RedShapeDecorator 装饰 Shape 对象。
DecoratorPatternDemo, our demo class will use RedShapeDecorator to decorate Shape objects.
Step 2
创建实现相同接口的具体类。
Create concrete classes implementing the same interface.
Rectangle.java
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Shape: Rectangle");
}
}
Circle.java
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Shape: Circle");
}
}
Step 3
创建一个实现 Shape 接口的抽象装饰类。
Create abstract decorator class implementing the Shape interface.
ShapeDecorator.java
public abstract class ShapeDecorator implements Shape {
protected Shape decoratedShape;
public ShapeDecorator(Shape decoratedShape){
this.decoratedShape = decoratedShape;
}
public void draw(){
decoratedShape.draw();
}
}
Step 4
创建一个扩展 ShapeDecorator 类的具体装饰类。
Create concrete decorator class extending the ShapeDecorator class.
RedShapeDecorator.java
public class RedShapeDecorator extends ShapeDecorator {
public RedShapeDecorator(Shape decoratedShape) {
super(decoratedShape);
}
@Override
public void draw() {
decoratedShape.draw();
setRedBorder(decoratedShape);
}
private void setRedBorder(Shape decoratedShape){
System.out.println("Border Color: Red");
}
}
Step 5
使用 RedShapeDecorator 装饰 Shape 对象。
Use the RedShapeDecorator to decorate Shape objects.
DecoratorPatternDemo.java
public class DecoratorPatternDemo {
public static void main(String[] args) {
Shape circle = new Circle();
Shape redCircle = new RedShapeDecorator(new Circle());
Shape redRectangle = new RedShapeDecorator(new Rectangle());
System.out.println("Circle with normal border");
circle.draw();
System.out.println("\nCircle of red border");
redCircle.draw();
System.out.println("\nRectangle of red border");
redRectangle.draw();
}
}
Facade Pattern
外观模式隐藏了系统的复杂性,并为客户端提供了一个接口,客户端可以使用它来访问系统。这种设计模式属于结构模式,因为该模式会向现有系统添加一个接口来隐藏其复杂性。
Facade pattern hides the complexities of the system and provides an interface to the client using which the client can access the system. This type of design pattern comes under structural pattern as this pattern adds an interface to exiting system to hide its complexities.
此模式涉及一个提供客户端所需且委托调用现有的系统类方法的简化方法的类。
This pattern involves a single class which provides simplified methods which are required by client and delegates calls to existing system classes methods.
Implementation
我们将创建一个 Shape 接口和实现 Shape 接口的具体类。外观类 ShapeMaker 被定义为下一步。
We’re going to create a Shape interface and concrete classes implementing the Shape interface. A facade class ShapeMaker is defined as a next step.
ShapeMaker 类使用具体类委托用户的调用到这些类。FacadePatternDemo 是我们的演示类,它将使用 ShapeMaker 类来显示结果。
ShapeMaker class uses the concrete classes to delegates user calls to these classes. FacadePatternDemo, our demo class will use ShapeMaker class to show the results.
Step 2
创建实现相同接口的具体类。
Create concrete classes implementing the same interface.
Rectangle.java
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Rectangle::draw()");
}
}
Square.java
public class Square implements Shape {
@Override
public void draw() {
System.out.println("Square::draw()");
}
}
Circle.java
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Circle::draw()");
}
}
Step 3
创建一个外观类。
Create a facade class.
ShapeMaker.java
public class ShapeMaker {
private Shape circle;
private Shape rectangle;
private Shape square;
public ShapeMaker() {
circle = new Circle();
rectangle = new Rectangle();
square = new Square();
}
public void drawCircle(){
circle.draw();
}
public void drawRectangle(){
rectangle.draw();
}
public void drawSquare(){
square.draw();
}
}
Flyweight Pattern
享元模式主要用来减少创建的对象数,从而减少内存占用并提升性能。这种设计模式属于结构模式,因为此模式提供了减少对象计数的方法,从而提升了应用程序所需的结构对象。
Flyweight pattern is primarily used to reduce the number of objects created, to decrease memory footprint and increase performance. This type of design pattern comes under structural pattern as this pattern provides ways to decrease objects count thus improving application required objects structure.
享元模式尝试通过存储类似类型的现有对象并仅在找不到匹配对象时创建一个新对象来重用它们。我们将通过绘制 20 个位于不同位置的圆形来说明这个模式,但我们只创建一个对象。只有 5 种颜色可用,所以颜色属性被用来检查现有的 Circle 对象。
Flyweight pattern try to reuse already existing similar kind objects by storing them and creates new object when no matching object is found. We’ll demonstrate this pattern by drawing 20 circle of different locations but we’ll creating only 5 objects. Only 5 colors are available so color property is used to check already existing Circle objects.
Implementation
我们将创建一个 Shape 接口和实现 Shape 接口的具体类 Circle。外观类 ShapeFactory 被定义为下一步。
We’re going to create a Shape interface and concrete class Circle implementing the Shape interface. A factory class ShapeFactory is defined as a next step.
ShapeFactory 具有 HashMap 的 Circle,其中密钥是 Circle 对象的颜色。每当请求来创建特定颜色的循环到 ShapeFactory 时。ShapeFactory 会检查其 HashMap 中的循环对象,如果找到 Circle 对象,则返回该对象,否则创建新对象,存储在 hashmap 中以备将来使用并返回给客户端。
ShapeFactory have a HashMap of Circle having key as color of the Circle object. Whenever a request comes to create a circle of particular color to ShapeFactory. ShapeFactory checks the circle object in its HashMap, if object of Circle found, that object is returned otherwise a new object is created, stored in hashmap for future use and returned to client.
FlyWeightPatternDemo,我们的演示类将使用 ShapeFactory 获得 Shape 对象。它将传递信息(红色/绿色/蓝色/黑色/白色)到 ShapeFactory 以获得所需颜色的圆。
FlyWeightPatternDemo, our demo class will use ShapeFactory to get a Shape object. It will pass information (red / green / blue/ black / white) to ShapeFactory to get the circle of desired color it needs.
Step 2
创建实现相同界面的具体类。
Create concrete class implementing the same interface.
Circle.java
public class Circle implements Shape {
private String color;
private int x;
private int y;
private int radius;
public Circle(String color){
this.color = color;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public void setRadius(int radius) {
this.radius = radius;
}
@Override
public void draw() {
System.out.println("Circle: Draw() [Color : " + color
+", x : " + x +", y :" + y +", radius :" + radius);
}
}
Step 3
创建工厂来根据给定的信息生成具体类的对象。
Create a Factory to generate object of concrete class based on given information.
ShapeFactory.java
import java.util.HashMap;
public class ShapeFactory {
// Uncomment the compiler directive line and
// javac *.java will compile properly.
// @SuppressWarnings("unchecked")
private static final HashMap circleMap = new HashMap();
public static Shape getCircle(String color) {
Circle circle = (Circle)circleMap.get(color);
if(circle == null) {
circle = new Circle(color);
circleMap.put(color, circle);
System.out.println("Creating circle of color : " + color);
}
return circle;
}
}
Step 4
使用 Factory 根据颜色等信息来获得具体类对象。
Use the Factory to get object of concrete class by passing an information such as color.
FlyweightPatternDemo.java
public class FlyweightPatternDemo {
private static final String colors[] =
{ "Red", "Green", "Blue", "White", "Black" };
public static void main(String[] args) {
for(int i=0; i < 20; ++i) {
Circle circle =
(Circle)ShapeFactory.getCircle(getRandomColor());
circle.setX(getRandomX());
circle.setY(getRandomY());
circle.setRadius(100);
circle.draw();
}
}
private static String getRandomColor() {
return colors[(int)(Math.random()*colors.length)];
}
private static int getRandomX() {
return (int)(Math.random()*100 );
}
private static int getRandomY() {
return (int)(Math.random()*100);
}
}
Step 5
验证输出。
Verify the output.
Creating circle of color : Black
Circle: Draw() [Color : Black, x : 36, y :71, radius :100
Creating circle of color : Green
Circle: Draw() [Color : Green, x : 27, y :27, radius :100
Creating circle of color : White
Circle: Draw() [Color : White, x : 64, y :10, radius :100
Creating circle of color : Red
Circle: Draw() [Color : Red, x : 15, y :44, radius :100
Circle: Draw() [Color : Green, x : 19, y :10, radius :100
Circle: Draw() [Color : Green, x : 94, y :32, radius :100
Circle: Draw() [Color : White, x : 69, y :98, radius :100
Creating circle of color : Blue
Circle: Draw() [Color : Blue, x : 13, y :4, radius :100
Circle: Draw() [Color : Green, x : 21, y :21, radius :100
Circle: Draw() [Color : Blue, x : 55, y :86, radius :100
Circle: Draw() [Color : White, x : 90, y :70, radius :100
Circle: Draw() [Color : Green, x : 78, y :3, radius :100
Circle: Draw() [Color : Green, x : 64, y :89, radius :100
Circle: Draw() [Color : Blue, x : 3, y :91, radius :100
Circle: Draw() [Color : Blue, x : 62, y :82, radius :100
Circle: Draw() [Color : Green, x : 97, y :61, radius :100
Circle: Draw() [Color : Green, x : 86, y :12, radius :100
Circle: Draw() [Color : Green, x : 38, y :93, radius :100
Circle: Draw() [Color : Red, x : 76, y :82, radius :100
Circle: Draw() [Color : Blue, x : 95, y :82, radius :100
Proxy Pattern
在 Proxy 模式中,一个类表示另一个类的功能。这种设计模式属于结构模式。
In Proxy pattern, a class represents functionality of another class. This type of design pattern comes under structural pattern.
在 Proxy 模式中,我们创建一个具有原始对象的对象,将其功能与外部世界进行接口。
In Proxy pattern, we create object having original object to interface its functionality to outer world.
Implementation
我们将创建一个 Image 接口和实现 Image 接口的具体类。ProxyImage 是一个代理类,用于减少 RealImage 对象加载的内存占用。
We’re going to create a Image interface and concrete classes implementing the Image interface. ProxyImage is a a proxy class to reduce memory footprint of RealImage object loading.
ProxyPatternDemo,我们的演示类将使用 ProxyImage 获得 Image 对象以根据需要加载和显示。
ProxyPatternDemo, our demo class will use ProxyImage to get a Image object to load and display as it needs.
Step 2
创建实现相同接口的具体类。
Create concrete classes implementing the same interface.
RealImage.java
public class RealImage implements Image {
private String fileName;
public RealImage(String fileName){
this.fileName = fileName;
loadFromDisk(fileName);
}
@Override
public void display() {
System.out.println("Displaying " + fileName);
}
private void loadFromDisk(String fileName){
System.out.println("Loading " + fileName);
}
}
ProxyImage.java
public class ProxyImage implements Image{
private RealImage realImage;
private String fileName;
public ProxyImage(String fileName){
this.fileName = fileName;
}
@Override
public void display() {
if(realImage == null){
realImage = new RealImage(fileName);
}
realImage.display();
}
}
Step 3
根据需要使用 ProxyImage 来获取 RealImage 类的对象。
Use the ProxyImage to get object of RealImage class when required.
ProxyPatternDemo.java
public class ProxyPatternDemo {
public static void main(String[] args) {
Image image = new ProxyImage("test_10mb.jpg");
//image will be loaded from disk
image.display();
System.out.println("");
//image will not be loaded from disk
image.display();
}
}
Chain of Responsibility Pattern
顾名思义,责任链模式为请求创建了一个接收器对象链。此模式基于请求类型将请求的发件人和接收者解耦。此模式属于行为模式。
As the name suggest, the chain of responsibility pattern creates a chain of receiver objects for a request. This pattern decouples sender and receiver of a request based on type of request. This pattern comes under behavioral patterns.
在此模式中,每个接收器通常包含对另一个接收器的引用。如果一个对象无法处理请求,则将其传递给下一个接收器,依此类推。
In this pattern, normally each receiver contains reference to another receiver. If one object cannot handle the request then it passes the same to the next receiver and so on.
Implementation
我们创建了一个具有日志记录级别的抽象类 AbstractLogger。然后我们创建了三种类型的记录器来扩展 AbstractLogger。每个记录器检查消息的级别到其级别并相应地打印,否则不打印并将其消息传递给下一个记录器。
We’ve created an abstract class AbstractLogger with a level of logging. Then we’ve created three types of loggers extending the AbstractLogger. Each logger checks the level of message to its level and print accordingly otherwise does not print and pass the message to its next logger.
Step 1
创建抽象记录器类。
Create an abstract logger class.
AbstractLogger.java
public abstract class AbstractLogger {
public static int INFO = 1;
public static int DEBUG = 2;
public static int ERROR = 3;
protected int level;
//next element in chain or responsibility
protected AbstractLogger nextLogger;
public void setNextLogger(AbstractLogger nextLogger){
this.nextLogger = nextLogger;
}
public void logMessage(int level, String message){
if(this.level <= level){
write(message);
}
if(nextLogger !=null){
nextLogger.logMessage(level, message);
}
}
abstract protected void write(String message);
}
Step 2
创建扩展记录器的具体类。
Create concrete classes extending the logger.
ConsoleLogger.java
public class ConsoleLogger extends AbstractLogger {
public ConsoleLogger(int level){
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("Standard Console::Logger: " + message);
}
}
ErrorLogger.java
public class ErrorLogger extends AbstractLogger {
public ErrorLogger(int level){
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("Error Console::Logger: " + message);
}
}
FileLogger.java
public class FileLogger extends AbstractLogger {
public FileLogger(int level){
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("File::Logger: " + message);
}
}
Step 3
创建不同类型的记录器。将错误级别分配给它们并在每个记录器中设置下一个记录器。每个记录器中的下一个记录器表示链的一部分。
Create different types of loggers. Assign them error levels and set next logger in each logger. Next logger in each logger represents the part of the chain.
ChainPatternDemo.java
public class ChainPatternDemo {
private static AbstractLogger getChainOfLoggers(){
AbstractLogger errorLogger = new ErrorLogger(AbstractLogger.ERROR);
AbstractLogger fileLogger = new FileLogger(AbstractLogger.DEBUG);
AbstractLogger consoleLogger = new ConsoleLogger(AbstractLogger.INFO);
errorLogger.setNextLogger(fileLogger);
fileLogger.setNextLogger(consoleLogger);
return errorLogger;
}
public static void main(String[] args) {
AbstractLogger loggerChain = getChainOfLoggers();
loggerChain.logMessage(AbstractLogger.INFO,
"This is an information.");
loggerChain.logMessage(AbstractLogger.DEBUG,
"This is an debug level information.");
loggerChain.logMessage(AbstractLogger.ERROR,
"This is an error information.");
}
}
Step 4
验证输出。
Verify the output.
Standard Console::Logger: This is an information.
File::Logger: This is an debug level information.
Standard Console::Logger: This is an debug level information.
Error Console::Logger: This is an error information.
File::Logger: This is an error information.
Standard Console::Logger: This is an error information.
Command Pattern
命令模式是一种数据驱动设计模式,属于行为模式类别。请求被包装在对象中作为命令并传递到调用者对象。调用者对象查找可以处理此命令的适当对象,并把命令传递给相应的对象,该对象执行命令。
Command pattern is a data driven design pattern and falls under behavioral pattern category. A request is wrapped under a object as command and passed to invoker object. Invoker object looks for the appropriate object which can handle this command and pass the command to the corresponding object and that object executes the command.
Implementation
我们创建了一个充当命令的接口 Order。我们创建了一个充当请求的 Stock 类。我们有具体的命令类 BuyStock 和 SellStock,实现了 Order 接口,将执行实际的命令处理。创建了一个充当调用者对象的类 Broker。它可以接受订单并下达订单。
We’ve created an interface Order which is acting as a command. We’ve created a Stock class which acts as a request. We’ve concrete command classes BuyStock and SellStock implementing Order interface which will do actual command processing. A class Broker is created which acts as a invoker object. It can take order and place orders.
Broker 对象使用命令模式根据命令类型识别哪个对象将执行哪个命令。我们的演示类 CommandPatternDemo 将使用 Broker 类演示命令模式。
Broker object uses command pattern to identify which object will execute which command based on type of command. CommandPatternDemo, our demo class will use Broker class to demonstrate command pattern.
Step 2
创建一个请求类。
Create a request class.
Stock.java
public class Stock {
private String name = "ABC";
private int quantity = 10;
public void buy(){
System.out.println("Stock [ Name: "+name+",
Quantity: " + quantity +" ] bought");
}
public void sell(){
System.out.println("Stock [ Name: "+name+",
Quantity: " + quantity +" ] sold");
}
}
Step 3
创建实现 Order 接口的具体类。
Create concrete classes implementing the Order interface.
BuyStock.java
public class BuyStock implements Order {
private Stock abcStock;
public BuyStock(Stock abcStock){
this.abcStock = abcStock;
}
public void execute() {
abcStock.buy();
}
}
SellStock.java
public class SellStock implements Order {
private Stock abcStock;
public SellStock(Stock abcStock){
this.abcStock = abcStock;
}
public void execute() {
abcStock.sell();
}
}
Step 4
创建命令调用者类。
Create command invoker class.
Broker.java
import java.util.ArrayList;
import java.util.List;
public class Broker {
private List<Order> orderList = new ArrayList<Order>();
public void takeOrder(Order order){
orderList.add(order);
}
public void placeOrders(){
for (Order order : orderList) {
order.execute();
}
orderList.clear();
}
}
Step 5
使用 Broker 类获取并执行命令。
Use the Broker class to take and execute commands.
CommandPatternDemo.java
public class CommandPatternDemo {
public static void main(String[] args) {
Stock abcStock = new Stock();
BuyStock buyStockOrder = new BuyStock(abcStock);
SellStock sellStockOrder = new SellStock(abcStock);
Broker broker = new Broker();
broker.takeOrder(buyStockOrder);
broker.takeOrder(sellStockOrder);
broker.placeOrders();
}
}
Interpreter Pattern
解释器模式提供了一种评估语言语法或表达式的途径。这种模式属于行为模式。此模式涉及实现一个表达式接口,该接口讲述如何解释特定上下文。此模式用于 SQL 解析、符号处理引擎等。
Interpreter pattern provides way to evaluate language grammar or expression. This type of pattern comes under behavioral patterns. This pattern involves implementing a expression interface which tells to interpret a particular context. This pattern is used in SQL parsing, symbol processing engine etc.
Implementation
我们将创建一个接口 Expression,并创建实现 Expression 接口的具体类。定义了一个类 TerminalExpression,它充当问题上下文中主要的解释器。其他类 OrExpression、AndExpression 用于创建组合表达式。
We’re going to create an interface Expression and concrete classes implementing the Expression interface. A class TerminalExpression is defined which acts as a main interpreter of context in question. Other classes OrExpression, AndExpression are used to create combinational expressions.
我们的演示类 InterpreterPatternDemo 将使用 Expression 类创建规则并演示表达式的解析。
InterpreterPatternDemo, our demo class will use Expression class to create rules and demonstrate parsing of expressions.
Step 1
创建一个表达式接口。
Create an expression interface.
Expression.java
public interface Expression {
public boolean interpret(String context);
}
Step 2
创建实现上述接口的具体类。
Create concrete classes implementing the above interface.
TerminalExpression.java
public class TerminalExpression implements Expression {
private String data;
public TerminalExpression(String data){
this.data = data;
}
@Override
public boolean interpret(String context) {
if(context.contains(data)){
return true;
}
return false;
}
}
OrExpression.java
public class OrExpression implements Expression {
private Expression expr1 = null;
private Expression expr2 = null;
public OrExpression(Expression expr1, Expression expr2) {
this.expr1 = expr1;
this.expr2 = expr2;
}
@Override
public boolean interpret(String context) {
return expr1.interpret(context) || expr2.interpret(context);
}
}
AndExpression.java
public class AndExpression implements Expression {
private Expression expr1 = null;
private Expression expr2 = null;
public AndExpression(Expression expr1, Expression expr2) {
this.expr1 = expr1;
this.expr2 = expr2;
}
@Override
public boolean interpret(String context) {
return expr1.interpret(context) && expr2.interpret(context);
}
}
Step 3
InterpreterPatternDemo 使用 Expression 类来创建规则并解释它们。
InterpreterPatternDemo uses Expression class to create rules and then parse them.
InterpreterPatternDemo.java
public class InterpreterPatternDemo {
//Rule: Robert and John are male
public static Expression getMaleExpression(){
Expression robert = new TerminalExpression("Robert");
Expression john = new TerminalExpression("John");
return new OrExpression(robert, john);
}
//Rule: Julie is a married women
public static Expression getMarriedWomanExpression(){
Expression julie = new TerminalExpression("Julie");
Expression married = new TerminalExpression("Married");
return new AndExpression(julie, married);
}
public static void main(String[] args) {
Expression isMale = getMaleExpression();
Expression isMarriedWoman = getMarriedWomanExpression();
System.out.println("John is male? " + isMale.interpret("John"));
System.out.println("Julie is a married women? "
+ isMarriedWoman.interpret("Married Julie"));
}
}
Iterator Pattern
迭代器模式是 Java 和 .Net 编程环境中非常常见的设计模式。此模式用于获取一种方法,在无需了解其底层表示的情况下,以顺序方式访问集合对象的元素。
Iterator pattern is very commonly used design pattern in Java and .Net programming environment. This pattern is used to get a way to access the elements of a collection object in sequential manner without any need to know its underlying representation.
迭代器模式属于行为模式类别。
Iterator pattern falls under behavioral pattern category.
Implementation
我们将创建一个描述导航方法的 Iterator 接口,以及一个返回迭代器的 Container 接口。实现 Container 接口的具体类将负责实现 Iterator 接口并使用它
We’re going to create a Iterator interface which narrates navigation method and a Container interface which retruns the iterator . Concrete classes implementing the Container interface will be responsible to implement Iterator interface and use it
我们的演示类 IteratorPatternDemo 将使用 NamesRepository(一个具体类实现)来打印存储为 NamesRepository 中集合的名称。
IteratorPatternDemo, our demo class will use NamesRepository, a concrete class implementation to print a Names stored as a collection in NamesRepository.
Step 1
创建接口。
Create interfaces.
Iterator.java
public interface Iterator {
public boolean hasNext();
public Object next();
}
Container.java
public interface Container {
public Iterator getIterator();
}
Step 2
创建实现 Container 接口的具体类。此类具有实现 Iterator 接口的内部类 NameIterator。
Create concrete class implementing the Container interface. This class has inner class NameIterator implementing the Iterator interface.
NameRepository.java
public class NameRepository implements Container {
public String names[] = {"Robert" , "John" ,"Julie" , "Lora"};
@Override
public Iterator getIterator() {
return new NameIterator();
}
private class NameIterator implements Iterator {
int index;
@Override
public boolean hasNext() {
if(index < names.length){
return true;
}
return false;
}
@Override
public Object next() {
if(this.hasNext()){
return names[index++];
}
return null;
}
}
}
Step 3
使用 NameRepository 获取迭代器并打印名称。
Use the NameRepository to get iterator and print names.
IteratorPatternDemo.java
public class IteratorPatternDemo {
public static void main(String[] args) {
NameRepository namesRepository = new NameRepository();
for(Iterator iter = namesRepository.getIterator(); iter.hasNext();){
String name = (String)iter.next();
System.out.println("Name : " + name);
}
}
}
Mediator Pattern
调解器模式用于减少多个对象或类之间的通信复杂性。此模式提供一个调解器类,该类通常处理不同类之间的所有通信,并通过松散耦合支持代码的轻松维护。调解器模式属于行为模式类别。
Mediator pattern is used to reduce communication complexity between multiple objects or classes. This pattern provides a mediator class which normally handles all the communications between different classes and supports easy maintainability of the code by loose coupling. Mediator pattern falls under behavioral pattern category.
Implementation
我们通过聊天室的示例来演示中介者模式,这里多个用户可以向聊天室发送消息,而聊天室负责向所有用户展示这些消息。我们创建了两个类 ChatRoom 和 User。User 对象将使用 ChatRoom 方法来共享其消息。
We’re demonstrating mediator pattern by example of a Chat Room where multiple users can send message to Chat Room and it is the responsibility of Chat Room to show the messages to all users. We’ve created two classes ChatRoom and User. User objects will use ChatRoom method to share their messages.
MediatorPatternDemo(我们的演示类)将使用 User 对象来展示它们之间的通信。
MediatorPatternDemo, our demo class will use User objects to show communication between them.
Step 1
创建中介者类。
Create mediator class.
ChatRoom.java
import java.util.Date;
public class ChatRoom {
public static void showMessage(User user, String message){
System.out.println(new Date().toString()
+ " [" + user.getName() +"] : " + message);
}
}
Step 2
创建用户类
Create user class
User.java
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User(String name){
this.name = name;
}
public void sendMessage(String message){
ChatRoom.showMessage(this,message);
}
}
Step 3
使用 User 对象来展示它们之间的通信。
Use the User object to show communications between them.
MediatorPatternDemo.java
public class MediatorPatternDemo {
public static void main(String[] args) {
User robert = new User("Robert");
User john = new User("John");
robert.sendMessage("Hi! John!");
john.sendMessage("Hello! Robert!");
}
}
Memento Pattern
备忘录模式用于减少我们希望将对象的某个状态还原到某个先前状态的情况。备忘录模式属于行为模式范畴。
Memento pattern is used to reduce where we want to restore state of an object to a previous state. Memento pattern falls under behavioral pattern category.
Implementation
备忘录模式使用三个执行者类。Memento 包含要还原对象的某个状态。Originator 在 Memento 对象中创建并存储状态,而 Caretaker 对象负责从 Memento 还原对象状态。我们创建了类 Memento、Originator 和 CareTaker。
Memento pattern uses three actor classes. Memento contains state of an object to be restored. Originator creates and stores states in Memento objects and Caretaker object which is responsible to restore object state from Memento. We’ve created classes Memento, Originator and CareTaker.
MediatorPatternDemo(我们的演示类)将使用 CareTaker 和 Originator 对象来展示对象状态的还原。
MementoPatternDemo, our demo class will use CareTaker and Originator objects to show restoration of object states.
Step 1
创建 Memento 类。
Create Memento class.
Memento.java
public class Memento {
private String state;
public Memento(String state){
this.state = state;
}
public String getState(){
return state;
}
}
Step 2
创建 Originator 类
Create Originator class
Originator.java
public class Originator {
private String state;
public void setState(String state){
this.state = state;
}
public String getState(){
return state;
}
public Memento saveStateToMemento(){
return new Memento(state);
}
public void getStateFromMemento(Memento Memento){
state = memento.getState();
}
}
Step 3
创建 CareTaker 类
Create CareTaker class
CareTaker.java
import java.util.ArrayList;
import java.util.List;
public class CareTaker {
private List<Memento> mementoList = new ArrayList<Memento>();
public void add(Memento state){
mementoList.add(state);
}
public Memento get(int index){
return mementoList.get(index);
}
}
Step 4
使用 CareTaker 和 Originator 对象。
Use CareTaker and Originator objects.
MementoPatternDemo.java
public class MementoPatternDemo {
public static void main(String[] args) {
Originator originator = new Originator();
CareTaker careTaker = new CareTaker();
originator.setState("State #1");
originator.setState("State #2");
careTaker.add(originator.saveStateToMemento());
originator.setState("State #3");
careTaker.add(originator.saveStateToMemento());
originator.setState("State #4");
System.out.println("Current State: " + originator.getState());
originator.getStateFromMemento(careTaker.get(0));
System.out.println("First saved State: " + originator.getState());
originator.getStateFromMemento(careTaker.get(1));
System.out.println("Second saved State: " + originator.getState());
}
}
Observer Pattern
当对象之间存在一对多的关系(例如,如果修改一个对象,则其依赖对象将被自动通知)时,可以使用观察者模式。观察者模式属于行为模式类别。
Observer pattern is used when there is one to many relationship between objects such as if one object is modified, its depenedent objects are to be notified automatically. Observer pattern falls under behavioral pattern category.
Implementation
观察者模式使用三个参与者类。主题、观察者和客户。主题,用于附加和分离观察者到客户对象的方法的对象。我们创建了主题、观察者抽象类和扩展观察者抽象类的具体类。
Observer pattern uses three actor classes. Subject, Observer and Client. Subject, an object having methods to attach and de-attach observers to a client object. We’ve created classes Subject, Observer abstract class and concrete classes extending the abstract class the Observer.
ObserverPatternDemo,我们的演示类将使用主题和具体类对象来演示观察者模式的作用。
ObserverPatternDemo, our demo class will use Subject and concrete class objects to show observer pattern in action.
Step 1
创建主题类。
Create Subject class.
Subject.java
import java.util.ArrayList;
import java.util.List;
public class Subject {
private List<Observer> observers
= new ArrayList<Observer>();
private int state;
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
notifyAllObservers();
}
public void attach(Observer observer){
observers.add(observer);
}
public void notifyAllObservers(){
for (Observer observer : observers) {
observer.update();
}
}
}
Step 2
创建观察者类。
Create Observer class.
Observer.java
public abstract class Observer {
protected Subject subject;
public abstract void update();
}
Step 3
创建具体观察者类
Create concrete observer classes
BinaryObserver.java
public class BinaryObserver extends Observer{
public BinaryObserver(Subject subject){
this.subject = subject;
this.subject.attach(this);
}
@Override
public void update() {
System.out.println( "Binary String: "
+ Integer.toBinaryString( subject.getState() ) );
}
}
OctalObserver.java
public class OctalObserver extends Observer{
public OctalObserver(Subject subject){
this.subject = subject;
this.subject.attach(this);
}
@Override
public void update() {
System.out.println( "Octal String: "
+ Integer.toOctalString( subject.getState() ) );
}
}
HexaObserver.java
public class HexaObserver extends Observer{
public HexaObserver(Subject subject){
this.subject = subject;
this.subject.attach(this);
}
@Override
public void update() {
System.out.println( "Hex String: "
+ Integer.toHexString( subject.getState() ).toUpperCase() );
}
}
Step 4
使用主题和具体观察者对象。
Use Subject and concrete observer objects.
ObserverPatternDemo.java
public class ObserverPatternDemo {
public static void main(String[] args) {
Subject subject = new Subject();
new HexaObserver(subject);
new OctalObserver(subject);
new BinaryObserver(subject);
System.out.println("First state change: 15");
subject.setState(15);
System.out.println("Second state change: 10");
subject.setState(10);
}
}
State Pattern
在状态模式中,类行为会根据其状态而变化。这种设计模式属于行为模式。
In State pattern a class behavior changes based on its state. This type of design pattern comes under behavior pattern.
在状态模式中,我们创建表示各种状态的对象,以及随着其状态对象的变化而行为发生变化的上下文对象。
In State pattern, we create objects which represent various states and a context object whose behavior varies as its state object changes.
Implementation
我们将创建一个定义动作的 State 接口以及实现 State 接口的具体状态类。Context 是一个承载状态的类。
We’re going to create a State interface defining a action and concrete state classes implementing the State interface. Context is a class which carries a State.
StaePatternDemo,我们的演示类将使用 Context 和状态对象来演示根据状态类型而改变 Context 行为。
StaePatternDemo, our demo class will use Context and state objects to demonstrate change in Context behavior based on type of state it is in.
Step 1
创建一个接口。
Create an interface.
Image.java
public interface State {
public void doAction(Context context);
}
Step 2
创建实现相同接口的具体类。
Create concrete classes implementing the same interface.
StartState.java
public class StartState implements State {
public void doAction(Context context) {
System.out.println("Player is in start state");
context.setState(this);
}
public String toString(){
return "Start State";
}
}
StopState.java
public class StopState implements State {
public void doAction(Context context) {
System.out.println("Player is in stop state");
context.setState(this);
}
public String toString(){
return "Stop State";
}
}
Step 3
创建 Context 类。
Create Context Class.
Context.java
public class Context {
private State state;
public Context(){
state = null;
}
public void setState(State state){
this.state = state;
}
public State getState(){
return state;
}
}
Step 4
使用 Context 查看状态改变时行为的变化。
Use the Context to see change in behaviour when State changes.
StatePatternDemo.java
public class StatePatternDemo {
public static void main(String[] args) {
Context context = new Context();
StartState startState = new StartState();
startState.doAction(context);
System.out.println(context.getState().toString());
StopState stopState = new StopState();
stopState.doAction(context);
System.out.println(context.getState().toString());
}
}
Null Object Pattern
在 Null 对象模式中,一个 null 对象替代了 NULL 对象实例的检查。Null 对象反映一种不采取任何操作的关系,而不是放置对 null 值的 if 检查。如果没有数据,也可以使用 Null 对象提供默认行为。
In Null Object pattern, a null object replaces check of NULL object instance. Instead of putting if check for a null value, Null Object reflects a do nothing relationship. Such Null object can also be used to provide default behaviour in case data is not available.
在 Null 对象模式中,我们创建一个指定要执行的各个操作的抽象类,扩展此类的具体类,以及提供此类的不执行实现的空对象类,并在需要检查 null 值时无缝地使用它。
In Null Object pattern, we create a abstract class specifying the various operations to be done, concreate classes extending this class and a null object class providing do nothing implemention of this class and will be used seemlessly where we need to check null value.
Implementation
我们创建一个定义操作的抽象类 AbstractCustomer,此处为客户的姓名,以及扩展 AbstractCustomer 类的具体类。创建一个工厂类 CustomerFactory,基于传递给它的客户姓名返回 RealCustomer 或 NullCustomer 对象。
We’re going to create a AbstractCustomer abstract class defining opearations, here the name of the customer and concrete classes extending the AbstractCustomer class. A factory class CustomerFactory is created to return either RealCustomer or NullCustomer objects based on the name of customer passed to it.
NullPatternDemo,我们的演示类,将使用 CustomerFactory 演示 Null 对象模式的使用。
NullPatternDemo, our demo class will use CustomerFactory to demonstrate use of Null Object pattern.
Step 1
创建一个抽象类。
Create an abstract class.
AbstractCustomer.java
public abstract class AbstractCustomer {
protected String name;
public abstract boolean isNil();
public abstract String getName();
}
Step 2
创建一个扩展上述类的具体类。
Create concrete classes extending the above class.
RealCustomer.java
public class RealCustomer extends AbstractCustomer {
public RealCustomer(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
public boolean isNil() {
return false;
}
}
NullCustomer.java
public class NullCustomer extends AbstractCustomer {
@Override
public String getName() {
return "Not Available in Customer Database";
}
@Override
public boolean isNil() {
return true;
}
}
Step 3
创建 CustomerFactory 类。
Create CustomerFactory Class.
CustomerFactory.java
public class CustomerFactory {
public static final String[] names = {"Rob", "Joe", "Julie"};
public static AbstractCustomer getCustomer(String name){
for (int i = 0; i < names.length; i++) {
if (names[i].equalsIgnoreCase(name)){
return new RealCustomer(name);
}
}
return new NullCustomer();
}
}
Step 4
使用 CustomerFactory 根据传递给它的客户姓名获取 RealCustomer 或 NullCustomer 对象。
Use the CustomerFactory get either RealCustomer or NullCustomer objects based on the name of customer passed to it.
NullPatternDemo.java
public class NullPatternDemo {
public static void main(String[] args) {
AbstractCustomer customer1 = CustomerFactory.getCustomer("Rob");
AbstractCustomer customer2 = CustomerFactory.getCustomer("Bob");
AbstractCustomer customer3 = CustomerFactory.getCustomer("Julie");
AbstractCustomer customer4 = CustomerFactory.getCustomer("Laura");
System.out.println("Customers");
System.out.println(customer1.getName());
System.out.println(customer2.getName());
System.out.println(customer3.getName());
System.out.println(customer4.getName());
}
}
Strategy Pattern
在策略模式中,一个类的行为或其算法可以在运行时更改。这种设计模式属于行为模式。
In Strategy pattern, a class behavior or its algorithm can be changed at run time. This type of design pattern comes under behavior pattern.
在策略模式中,我们创建代表各种策略的对象,以及随其策略对象而行为不同的上下文对象。策略对象更改上下文对象的可执行算法。
In Strategy pattern, we create objects which represent various strategies and a context object whose behavior varies as per its strategy object. The strategy object changes the executing algorithm of the context object.
Implementation
我们将创建一个定义操作的策略接口和实现策略接口的具体策略类。Context 是使用策略的类。
We’re going to create a Strategy interface defining a action and concrete strategy classes implementing the Strategy interface. Context is a class which uses a Strategy.
StrategyPatternDemo,我们的演示类将使用 Context 和 strategy 对象来展示根据它部署或使用的策略,在 Context 行为中进行更改。
StrategyPatternDemo, our demo class will use Context and strategy objects to demonstrate change in Context behaviour based on strategy it deploys or uses.
Step 1
创建一个接口。
Create an interface.
Strategy.java
public interface Strategy {
public int doOperation(int num1, int num2);
}
Step 2
创建实现相同接口的具体类。
Create concrete classes implementing the same interface.
OperationAdd.java
public class OperationAdd implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 + num2;
}
}
OperationSubstract.java
public class OperationSubstract implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 - num2;
}
}
OperationMultiply.java
public class OperationMultiply implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 * num2;
}
}
Step 3
创建 Context 类。
Create Context Class.
Context.java
public class Context {
private Strategy strategy;
public Context(Strategy strategy){
this.strategy = strategy;
}
public int executeStrategy(int num1, int num2){
return strategy.doOperation(num1, num2);
}
}
Step 4
使用 Context 查看当其更改其 Strategy 时,行为中的变更。
Use the Context to see change in behaviour when it changes its Strategy.
StatePatternDemo.java
public class StrategyPatternDemo {
public static void main(String[] args) {
Context context = new Context(new OperationAdd());
System.out.println("10 + 5 = " + context.executeStrategy(10, 5));
context = new Context(new OperationSubstract());
System.out.println("10 - 5 = " + context.executeStrategy(10, 5));
context = new Context(new OperationMultiply());
System.out.println("10 * 5 = " + context.executeStrategy(10, 5));
}
}
Template Pattern
在 Template 中,一个抽象类公开了定义的执行其方法的方式/模板。其子类可以根据需要覆盖方法实现,但调用应该是按照抽象类定义的方式进行。此模式属于行为模式类别。
In Template pattern, an abstract class exposes defined way(s)/template(s) to execute its methods. Its subclasses can overrides the method implementations as per need basis but the invocation is to be in the same way as defined by an abstract class. This pattern comes under behavior pattern category.
Implementation
我们将创建一个 Game 抽象类,它使用模板方法定义操作,将其设置为 final,以便不能将其覆盖。Cricket 和 Football 是具体类,扩展 Game 并覆盖其方法。
We’re going to create a Game abstract class defining operations with a template method set to be final so that it cannot be overridden. Cricket and Football are concrete classes extend Game and override its methods.
TemplatePatternDemo,我们的演示类将使用 Game 来展示模板模式用法。
TemplatePatternDemo, our demo class will use Game to demonstrate use of template pattern.
Step 1
创建带有 final 模板方法的抽象类。
Create an abstract class with a template method being final.
Game.java
public abstract class Game {
abstract void initialize();
abstract void startPlay();
abstract void endPlay();
//template method
public final void play(){
//initialize the game
initialize();
//start game
startPlay();
//end game
endPlay();
}
}
Step 2
创建一个扩展上述类的具体类。
Create concrete classes extending the above class.
Cricket.java
public class Cricket extends Game {
@Override
void endPlay() {
System.out.println("Cricket Game Finished!");
}
@Override
void initialize() {
System.out.println("Cricket Game Initialized! Start playing.");
}
@Override
void startPlay() {
System.out.println("Cricket Game Started. Enjoy the game!");
}
}
Football.java
public class Football extends Game {
@Override
void endPlay() {
System.out.println("Football Game Finished!");
}
@Override
void initialize() {
System.out.println("Football Game Initialized! Start playing.");
}
@Override
void startPlay() {
System.out.println("Football Game Started. Enjoy the game!");
}
}
Step 3
使用 Game 的模板方法 play() 来展示一种定义好的比赛玩法。
Use the Game’s template method play() to demonstrate a defined way of playing game.
TemplatePatternDemo.java
public class TemplatePatternDemo {
public static void main(String[] args) {
Game game = new Cricket();
game.play();
System.out.println();
game = new Football();
game.play();
}
}
Visitor Pattern
在 Visitor 模式中,我们使用 visitor 类来更改 element 类的执行算法。这样,随着 visitor 的变化,element 的执行算法也会发生变化。此模式属于行为模式类别。按照此模式,element 对象必须接受 visitor 对象,以便 visitor 对象处理 element 对象上的操作。
In Visitor pattern, we use a visitor class which changes the executing algorithm of an element class. By this way, execution algorithm of element can varies as visitor varies. This pattern comes under behavior pattern category. As per the pattern, element object has to accept the visitor object so that visitor object handles the operation on the element object.
Implementation
我们将创建一个 ComputerPart 接口,它定义 accept 操作。Keyboard、Mouse、Monitor 和 Computer 是实现 ComputerPart 接口的具体类。我们将定义另一个接口 ComputerPartVisitor,它将定义 visitor 类操作。Computer 使用具体 visitor 来执行相应的动作。
We’re going to create a ComputerPart interface defining accept opearation.Keyboard, Mouse, Monitor and Computer are concrete classes implementing ComputerPart interface. We’ll define another interface ComputerPartVisitor which will define a visitor class operations. Computer uses concrete visitor to do corresponding action.
VisitorPatternDemo,我们的演示类将使用 Computer、ComputerPartVisitor 类来展示 visitor 模式用法。
VisitorPatternDemo, our demo class will use Computer, ComputerPartVisitor classes to demonstrate use of visitor pattern.
Step 1
定义一个接口来表示元素。
Define an interface to represent element.
ComputerPart.java
public interface class ComputerPart {
public void accept(ComputerPartVisitor computerPartVisitor);
}
Step 2
创建一个扩展上述类的具体类。
Create concrete classes extending the above class.
Keyboard.java
public class Keyboard implements ComputerPart {
@Override
public void accept(ComputerPartVisitor computerPartVisitor) {
computerPartVisitor.visit(this);
}
}
Monitor.java
public class Monitor implements ComputerPart {
@Override
public void accept(ComputerPartVisitor computerPartVisitor) {
computerPartVisitor.visit(this);
}
}
Mouse.java
public class Mouse implements ComputerPart {
@Override
public void accept(ComputerPartVisitor computerPartVisitor) {
computerPartVisitor.visit(this);
}
}
Computer.java
public class Computer implements ComputerPart {
ComputerPart[] parts;
public Computer(){
parts = new ComputerPart[] {new Mouse(), new Keyboard(), new Monitor()};
}
@Override
public void accept(ComputerPartVisitor computerPartVisitor) {
for (int i = 0; i < parts.length; i++) {
parts[i].accept(computerPartVisitor);
}
computerPartVisitor.visit(this);
}
}
Step 3
确定一个界面来表示访问者。
Define an interface to represent visitor.
ComputerPartVisitor.java
public interface ComputerPartVisitor {
public void visit(Computer computer);
public void visit(Mouse mouse);
public void visit(Keyboard keyboard);
public void visit(Monitor monitor);
}
Step 4
创建具体访问者实现上述类。
Create concrete visitor implementing the above class.
ComputerPartDisplayVisitor.java
public class ComputerPartDisplayVisitor implements ComputerPartVisitor {
@Override
public void visit(Computer computer) {
System.out.println("Displaying Computer.");
}
@Override
public void visit(Mouse mouse) {
System.out.println("Displaying Mouse.");
}
@Override
public void visit(Keyboard keyboard) {
System.out.println("Displaying Keyboard.");
}
@Override
public void visit(Monitor monitor) {
System.out.println("Displaying Monitor.");
}
}
Step 5
使用 ComputerPartDisplayVisitor 来显示计算机的部分。
Use the ComputerPartDisplayVisitor to display parts of Computer.
VisitorPatternDemo.java
public class VisitorPatternDemo {
public static void main(String[] args) {
ComputerPart computer = new Computer();
computer.accept(new ComputerPartDisplayVisitor());
}
}
MVC Pattern
MVC 模式代表模型-视图-控制器模式。此模式用于分离应用程序的关注点。
MVC Pattern stands for Model-View-Controller Pattern. This pattern is used to separate application’s concerns.
-
Model - Model represents an object or JAVA POJO carrying data. It can also have logic to update controller if its data changes.
-
View - View represents the visualization of the data that model contains.
-
Controller - Controller acts on both Model and view. It controls the data flow into model object and updates the view whenever data changes. It keeps View and Model separate.
Implementation
我们将创建一个充当模型的学生对象。StudentView 将是一个可以将学生详细信息打印到控制台的视图类,而 StudentController 是负责将数据存储在 Student 对象中并相应地更新视图 StudentView 的控制器类。
We’re going to create a Student object acting as a model.StudentView will be a view class which can print student details on console and StudentController is the controller class responsible to store data in Student object and update view StudentView accordingly.
MVCPatternDemo,我们的演示类,将使用 StudentController 来演示 MVC 模式的用法。
MVCPatternDemo, our demo class will use StudentController to demonstrate use of MVC pattern.
Step 1
创建模型。
Create Model.
Student.java
public class Student {
private String rollNo;
private String name;
public String getRollNo() {
return rollNo;
}
public void setRollNo(String rollNo) {
this.rollNo = rollNo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Step 2
创建视图。
Create View.
StudentView.java
public class StudentView {
public void printStudentDetails(String studentName, String studentRollNo){
System.out.println("Student: ");
System.out.println("Name: " + studentName);
System.out.println("Roll No: " + studentRollNo);
}
}
Step 3
创建控制器。
Create Controller.
StudentController.java
public class StudentController {
private Student model;
private StudentView view;
public StudentController(Student model, StudentView view){
this.model = model;
this.view = view;
}
public void setStudentName(String name){
model.setName(name);
}
public String getStudentName(){
return model.getName();
}
public void setStudentRollNo(String rollNo){
model.setRollNo(rollNo);
}
public String getStudentRollNo(){
return model.getRollNo();
}
public void updateView(){
view.printStudentDetails(model.getName(), model.getRollNo());
}
}
Step 4
使用 StudentController 方法来演示 MVC 设计模式的用法。
Use the StudentController methods to demonstrate MVC design pattern usage.
MVCPatternDemo.java
public class MVCPatternDemo {
public static void main(String[] args) {
//fetch student record based on his roll no from the database
Student model = retriveStudentFromDatabase();
//Create a view : to write student details on console
StudentView view = new StudentView();
StudentController controller = new StudentController(model, view);
controller.updateView();
//update model data
controller.setStudentName("John");
controller.updateView();
}
private static Student retriveStudentFromDatabase(){
Student student = new Student();
student.setName("Robert");
student.setRollNo("10");
return student;
}
}
Business Delegate Pattern
业务委托模式用于分离表示层和业务层。主要用于减少表示层代码中与业务层代码进行通信或远程查找功能。我们在业务层中具有下列实体。
Business Delegate Pattern is used to decouple presentation tier and business tier. It is basically use to reduce communication or remote lookup functionality to business tier code in presentation tier code. In business tier we’ve following entities.
-
Client - Presentation tier code may be JSP, servlet or UI java code.
-
Business Delegate - A single entry point class for client entities to provide access to Business Service methods.
-
LookUp Service - Lookup service object is responsible to get relative business implementation and provide business object access to business delegate object.
-
Business Service - Business Service interface. Concrete classes implements this business service to provide actual business implementation logic.
Implementation
我们将创建一个 Client、BusinessDelegate、BusinessService、LookUpService、JMSService 和 EJBService,它们表示业务委托模式的各个实体。
We’re going to create a Client, BusinessDelegate, BusinessService, LookUpService, JMSService and EJBService representing various entities of Business Delegate pattern.
我们的演示类 BusinessDelegatePatternDemo 将使用 BusinessDelegate 和 Client 来演示业务委托模式的使用。
BusinessDelegatePatternDemo, our demo class will use BusinessDelegate and Client to demonstrate use of Business Delegate pattern.
Step 1
创建 BusinessService 界面。
Create BusinessService Interface.
BusinessService.java
public interface BusinessService {
public void doProcessing();
}
Step 2
创建具体服务类。
Create Concreate Service Classes.
EJBService.java
public class EJBService implements BusinessService {
@Override
public void doProcessing() {
System.out.println("Processing task by invoking EJB Service");
}
}
JMSService.java
public class JMSService implements BusinessService {
@Override
public void doProcessing() {
System.out.println("Processing task by invoking JMS Service");
}
}
Step 3
创建业务查找服务。
Create Business Lookup Service.
BusinessLookUp.java
public class BusinessLookUp {
public BusinessService getBusinessService(String serviceType){
if(serviceType.equalsIgnoreCase("EJB")){
return new EJBService();
}else {
return new JMSService();
}
}
}
Step 4
创建业务委托。
Create Business Delegate.
BusinessLookUp.java
public class BusinessDelegate {
private BusinessLookUp lookupService = new BusinessLookUp();
private BusinessService businessService;
private String serviceType;
public void setServiceType(String serviceType){
this.serviceType = serviceType;
}
public void doTask(){
businessService = lookupService.getBusinessService(serviceType);
businessService.doProcessing();
}
}
Step 5
创建客户端。
Create Client.
Student.java
public class Client {
BusinessDelegate businessService;
public Client(BusinessDelegate businessService){
this.businessService = businessService;
}
public void doTask(){
businessService.doTask();
}
}
Step 6
使用 BusinessDelegate 和 Client 类演示业务委托模式。
Use BusinessDelegate and Client classes to demonstrate Business Delegate pattern.
BusinessDelegatePatternDemo.java
public class BusinessDelegatePatternDemo {
public static void main(String[] args) {
BusinessDelegate businessDelegate = new BusinessDelegate();
businessDelegate.setServiceType("EJB");
Client client = new Client(businessDelegate);
client.doTask();
businessDelegate.setServiceType("JMS");
client.doTask();
}
}
Composite Entity Pattern
复合实体模式用于 EJB 持久性机制。复合实体是一个 EJB 实体 Bean,它表示一个对象图。当更新复合实体时,由 EJB 实体 Bean 管理的内部相关对象 Bean 会自动得到更新。下面是复合实体 Bean 中的参与者。
Composite Entity pattern is used in EJB persistence mechanism. A Composite entity is an EJB entity bean which represents a graph of objects. When a composite entity is updated, internally dependent objects beans get updated automatically as being managed by EJB entity bean. Following are the participants in Composite Entity Bean.
-
Composite Entity - It is primary entity bean.It can be coarse grained or can contain a coarse grained object to be used for persistence purpose.
-
Coarse-Grained Object -This object contains dependent objects. It has its own life cycle and also manages life cycle of dependent objects.
-
Dependent Object - Dependent objects is an object which depends on Coarse-Grained object for its persistence lifecycle.
-
Strategies - Strategies represents how to implement a Composite Entity.
Implementation
我们将创建充当 CompositeEntity 的 CompositeEntity 对象。CoarseGrainedObject 将是一个包含相关对象的类。我们的演示类 CompositeEntityPatternDemo 将使用 Client 类演示复合实体模式的使用。
We’re going to create CompositeEntity object acting as CompositeEntity. CoarseGrainedObject will be a class which contains dependent objects. CompositeEntityPatternDemo, our demo class will use Client class to demonstrate use of Composite Entity pattern.
Step 1
创建相关对象。
Create Dependent Objects.
DependentObject1.java
public class DependentObject1 {
private String data;
public void setData(String data){
this.data = data;
}
public String getData(){
return data;
}
}
DependentObject2.java
public class DependentObject2 {
private String data;
public void setData(String data){
this.data = data;
}
public String getData(){
return data;
}
}
Step 2
创建粗粒度对象。
Create Coarse Grained Object.
CoarseGrainedObject.java
public class CoarseGrainedObject {
DependentObject1 do1 = new DependentObject1();
DependentObject2 do2 = new DependentObject2();
public void setData(String data1, String data2){
do1.setData(data1);
do2.setData(data2);
}
public String[] getData(){
return new String[] {do1.getData(),do2.getData()};
}
}
Step 3
创建复合实体。
Create Composite Entity.
CompositeEntity.java
public class CompositeEntity {
private CoarseGrainedObject cgo = new CoarseGrainedObject();
public void setData(String data1, String data2){
cgo.setData(data1, data2);
}
public String[] getData(){
return cgo.getData();
}
}
Step 4
创建客户端类以使用复合实体。
Create Client class to use Composite Entity.
Client.java
public class Client {
private CompositeEntity compositeEntity = new CompositeEntity();
public void printData(){
for (int i = 0; i < compositeEntity.getData().length; i++) {
System.out.println("Data: " + compositeEntity.getData()[i]);
}
}
public void setData(String data1, String data2){
compositeEntity.setData(data1, data2);
}
}
Step 5
使用 Client 来演示 Composite Entity 设计模式用法。
Use the Client to demonstrate Composite Entity design pattern usage.
CompositeEntityPatternDemo.java
public class CompositeEntityPatternDemo {
public static void main(String[] args) {
Client client = new Client();
client.setData("Test", "Data");
client.printData();
client.setData("Second Test", "Data1");
client.printData();
}
}
Data Access Object Pattern
数据访问对象模式或 DAO 模式用于将低级别数据访问 API 或操作从高级业务服务中分离。以下是数据访问对象模式中的参与者。
Data Access Object Pattern or DAO pattern is used to separate low level data accessing API or operations from high level business services. Following are the participants in Data Access Object Pattern.
-
Data Access Object Interface - This interface defines the standard operations to be performed on a model object(s).
-
Data Access Object concrete class -This class implements above interface. This class is responsible to get data from a datasource which can be database / xml or any other storage mechanism.
-
Model Object or Value Object - This object is simple POJO containing get/set methods to store data retrieved using DAO class.
Implementation
我们将创建一个充当模型或值对象的 Student 对象。StudentDao 是数据访问对象接口。StudentDaoImpl 是实现数据访问对象接口的具体类。我们的演示类 DaoPatternDemo 将使用 StudentDao 演示数据访问对象模式的使用。
We’re going to create a Student object acting as a Model or Value Object.StudentDao is Data Access Object Interface.StudentDaoImpl is concrete class implementing Data Access Object Interface. DaoPatternDemo, our demo class will use StudentDao demonstrate use of Data Access Object pattern.
Step 1
创建值对象。
Create Value Object.
Student.java
public class Student {
private String name;
private int rollNo;
Student(String name, int rollNo){
this.name = name;
this.rollNo = rollNo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getRollNo() {
return rollNo;
}
public void setRollNo(int rollNo) {
this.rollNo = rollNo;
}
}
Step 2
创建数据访问对象接口。
Create Data Access Object Interface.
StudentDao.java
import java.util.List;
public interface StudentDao {
public List<Student> getAllStudents();
public Student getStudent(int rollNo);
public void updateStudent(Student student);
public void deleteStudent(Student student);
}
Step 3
创建实现上述接口的具体类。
Create concreate class implementing above interface.
StudentDaoImpl.java
import java.util.ArrayList;
import java.util.List;
public class StudentDaoImpl implements StudentDao {
//list is working as a database
List<Student> students;
public StudentDaoImpl(){
students = new ArrayList<Student>();
Student student1 = new Student("Robert",0);
Student student2 = new Student("John",1);
students.add(student1);
students.add(student2);
}
@Override
public void deleteStudent(Student student) {
students.remove(student.getRollNo());
System.out.println("Student: Roll No " + student.getRollNo()
+", deleted from database");
}
//retrive list of students from the database
@Override
public List<Student> getAllStudents() {
return students;
}
@Override
public Student getStudent(int rollNo) {
return students.get(rollNo);
}
@Override
public void updateStudent(Student student) {
students.get(student.getRollNo()).setName(student.getName());
System.out.println("Student: Roll No " + student.getRollNo()
+", updated in the database");
}
}
Step 4
使用 StudentDao 来演示数据访问对象模式用法。
Use the StudentDao to demonstrate Data Access Object pattern usage.
CompositeEntityPatternDemo.java
public class DaoPatternDemo {
public static void main(String[] args) {
StudentDao studentDao = new StudentDaoImpl();
//print all students
for (Student student : studentDao.getAllStudents()) {
System.out.println("Student: [RollNo : "
+student.getRollNo()+", Name : "+student.getName()+" ]");
}
//update student
Student student =studentDao.getAllStudents().get(0);
student.setName("Michael");
studentDao.updateStudent(student);
//get the student
studentDao.getStudent(0);
System.out.println("Student: [RollNo : "
+student.getRollNo()+", Name : "+student.getName()+" ]");
}
}
Front Controller Pattern
前端控制器设计模式用于提供集中式请求处理机制,以便所有请求都由单个处理程序处理。此处理程序可以执行身份验证/授权/请求日志记录或跟踪,然后将请求传递到相应的处理程序。以下是这种设计模式的实体。
The front controller design pattern is used to provide a centralized request handling mechanism so that all requests will be handled by a single handler. This handler can do the authentication/ authorization/ logging or tracking of request and then pass the requests to corresponding handlers. Following are the entities of this type of design pattern.
-
Front Controller - Single handler for all kind of request coming to the application (either web based/ desktop based).
-
Dispatcher - Front Controller may use a dispatcher object which can dispatch the request to corresponding specific handler.
-
View - Views are the object for which the requests are made.
Implementation
我们将创建一个 FrontController、Dispatcher,它们分别充当前端控制器和分发器。HomeView 和 StudentView 表示前端控制器可以接收请求的各种视图。
We’re going to create a FrontController,Dispatcher to act as Front Controller and Dispatcher correspondingly. HomeView and StudentView represent various views for which requests can come to front controller.
我们的演示类 FrontControllerPatternDemo 将使用 FrontController 来演示前端控制器设计模式。
FrontControllerPatternDemo, our demo class will use FrontController ato demonstrate Front Controller Design Pattern.
Step 1
创建视图。
Create Views.
HomeView.java
public class HomeView {
public void show(){
System.out.println("Displaying Home Page");
}
}
StudentView.java
public class StudentView {
public void show(){
System.out.println("Displaying Student Page");
}
}
Step 2
创建调度中心。
Create Dispatcher.
Dispatcher.java
public class Dispatcher {
private StudentView studentView;
private HomeView homeView;
public Dispatcher(){
studentView = new StudentView();
homeView = new HomeView();
}
public void dispatch(String request){
if(request.equalsIgnoreCase("STUDENT")){
studentView.show();
}else{
homeView.show();
}
}
}
Step 3
创建前端控制器
Create FrontController
Context.java
public class FrontController {
private Dispatcher dispatcher;
public FrontController(){
dispatcher = new Dispatcher();
}
private boolean isAuthenticUser(){
System.out.println("User is authenticated successfully.");
return true;
}
private void trackRequest(String request){
System.out.println("Page requested: " + request);
}
public void dispatchRequest(String request){
//log each request
trackRequest(request);
//authenticate the user
if(isAuthenticUser()){
dispatcher.dispatch(request);
}
}
}
Step 4
使用前端控制器演示前端控制器设计模式。
Use the FrontController to demonstrate Front Controller Design Pattern.
FrontControllerPatternDemo.java
public class FrontControllerPatternDemo {
public static void main(String[] args) {
FrontController frontController = new FrontController();
frontController.dispatchRequest("HOME");
frontController.dispatchRequest("STUDENT");
}
}
Intercepting Filter Pattern
当我们希望对请求或应用程序的响应进行一些预处理/后处理时,将使用拦截过滤器设计模式。在将请求传递给实际目标应用程序之前,对请求定义并应用过滤器。过滤器可以对请求进行身份验证/授权/记录或跟踪,然后将请求传递给相应的处理程序。以下是此类设计模式的实体。
The intercepting filter design pattern is used when we want to do some pre-processing / post-processing with request or response of the application. Filters are defined and applied on the request before passing the request to actual target application. Filters can do the authentication/ authorization/ logging or tracking of request and then pass the requests to corresponding handlers. Following are the entities of this type of design pattern.
-
Filter - Filter which will perform certain task prior or after execution of request by request handler.
-
Filter Chain - Filter Chain carries multiple filters and help to execute them in defined order on target.
-
Target - Target object is the request handler
-
Filter Manager - Filter Manager manages the filters and Filter Chain.
-
Client - Client is the object who sends request to the Target object.
Implementation
我们将创建一个过滤器链、过滤器管理程序、目标和客户端作为代表实体的不同对象。AuthenticationFilter 和 DebugFilter 表示具体过滤器。
We’re going to create a FilterChain,FilterManager, Target, Client as various objects representing our entities.AuthenticationFilter and DebugFilter represents concrete filters.
InterceptingFilterDemo 我们的演示类将使用客户端演示拦截过滤器设计模式。
InterceptingFilterDemo, our demo class will use Client to demonstrate Intercepting Filter Design Pattern.
Step 1
创建过滤器界面。
Create Filter interface.
Filter.java
public interface Filter {
public void execute(String request);
}
Step 2
创建具体过滤器。
Create concrete filters.
AuthenticationFilter.java
public class AuthenticationFilter implements Filter {
public void execute(String request){
System.out.println("Authenticating request: " + request);
}
}
DebugFilter.java
public class DebugFilter implements Filter {
public void execute(String request){
System.out.println("request log: " + request);
}
}
Step 3
创建目标
Create Target
Target.java
public class Target {
public void execute(String request){
System.out.println("Executing request: " + request);
}
}
Step 4
创建过滤器链
Create Filter Chain
FilterChain.java
import java.util.ArrayList;
import java.util.List;
public class FilterChain {
private List<Filter> filters = new ArrayList<Filter>();
private Target target;
public void addFilter(Filter filter){
filters.add(filter);
}
public void execute(String request){
for (Filter filter : filters) {
filter.execute(request);
}
target.execute(request);
}
public void setTarget(Target target){
this.target = target;
}
}
Step 5
创建过滤器管理程序
Create Filter Manager
FilterManager.java
public class FilterManager {
FilterChain filterChain;
public FilterManager(Target target){
filterChain = new FilterChain();
filterChain.setTarget(target);
}
public void setFilter(Filter filter){
filterChain.addFilter(filter);
}
public void filterRequest(String request){
filterChain.execute(request);
}
}
Step 6
创建客户端
Create Client
Client.java
public class Client {
FilterManager filterManager;
public void setFilterManager(FilterManager filterManager){
this.filterManager = filterManager;
}
public void sendRequest(String request){
filterManager.filterRequest(request);
}
}
Step 7
使用客户端演示拦截过滤器设计模式。
Use the Client to demonstrate Intercepting Filter Design Pattern.
FrontControllerPatternDemo.java
public class InterceptingFilterDemo {
public static void main(String[] args) {
FilterManager filterManager = new FilterManager(new Target());
filterManager.setFilter(new AuthenticationFilter());
filterManager.setFilter(new DebugFilter());
Client client = new Client();
client.setFilterManager(filterManager);
client.sendRequest("HOME");
}
}
Service Locator Pattern
在使用 JNDI 查找定位各种服务时,使用服务定位器设计模式。考虑到为服务查找 JNDI 的高成本,Service Locator 模式利用缓存技术。第一次需要服务时,Service Locator 会在 JNDI 中查找并缓存服务对象。通过 Service Locator 进一步查找或相同的服务在其缓存中进行,极大地提高了应用程序的性能。以下是这种设计模式的实体。
The service locator design pattern is used when we want to locate various services using JNDI lookup. Considering high cost of looking up JNDI for a service, Service Locator pattern makes use of caching technique. For the first time a service is required, Service Locator looks up in JNDI and caches the service object. Further lookup or same service via Service Locator is done in its cache which improves the performance of application to great extent. Following are the entities of this type of design pattern.
-
Service - Actual Service which will process the request. Reference of such service is to be looked upon in JNDI server.
-
Context / Initial Context -JNDI Context, carries the reference to service used for lookup purpose.
-
Service Locator - Service Locator is a single point of contact to get services by JNDI lookup, caching the services.
-
Cache - Cache to store references of services to reuse them
-
Client - Client is the object who invokes the services via ServiceLocator.
Implementation
我们将创建一个 ServiceLocator、InitialContext、Cache、Service 作为表示我们实体的各种对象。Service1 和 Service2 表示具体服务。
We’re going to create a ServiceLocator,InitialContext, Cache, Service as various objects representing our entities.Service1 and Service2 represents concrete services.
ServiceLocatorPatternDemo,我们的演示类在此充当客户端,并将使用 ServiceLocator 演示服务定位器设计模式。
ServiceLocatorPatternDemo, our demo class is acting as a client here and will use ServiceLocator to demonstrate Service Locator Design Pattern.
Step 1
创建服务接口。
Create Service interface.
Service.java
public interface Service {
public String getName();
public void execute();
}
Step 2
创建具体服务。
Create concrete services.
Service1.java
public class Service1 implements Service {
public void execute(){
System.out.println("Executing Service1");
}
@Override
public String getName() {
return "Service1";
}
}
Service2.java
public class Service2 implements Service {
public void execute(){
System.out.println("Executing Service2");
}
@Override
public String getName() {
return "Service2";
}
}
Step 3
为 JNDI 查找创建初始上下文
Create InitialContext for JNDI lookup
InitialContext.java
public class InitialContext {
public Object lookup(String jndiName){
if(jndiName.equalsIgnoreCase("SERVICE1")){
System.out.println("Looking up and creating a new Service1 object");
return new Service1();
}else if (jndiName.equalsIgnoreCase("SERVICE2")){
System.out.println("Looking up and creating a new Service2 object");
return new Service2();
}
return null;
}
}
Step 4
创建缓存
Create Cache
Cache.java
import java.util.ArrayList;
import java.util.List;
public class Cache {
private List<Service> services;
public Cache(){
services = new ArrayList<Service>();
}
public Service getService(String serviceName){
for (Service service : services) {
if(service.getName().equalsIgnoreCase(serviceName)){
System.out.println("Returning cached "+serviceName+" object");
return service;
}
}
return null;
}
public void addService(Service newService){
boolean exists = false;
for (Service service : services) {
if(service.getName().equalsIgnoreCase(newService.getName())){
exists = true;
}
}
if(!exists){
services.add(newService);
}
}
}
Step 5
创建服务定位器
Create Service Locator
ServiceLocator.java
public class ServiceLocator {
private static Cache cache;
static {
cache = new Cache();
}
public static Service getService(String jndiName){
Service service = cache.getService(jndiName);
if(service != null){
return service;
}
InitialContext context = new InitialContext();
Service service1 = (Service)context.lookup(jndiName);
cache.addService(service1);
return service1;
}
}
Step 6
使用 ServiceLocator 演示服务定位器设计模式。
Use the ServiceLocator to demonstrate Service Locator Design Pattern.
ServiceLocatorPatternDemo.java
public class ServiceLocatorPatternDemo {
public static void main(String[] args) {
Service service = ServiceLocator.getService("Service1");
service.execute();
service = ServiceLocator.getService("Service2");
service.execute();
service = ServiceLocator.getService("Service1");
service.execute();
service = ServiceLocator.getService("Service2");
service.execute();
}
}
Transfer Object Pattern
传输对象模式用于希望一次性从客户端向服务器传递具有多个属性的数据时。传输对象也称为值对象。传输对象是一个简单的 POJO 类,它拥有 getter/setter 方法,并且可以序列化,以便通过网络进行传输。它没有任何行为。服务器端业务类通常从数据库获取数据并填充 POJO,然后将其发送到客户端或按值传递。对于客户端而言,传输对象是只读的。客户端可以创建自己的传输对象并将其传递给服务器,以便一次性更新数据库中的值。以下是该类型设计模式的实体。
The Transfer Object pattern is used when we want to pass data with multiple attributes in one shot from client to server. Transfer object is also known as Value Object. Transfer Object is a simple POJO class having getter/setter methods and is serializable so that it can be transferred over the network. It do not have any behavior. Server Side business class normally fetches data from the database and fills the POJO and send it to the client or pass it by value. For client, transfer object is read-only. Client can create its own transfer object and pass it to server to update values in database in one shot. Following are the entities of this type of design pattern.
-
Business Object - Business Service which fills the Transfer Object with data.
-
Transfer Object -Simple POJO, having methods to set/get attributes only.
-
Client - Client either requests or sends the Transfer Object to Business Object.
Implementation
我们将创建 StudentBO 作为业务对象,创建 Student 作为传输对象来表示我们的实体。
We’re going to create a StudentBO as Business Object,Student as Transfer Object representing our entities.
TransferObjectPatternDemo,我们的演示类在这里充当客户端,并将使用 StudentBO 和 Student 来演示传输对象设计模式。
TransferObjectPatternDemo, our demo class is acting as a client here and will use StudentBO and Student to demonstrate Transfer Object Design Pattern.
Step 1
创建传输对象。
Create Transfer Object.
StudentVO.java
public class StudentVO {
private String name;
private int rollNo;
StudentVO(String name, int rollNo){
this.name = name;
this.rollNo = rollNo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getRollNo() {
return rollNo;
}
public void setRollNo(int rollNo) {
this.rollNo = rollNo;
}
}
Step 2
创建业务对象。
Create Business Object.
StudentBO.java
import java.util.ArrayList;
import java.util.List;
public class StudentBO {
//list is working as a database
List<StudentVO> students;
public StudentBO(){
students = new ArrayList<StudentVO>();
StudentVO student1 = new StudentVO("Robert",0);
StudentVO student2 = new StudentVO("John",1);
students.add(student1);
students.add(student2);
}
public void deleteStudent(StudentVO student) {
students.remove(student.getRollNo());
System.out.println("Student: Roll No "
+ student.getRollNo() +", deleted from database");
}
//retrive list of students from the database
public List<StudentVO> getAllStudents() {
return students;
}
public StudentVO getStudent(int rollNo) {
return students.get(rollNo);
}
public void updateStudent(StudentVO student) {
students.get(student.getRollNo()).setName(student.getName());
System.out.println("Student: Roll No "
+ student.getRollNo() +", updated in the database");
}
}
Step 3
使用 StudentBO 来演示传输对象设计模式。
Use the StudentBO to demonstrate Transfer Object Design Pattern.
TransferObjectPatternDemo.java
public class TransferObjectPatternDemo {
public static void main(String[] args) {
StudentBO studentBusinessObject = new StudentBO();
//print all students
for (StudentVO student : studentBusinessObject.getAllStudents()) {
System.out.println("Student: [RollNo : "
+student.getRollNo()+", Name : "+student.getName()+" ]");
}
//update student
StudentVO student =studentBusinessObject.getAllStudents().get(0);
student.setName("Michael");
studentBusinessObject.updateStudent(student);
//get the student
studentBusinessObject.getStudent(0);
System.out.println("Student: [RollNo : "
+student.getRollNo()+", Name : "+student.getName()+" ]");
}
}