目录

Design Patterns - 快速指南

设计模式代表了经验丰富的面向对象软件开发人员使用的最佳实践。 设计模式是软件开发人员在软件开发过程中遇到的一般问题的解决方 这些解决方案是在相当长的一段时间内由众多软件开发人员通过反复试验获得的。

什么是四人帮(GOF)?

1994年,四位作者Erich Gamma,Richard Helm,Ralph Johnson和John Vlissides出版了一本名为“ Design Patterns - Elements of Reusable Object-Oriented Software ”的书,该书启动了软件开发中的设计模式概念。

这些作者统称为Gang of Four (GOF) 。 根据这些作者,设计模式主要基于面向对象设计的以下原则。

  • 编程到接口而不是实现

  • 赞成对象组合而不是继承

设计模式的使用

设计模式在软件开发中有两个主要用途。

开发人员的通用平台

设计模式提供标准术语,并且特定于特定场景。 例如,单例设计模式表示单个对象的使用,因此所有熟悉单一设计模式的开发人员都将使用单个对象,并且他们可以告诉彼此程序遵循单一模式。

最佳实践

设计模式已经发展了很长一段时间,它们为软件开发过程中遇到的某些问题提供了最佳解决方案。 学习这些模式可以帮助没有经验的开发人员以简单快捷的方式学习软件设计。

设计模式的类型

根据设计模式参考书“ Design Patterns - Elements of Reusable Object-Oriented Software ,有23种设计模式。 这些模式可分为三类:创造模式,结构模式和行为模式。 我们还将讨论另一类设计模式:J2EE设计模式。

SN 模式和描述
1 Creational Patterns这些设计模式提供了在隐藏创建逻辑的同时创建对象的方法,而不是使用new运算符直接实例化对象。 这使程序在决定需要为给定用例创建哪些对象时具有更大的灵活性。
2 Structural Patterns这些设计模式涉及类和对象组成。 继承的概念用于组合接口并定义组合对象以获得新功能的方法。
3 Behavioral Patterns这些设计模式特别关注对象之间的通信。
4 J2EE Patterns这些设计模式特别关注表示层。 这些模式由Sun Java Center识别。

Factory Pattern

工厂模式是Java中最常用的设计模式之一。 这种类型的设计模式属于创建模式,因为此模式提供了创建对象的最佳方法之一。

在Factory模式中,我们创建对象而不将创建逻辑暴露给客户端,并使用公共接口引用新创建的对象。

实现 (Implementation)

我们将创建一个Shape接口和实现Shape接口的具体类。 工厂类ShapeFactory被定义为下一步。

FactoryPatternDemo ,我们的演示类将使用ShapeFactory来获取Shape对象。 它会将信息( CIRCLE/RECTANGLE/SQUARE )传递给ShapeFactory以获取所需的对象类型。

工厂模式UML图

Step 1

创建一个界面。

Shape.java

public interface Shape {
   void draw();
}

Step 2

创建实现相同接口的具体类。

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

创建工厂以根据给定信息生成具体类的对象。

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

使用Factory通过传递类型等信息来获取具体类的对象。

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();
   }
}

Step 5

验证输出。

Inside Circle::draw() method.
Inside Rectangle::draw() method.
Inside Square::draw() method.

Abstract Factory Pattern

抽象工厂模式围绕一个超级工厂工作,创建其他工厂。 这家工厂也被称为工厂工厂。 这种类型的设计模式属于创建模式,因为此模式提供了创建对象的最佳方法之一。

在抽象工厂模式中,接口负责创建相关对象的工厂,而无需显式指定其类。 每个生成的工厂都可以按照工厂模式提供对象。

实现 (Implementation)

我们将创建一个ShapeColor接口以及实现这些接口的具体类。 我们将创建一个抽象工厂类AbstractFactory作为下一步。 工厂类ShapeFactoryColorFactory是在每个工厂扩展AbstractFactory地方定义的。 将创建工厂创建者/生成器类FactoryProducer

AbstractFactoryPatternDemo ,我们的演示类使用FactoryProducer来获取AbstractFactory对象。 它会将信息( CIRCLE/RECTANGLE/SQUARE for Shape )传递给AbstractFactory以获取它所需的对象类型。 它还将信息( ColorRED/GREEN/BLUE )传递给AbstractFactory以获取所需对象的类型。

抽象工厂模式UML图

Step 1

为Shapes创建一个界面。

Shape.java

public interface Shape {
   void draw();
}

Step 2

创建实现相同接口的具体类。

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

为Colors创建一个界面。

Color.java

public interface Color {
   void fill();
}

Step4

创建实现相同接口的具体类。

Red.java

public class Red implements Color {
   @Override
   public void fill() {
      System.out.println("Inside Red::fill() method.");
   }
}

Green.java

public class Green implements Color {
   @Override
   public void fill() {
      System.out.println("Inside Green::fill() method.");
   }
}

Blue.java

public class Blue implements Color {
   @Override
   public void fill() {
      System.out.println("Inside Blue::fill() method.");
   }
}

Step 5

创建一个Abstract类来获取Color和Shape对象的工厂。

AbstractFactory.java

public abstract class AbstractFactory {
   abstract Color getColor(String color);
   abstract Shape getShape(String shape) ;
}

Step 6

创建扩展AbstractFactory的Factory类,根据给定的信息生成具体类的对象。

ShapeFactory.java

public class ShapeFactory extends AbstractFactory {
   @Override
   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;
   }
   @Override
   Color getColor(String color) {
      return null;
   }
}

ColorFactory.java

public class ColorFactory extends AbstractFactory {
   @Override
   public Shape getShape(String shapeType){
      return null;
   }
   @Override
   Color getColor(String color) {
      if(color == null){
         return null;
      }		
      if(color.equalsIgnoreCase("RED")){
         return new Red();
      } else if(color.equalsIgnoreCase("GREEN")){
         return new Green();
      } else if(color.equalsIgnoreCase("BLUE")){
         return new Blue();
      }
      return null;
   }
}

Step 7

创建Factory生成器/生成器类以通过传递Shape或Color等信息来获取工厂

FactoryProducer.java

public class FactoryProducer {
   public static AbstractFactory getFactory(String choice){
      if(choice.equalsIgnoreCase("SHAPE")){
         return new ShapeFactory();
      } else if(choice.equalsIgnoreCase("COLOR")){
         return new ColorFactory();
      }
      return null;
   }
}

Step 8

使用FactoryProducer获取AbstractFactory,以便通过传递类型等信息来获取具体类的工厂。

AbstractFactoryPatternDemo.java

public class AbstractFactoryPatternDemo {
   public static void main(String[] args) {
      //get shape factory
      AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");
      //get an object of Shape Circle
      Shape shape1 = shapeFactory.getShape("CIRCLE");
      //call draw method of Shape Circle
      shape1.draw();
      //get an object of Shape Rectangle
      Shape shape2 = shapeFactory.getShape("RECTANGLE");
      //call draw method of Shape Rectangle
      shape2.draw();
      //get an object of Shape Square 
      Shape shape3 = shapeFactory.getShape("SQUARE");
      //call draw method of Shape Square
      shape3.draw();
      //get color factory
      AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");
      //get an object of Color Red
      Color color1 = colorFactory.getColor("RED");
      //call fill method of Red
      color1.fill();
      //get an object of Color Green
      Color color2 = colorFactory.getColor("Green");
      //call fill method of Green
      color2.fill();
      //get an object of Color Blue
      Color color3 = colorFactory.getColor("BLUE");
      //call fill method of Color Blue
      color3.fill();
   }
}

Step 9

验证输出。

Inside Circle::draw() method.
Inside Rectangle::draw() method.
Inside Square::draw() method.
Inside Red::fill() method.
Inside Green::fill() method.
Inside Blue::fill() method.

Singleton Pattern

单例模式是Java中最简单的设计模式之一。 这种类型的设计模式属于创建模式,因为此模式提供了创建对象的最佳方式之一。

此模式涉及一个类,它负责创建自己的对象,同时确保只创建单个对象。 此类提供了一种访问其唯一对象的方法,该对象可以直接访问,而无需实例化该类的对象。

实现 (Implementation)

我们将创建一个SingleObject类。 SingleObject类将其构造函数作为私有,并具有自身的静态实例。

SingleObject类提供了一个静态方法来将其静态实例传递给外部世界。 SingletonPatternDemo ,我们的演示类将使用SingleObject类来获取SingleObject对象。

单例模式UML图

Step 1

创建一个Singleton类。

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

从单例类中获取唯一的对象。

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();
   }
}

Step 3

验证输出。

Hello World!

Builder Pattern

构建器模式使用简单对象并使用逐步方法构建复杂对象。 这种类型的设计模式属于创建模式,因为此模式提供了创建对象的最佳方法之一。

Builder类逐步构建最终对象。 此构建器独立于其他对象。

实现 (Implementation)

我们考虑过快餐店的商业案例,其中典型的餐点可能是汉堡包和冷饮。 汉堡可以是蔬菜汉堡或鸡肉汉堡,将由包装纸包装。 冷饮可以是可乐或百事可乐,也可以装在一个瓶子里。

我们将创建一个Item接口,表示食物项目,例如汉堡包和冷饮,以及实现Item接口的具体类,以及代表食品项目包装的Packing接口和实现Packing接口的具体类,因为汉堡包装在包装和冷藏中饮料将被装入瓶中。

然后我们创建一个具有MealBuilderMealBuilderMeal类,通过组合Item来构建不同类型的Meal对象。 BuilderPatternDemo ,我们的演示类将使用MealBuilder构建一个Meal

生成器模式UML图

Step 1

创建表示食品和包装的接口项。

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接口的concreate类。

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

创建实现项接口的抽象类,提供默认功能。

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类的具体类

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类。

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对象的实际构建器类。

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来演示构建器模式。

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());
   }
}

Step 8

验证输出。

Veg Meal
Item : Veg Burger, Packing : Wrapper, Price : 25.0
Item : Coke, Packing : Bottle, Price : 30.0
Total Cost: 55.0
Non-Veg Meal
Item : Chicken Burger, Packing : Wrapper, Price : 50.5
Item : Pepsi, Packing : Bottle, Price : 35.0
Total Cost: 85.5

Prototype Pattern

原型模式是指在保持性能的同时创建重复对象。 这种类型的设计模式属于创建模式,因为此模式提供了创建对象的最佳方式之一。

此模式涉及实现原型接口,该接口告诉创建当前对象的克隆。 当直接创建对象成本高时使用此模式。 例如,在昂贵的数据库操作之后创建对象。 我们可以缓存对象,在下一个请求时返回其克隆,并在需要时更新数据库,从而减少数据库调用。

实现 (Implementation)

我们将创建一个抽象类Shape和扩展Shape类的具体类。 类ShapeCache被定义为下一步,它将形状对象存储在Hashtable并在请求时返回它们的克隆。

PrototypPatternDemo ,我们的演示类将使用ShapeCache类来获取Shape对象。

原型模式UML图

Step 1

创建一个实现Clonable接口的抽象类。

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

创建扩展上述类的具体类。

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

创建一个类以从数据库中获取concreate类并将它们存储在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类来获取存储在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());		
   }
}

Step 5

验证输出。

Shape : Circle
Shape : Square
Shape : Rectangle

Adapter Pattern

适配器模式充当两个不兼容接口之间的桥梁。 这种类型的设计模式属于结构模式,因为该模式结合了两个独立接口的功能。

此模式涉及单个类,该类负责连接独立或不兼容接口的功能。 一个真实的例子可能是读卡器的情况,它充当存储卡和笔记本电脑之间的适配器。 您将存储卡插入读卡器和读卡器插入笔记本电脑,以便通过笔记本电脑读取存储卡。

我们通过以下示例演示适配器模式的使用,其中音频播放器设备只能播放mp3文件并且想要使用能够播放vlc和mp4文件的高级音频播放器。

实现 (Implementation)

我们有一个接口MediaPlayer接口和一个实现MediaPlayer接口的具体类AudioPlayerAudioPlayer默认播放mp3格式的音频文件。

我们有另一个接口AdvancedMediaPlayer和实现AdvancedMediaPlayer接口的具体类。这些类可以播放vlc和mp4格式文件。

我们希望让AudioPlayer能播放其他格式。 为此,我们创建了一个适配器类MediaAdapter ,它实现了MediaPlayer接口,并使用AdvancedMediaPlayer对象来播放所需的格式。

AudioPlayer使用适配器类MediaAdapter传递所需的音频类型,而不知道可以播放所需格式的实际类。 AdapterPatternDemo ,我们的演示类将使用AudioPlayer类来播放各种格式。

适配器模式UML图

Step 1

为Media Player和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接口的具体类。

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接口的适配器类。

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接口的具体类。

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播放不同类型的音频格式。

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");
   }
}

Step 6

验证输出。

Playing mp3 file. Name: beyond the horizon.mp3
Playing mp4 file. Name: alone.mp4
Playing vlc file. Name: far far away.vlc
Invalid media. avi format not supported

Bridge Pattern

在我们需要将抽象与其实现分离的地方使用Bridge,以便两者可以独立变化。 这种类型的设计模式属于结构模式,因为这种模式通过在它们之间提供桥接结构来分离实现类和抽象类。

这种模式涉及一个接口,它充当一个桥梁,使具体类的功能独立于接口实现者类。 两种类型的类都可以在结构上进行更改而不会相互影响。

我们通过以下示例演示Bridge模式的使用,其中可以使用相同的抽象类方法但不同的桥实现者类以不同的颜色绘制圆。

实现 (Implementation)

我们有一个接口DrawAPI接口,它充当桥接器实现者和具体类RedCircleGreenCircle实现DrawAPI接口。 Shape是一个抽象类,将使用DrawAPI对象。 BridgePatternDemo ,我们的演示类将使用Shape类绘制不同的彩色圆圈。

桥模式UML图

Step 1

创建桥接器实现器接口。

DrawAPI.java

public interface DrawAPI {
   public void drawCircle(int radius, int x, int y);
}

Step 2

创建实现DrawAPI接口的具体桥实现者类。

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

Shape.java

public abstract class Shape {
   protected DrawAPI drawAPI;
   protected Shape(DrawAPI drawAPI){
      this.drawAPI = drawAPI;
   }
   public abstract void draw();	
}

Step 4

创建实现Shape接口的具体类。

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

使用ShapeDrawAPI类绘制不同的彩色圆圈。

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();
   }
}

Step 6

验证输出。

Drawing Circle[ color: red, radius: 10, x: 100, 100]
Drawing Circle[  color: green, radius: 10, x: 100, 100]

Filter/Criteria Pattern

过滤模式或标准模式是一种设计模式,使开发人员能够使用不同的标准过滤一组对象,并通过逻辑操作以分离的方式将它们链接在一起。 这种类型的设计模式属于结构模式,因为该模式结合了多个标准以获得单一标准。

实现 (Implementation)

我们将创建一个Person对象, Criteria接口和实现此接口的具体类来过滤Person对象列表。 CriteriaPatternDemo ,我们的演示类使用Criteria对象根据各种标准及其组合过滤Person对象列表。

过滤模式UML图

Step 1

创建要应用条件的类。

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创建一个界面。

Criteria.java

import java.util.List;
public interface Criteria {
   public List<Person> meetCriteria(List<Person> persons);
}

Step 3

创建实现Criteria接口的具体类。

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

使用不同的Criteria及其组合来过滤掉人员。

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

验证输出。

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

复合模式用于需要以与单个对象类似的方式处理一组对象的位置。 复合模式根据树结构组成对象,以表示部分以及整个层次结构。 这种类型的设计模式属于结构模式,因为此模式创建了一组对象的树结构。

此模式创建一个类包含其自己的对象组。 此类提供了修改其相同对象组的方法。

我们通过以下示例演示组织的员工层次结构,展示复合模式的使用。

实现 (Implementation)

我们有一个类Employee ,它充当复合模式actor类。 CompositePatternDemo ,我们的演示类将使用Employee类添加部门级层次结构并打印所有员工。

复合模式UML图

Step 1

创建具有Employee对象列表的Employee类。

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类创建和打印员工层次结构。

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

验证输出。

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模式的使用,其中我们将使用一些颜色装饰一个没有alter shape类的形状。

实现 (Implementation)

我们将创建一个Shape接口和实现Shape接口的具体类。 然后,我们创建一个抽象装饰器类ShapeDecorator实现Shape接口并将Shape对象作为其实例变量。

RedShapeDecorator是实现ShapeDecorator具体类。

DecoratorPatternDemo ,我们的演示类将使用RedShapeDecorator来装饰Shape对象。

装饰图案UML图

Step 1

创建一个界面。

Shape.java

public interface Shape {
   void draw();
}

Step 2

创建实现相同接口的具体类。

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接口的抽象装饰器类。

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类的具体装饰器类。

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对象。

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();
   }
}

Step 6

验证输出。

Circle with normal border
Shape: Circle
Circle of red border
Shape: Circle
Border Color: Red
Rectangle of red border
Shape: Rectangle
Border Color: Red

Facade Pattern

Facade模式隐藏了系统的复杂性,并为客户端提供了一个接口,客户端可以使用该接口访问系统。 这种类型的设计模式属于结构模式,因为这种模式为现有系统添加了一个接口以隐藏其复杂性。

此模式涉及单个类,它提供客户端所需的简化方法,并委托对现有系统类方法的调用。

实现 (Implementation)

我们将创建一个Shape接口和实现Shape接口的具体类。 Facade类ShapeMaker被定义为下一步。

ShapeMaker类使用具体类将用户调用委托给这些类。 FacadePatternDemo ,我们的演示类将使用ShapeMaker类来显示结果。

门面图案UML图

Step 1

创建一个界面。

Shape.java

public interface Shape {
   void draw();
}

Step 2

创建实现相同接口的具体类。

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

创建一个外观类。

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();
   }
}

Step 4

使用立面绘制各种类型的形状。

FacadePatternDemo.java

public class FacadePatternDemo {
   public static void main(String[] args) {
      ShapeMaker shapeMaker = new ShapeMaker();
      shapeMaker.drawCircle();
      shapeMaker.drawRectangle();
      shapeMaker.drawSquare();		
   }
}

Step 5

验证输出。

Circle::draw()
Rectangle::draw()
Square::draw()

Flyweight Pattern

Flyweight模式主要用于减少创建的对象数量,减少内存占用并提高性能。 这种类型的设计模式属于结构模式,因为该模式提供了减少对象数量的方法,从而改善了应用程序所需的对象结构

Flyweight模式尝试通过存储它们来重用已存在的类似对象,并在找不到匹配对象时创建新对象。 我们将通过绘制20个不同位置的圆圈来演示这种模式,但我们只创建5个对象。 只有5种颜色可用,因此颜色属性用于检查现有的Circle对象。

实现 (Implementation)

我们将创建一个Shape接口和实现Shape接口的具体类Circle 。 工厂类ShapeFactory被定义为下一步。

ShapeFactory有一个CircleHashMap ,其键作为Circle对象的颜色。 每当请求为ShapeFactory创建特定颜色的ShapeFactoryShapeFactory检查其HashMap的圆形对象,如果找到Circle对象,则返回该对象,否则创建一个新对象,存储在hashmap中以备将来使用并返回给客户端。

FlyWeightPatternDemo ,我们的演示类将使用ShapeFactory来获取Shape对象。 它会将信息( red/green/blue/ black/white )传递给ShapeFactory以获得所需颜色的圆圈。

Flyweight模式UML图

Step 1

创建一个界面。

Shape.java

public interface Shape {
   void draw();
}

Step 2

创建实现相同接口的具体类。

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

创建工厂以根据给定信息生成具体类的对象。

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通过传递颜色等信息来获取具体类的对象。

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

验证输出。

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

在代理模式中,类表示另一个类的功能。 这种类型的设计模式属于结构模式。

在代理模式中,我们创建具有原始对象的对象,以将其功能与外部世界接口。

实现 (Implementation)

我们将创建一个Image接口和实现Image接口的具体类。 ProxyImage是一个代理类,用于减少RealImage对象加载的内存占用。

ProxyPatternDemo ,我们的演示类将使用ProxyImage来获取Image对象以根据需要加载和显示。

代理模式UML图

Step 1

创建一个界面。

Image.java

public interface Image {
   void display();
}

Step 2

创建实现相同接口的具体类。

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类的对象。

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(); 	
   }
}

Step 4

验证输出。

Loading test_10mb.jpg
Displaying test_10mb.jpg
Displaying test_10mb.jpg

Chain of Responsibility Pattern

顾名思义,责任链模式为请求创建了一系列接收者对象。 此模式根据请求类型将请求的发送方和接收方解耦。 这种模式属于行为模式。

在此模式中,通常每个接收器包含对另一个接收器的引用。 如果一个对象无法处理请求,则它将该对象传递给下一个接收器,依此类推。

实现 (Implementation)

我们创建了一个具有一定日志记录级别的抽象类AbstractLogger 。 然后我们创建了三种扩展AbstractLogger的记录器。 每个记录器检查消息级别到其级别并相应地打印,否则不打印并将消息传递给下一个记录器。

责任链模式UML图

Step 1

创建一个抽象记录器类。

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

创建扩展记录器的具体类。

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

创建不同类型的记录器。 为每个记录器分配错误级别并设置下一个记录器。 每个记录器中的下一个记录器代表链的一部分。

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

验证输出。

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

命令模式是一种数据驱动的设计模式,属于行为模式类别。 请求作为命令包装在对象下并传递给调用者对象。 Invoker对象查找可以处理此命令的相应对象,并将该命令传递给相应的对象,该对象执行该命令。

实现 (Implementation)

我们创建了一个作为命令的接口Order 。 我们创建了一个充当请求的Stock类。 我们有具体的命令类BuyStockSellStock实现Order接口,它将进行实际的命令处理。 创建一个类Broker ,它充当调用者对象。 它可以接受订单和下订单。

Broker对象使用命令模式来识别哪个对象将根据命令类型执行哪个命令。 CommandPatternDemo ,我们的演示类将使用Broker类来演示命令模式。

命令模式UML图

Step 1

创建命令界面。

Order.java

public interface Order {
   void execute();
}

Step 2

创建一个请求类。

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接口的具体类。

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

创建命令调用程序类。

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类来获取和执行命令。

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();
   }
}

Step 6

验证输出。

Stock [ Name: ABC, Quantity: 10 ] bought
Stock [ Name: ABC, Quantity: 10 ] sold

Interpreter Pattern

解释器模式提供了评估语言语法或表达的方法。 这种模式属于行为模式。 此模式涉及实现表达式接口,该接口用于解释特定上下文。 此模式用于SQL解析,符号处理引擎等。

实现 (Implementation)

我们将创建一个接口Expression和实现Expression接口的具体类。 定义了一个类TerminalExpression ,它充当相关上下文的主要解释器。 其他类OrExpressionAndExpression用于创建组合表达式。

InterpreterPatternDemo ,我们的演示类将使用Expression类来创建规则并演示表达式的解析。

解释器模式UML图

Step 1

创建表达式界面。

Expression.java

public interface Expression {
   public boolean interpret(String context);
}

Step 2

创建实现上述接口的具体类。

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.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"));
   }
}

Step 4

验证输出。

John is male? true
Julie is a married women? true

Iterator Pattern

Iterator模式是Java和.Net编程环境中非常常用的设计模式。 此模式用于获取以顺序方式访问集合对象的元素的方法,而无需了解其基础表示。

迭代器模式属于行为模式类别。

实现 (Implementation)

我们将创建一个Iterator导航方法的Iterator接口和一个重新构造迭代器的Container接口。 实现Container接口的具体类将负责实现Iterator接口并使用它

IteratorPatternDemo ,我们的演示类将使用NamesRepository ,这是一个具体的类实现,用于在NamesRepository打印存储为集合的NamesRepository

迭代器模式UML图

Step 1

创建接口。

Iterator.java

public interface Iterator {
   public boolean hasNext();
   public Object next();
}

Container.java

public interface Container {
   public Iterator getIterator();
}

Step 2

创建实现Container接口的具体类。 该类具有实现Iterator接口的内部类NameIterator

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获取迭代器和打印名称。

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);
      } 	
   }
}

Step 4

验证输出。

Name : Robert
Name : John
Name : Julie
Name : Lora

Mediator Pattern

介体模式用于减少多个对象或类之间的通信复杂性。 此模式提供了一个中介类,它通常处理不同类之间的所有通信,并通过松散耦合支持代码的轻松可维护性。 中介模式属于行为模式类别。

实现 (Implementation)

我们通过聊天室的示例演示中介模式,其中多个用户可以向聊天室发送消息,聊天室负责向所有用户显示消息。 我们创建了两个类ChatRoomUserUser对象将使用ChatRoom方法来共享其消息。

MediatorPatternDemo ,我们的演示类将使用User对象来显示它们之间的通信。

中介模式UML图

Step 1

创建中介类。

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

创建用户类

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对象显示它们之间的通信。

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!");
   }
}

Step 4

验证输出。

Thu Jan 31 16:05:46 IST 2013 [Robert] : Hi! John!
Thu Jan 31 16:05:46 IST 2013 [John] : Hello! Robert!

Memento Pattern

Memento模式用于减少我们想要将对象的状态恢复到先前状态的位置。 纪念品模式属于行为模式类别。

实现 (Implementation)

Memento模式使用三个actor类。 Memento包含要恢复的对象的状态。 Originator在Memento对象和Caretaker对象中创建和存储状态,Caretaker对象负责从Memento恢复对象状态。 我们创建了MementoOriginatorCareTaker

MementoPatternDemo ,我们的演示类将使用CareTakerOriginator对象来显示对象状态的恢复。

纪念图案UML图

Step 1

创建Memento类。

Memento.java

public class Memento {
   private String state;
   public Memento(String state){
      this.state = state;
   }
   public String getState(){
      return state;
   }	
}

Step 2

创建Originator类

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课程

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

使用CareTakerOriginator对象。

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());
   }
}

Step 5

验证输出。

Current State: State #4
First saved State: State #2
Second saved State: State #3

Observer Pattern

当对象之间存在一对多关系时使用观察者模式,例如,如果修改了一个对象,则会自动通知其依赖对象。 观察者模式属于行为模式类别。

实现 (Implementation)

观察者模式使用三个actor类。 主题,观察者和客户。 Subject,一个对象,具有将观察者附加和取消附加到客户端对象的方法。 我们创建了类SubjectObserver抽象类和扩展Observer抽象类的具体类。

ObserverPatternDemo ,我们的演示类将使用Subject和具体的类对象来显示操作中的观察者模式。

观察者模式UML图

Step 1

创建主题类。

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

创建Observer类。

Observer.java

public abstract class Observer {
   protected Subject subject;
   public abstract void update();
}

Step 3

创建具体的观察者类

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

使用Subject和具体观察者对象。

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);
   }
}

Step 5

验证输出。

First state change: 15
Hex String: F
Octal String: 17
Binary String: 1111
Second state change: 10
Hex String: A
Octal String: 12
Binary String: 1010

State Pattern

在状态模式中,类行为会根据其状态而更改。 这种类型的设计模式属于行为模式。

在状态模式中,我们创建表示各种状态的对象和上下文对象,其行为随状态对象的变化而变化。

实现 (Implementation)

我们将创建一个定义动作的State接口和实现State接口的具体状态类。 Context是一个携带国家的阶级。

StaePatternDemo ,我们的演示类将使用Context和状态对象来根据它StaePatternDemo的状态类型演示Context行为的变化。

状态模式UML图

Step 1

创建一个界面。

Image.java

public interface State {
   public void doAction(Context context);
}

Step 2

创建实现相同接口的具体类。

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类。

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查看状态更改时的行为更改。

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());
   }
}

Step 5

验证输出。

Player is in start state
Start State
Player is in stop state
Stop State

Null Object Pattern

在Null Object模式中,null对象替换NULL对象实例的检查。 Null Object反映了不做任何关系,而不是检查是否为空值。 在数据不可用的情况下,此类Null对象还可用于提供默认行为。

在Null Object模式中,我们创建一个抽象类,指定要完成的各种操作,concreate扩展此类的类和一个null对象类,提供此类的任何实现,并将在我们需要检查null值的地方无用地使用。

实现 (Implementation)

我们将创建一个定义操作的AbstractCustomer抽象类,这里是客户的名称和扩展AbstractCustomer类的具体类。 创建工厂类CustomerFactory ,以根据传递给它的客户名称返回RealCustomerNullCustomer对象。

NullPatternDemo ,我们的演示类将使用CustomerFactory来演示Null Object模式的使用。

空对象模式UML图

Step 1

创建一个抽象类。

AbstractCustomer.java

public abstract class AbstractCustomer {
   protected String name;
   public abstract boolean isNil();
   public abstract String getName();
}

Step 2

创建扩展上述类的具体类。

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类。

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根据传递给它的客户名称获取RealCustomerNullCustomer对象。

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());
   }
}

Step 5

验证输出。

Customers
Rob
Not Available in Customer Database
Julie
Not Available in Customer Database

Strategy Pattern

在策略模式中,可以在运行时更改类行为或其算法。 这种类型的设计模式属于行为模式。

在策略模式中,我们创建表示各种策略的对象和根据其策略对象行为不同的上下文对象。 策略对象更改上下文对象的执行算法。

实现 (Implementation)

我们将创建一个定义动作的Strategy接口和实现Strategy接口的具体策略类。 Context是一个使用策略的类。

StrategyPatternDemo ,我们的演示类将使用Context和strategy对象来演示基于它部署或使用的策略的Context行为的变化。

策略模式UML图

Step 1

创建一个界面。

Strategy.java

public interface Strategy {
   public int doOperation(int num1, int num2);
}

Step 2

创建实现相同接口的具体类。

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类。

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时的行为更改。

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));
   }
}

Step 5

验证输出。

10 + 5 = 15
10 - 5 = 5
10 * 5 = 50

Template Pattern

在模板模式中,抽象类公开定义的方式/模板以执行其方法。 它的子类可以根据需要覆盖方法实现,但调用的方式与抽象类的定义相同。 此模式属于行为模式类别。

实现 (Implementation)

我们将创建一个Game抽象类,定义操作,模板方法设置为final,这样就无法覆盖它。 CricketFootball是具体的类扩展Game并覆盖其方法。

TemplatePatternDemo ,我们的演示类将使用Game来演示模板模式的使用。

模板模式UML图

Step 1

使用最终的模板方法创建一个抽象类。

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

创建扩展上述类的具体类。

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()来演示一种定义的游戏方式。

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();		
   }
}

Step 4

验证输出。

Cricket Game Initialized! Start playing.
Cricket Game Started. Enjoy the game!
Cricket Game Finished!
Football Game Initialized! Start playing.
Football Game Started. Enjoy the game!
Football Game Finished!

Visitor Pattern

在Visitor模式中,我们使用一个访问者类来更改元素类的执行算法。 通过这种方式,元素的执行算法可以随着访问者的变化而变化。 此模式属于行为模式类别。 根据模式,元素对象必须接受访问者对象,以便访问者对象处理元素对象上的操作。

实现 (Implementation)

我们将创建一个定义接受操作的ComputerPart接口。 KeyboardMouseMonitorComputer是实现ComputerPart接口的具体类。 我们将定义另一个接口ComputerPartVisitor ,它将定义一个访问者类操作。 Computer使用具体访问者做相应的动作。

VisitorPatternDemo ,我们的演示类将使用ComputerComputerPartVisitor类来演示访问者模式的使用。

访客模式UML图

Step 1

定义表示元素的接口。

ComputerPart.java

public interface class ComputerPart {
   public void accept(ComputerPartVisitor computerPartVisitor);
}

Step 2

创建扩展上述类的具体类。

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

定义代表访问者的界面。

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

创建实现上述类的具体访问者。

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显示Computer部分。

VisitorPatternDemo.java

public class VisitorPatternDemo {
   public static void main(String[] args) {
      ComputerPart computer = new Computer();
      computer.accept(new ComputerPartDisplayVisitor());
   }
}

Step 6

验证输出。

Displaying Mouse.
Displaying Keyboard.
Displaying Monitor.
Displaying Computer.

MVC Pattern

MVC Pattern代表模型 - 视图 - 控制器模式。 此模式用于分离应用程序的问题。

  • Model - 模型表示携带数据的对象或JAVA POJO。 如果控制器的数据发生变化,它也可以有更新控制器的逻辑

  • View - 视图表示模型包含的数据的可视化。

  • Controller - 控制器作用于模型和视图。 它控制数据流到模型对象,并在数据发生变化时更新视图。 它使View和Model分开。

实现 (Implementation)

我们将创建一个充当模型的Student对象。 StudentView将是一个可以在控制台上打印学生详细信息的视图类, StudentController是负责在Student对象中存储数据的控制器类,并相应地更新视图StudentView

MVCPatternDemo ,我们的演示类将使用StudentController来演示MVC模式的使用。

MVC模式UML图

Step 1

创建模型。

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

创建视图。

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

创建控制器。

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设计模式用法。

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;
   }
}

Step 5

验证输出。

Student: 
Name: Robert
Roll No: 10
Student: 
Name: Julie
Roll No: 10

Business Delegate Pattern

Business Delegate Pattern用于解耦表示层和业务层。 它基本上用于减少表示层代码中的业务层代码的通信或远程查找功能。 在业务层,我们遵循实体。

  • Client - 表示层代码可以是JSP,servlet或UI java代码。

  • Business Delegate - 客户实体提供对业务服务方法的访问的单一入口点类。

  • LookUp Service - 查找服务对象负责获取相关业务实现并提供业务对象访问业务委托对象。

  • Business Service - 商业服务界面。 具体类实现此业务服务以提供实际的业务实现逻辑。

实现 (Implementation)

我们将创建一个ClientBusinessDelegateBusinessServiceLookUpServiceJMSServiceEJBService代表Business Delegate模式的各种实体。

BusinessDelegatePatternDemo ,我们的演示类将使用BusinessDelegateClient来演示Business Delegate模式的使用。

业务代表模式UML图

Step 1

创建BusinessService接口。

BusinessService.java

public interface BusinessService {
   public void doProcessing();
}

Step 2

创建Concreate服务类。

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

创建业务查询服务。

BusinessLookUp.java

public class BusinessLookUp {
   public BusinessService getBusinessService(String serviceType){
      if(serviceType.equalsIgnoreCase("EJB")){
         return new EJBService();
      }else {
         return new JMSService();
      }
   }
}

Step 4

创建业务代表。

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

创建客户端。

Student.java

public class Client {
   BusinessDelegate businessService;
   public Client(BusinessDelegate businessService){
      this.businessService  = businessService;
   }
   public void doTask(){		
      businessService.doTask();
   }
}

Step 6

使用BusinessDelegate和Client类演示Business Delegate模式。

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();
   }
}

Step 7

验证输出。

Processing task by invoking EJB Service
Processing task by invoking JMS Service

Composite Entity Pattern

复合实体模式用于EJB持久性机制。 Composite实体是EJB实体bean,表示对象图。 更新复合实体时,内部相关对象bean会自动更新为EJB实体bean管理。 以下是Composite Entity Bean的参与者。

  • Composite Entity - 它是主要实体bean。它可以是粗粒度的,也可以包含粗粒度对象以用于持久性目的。

  • Coarse-Grained Object - 此对象包含依赖对象。 它有自己的生命周期,也管理依赖对象的生命周期。

  • Dependent Object - 依赖对象是一个对象,它依赖于Coarse-Grained对象的持久性生命周期。

  • Strategies - 策略表示如何实现复合实体。

实现 (Implementation)

我们将创建充当CompositeEntity的CompositeEntity对象。 CoarseGrainedObject将是一个包含依赖对象的类。 CompositeEntityPatternDemo ,我们的演示类将使用Client类来演示Composite Entity模式的使用。

复合实体模式UML图

Step 1

创建从属对象。

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

创建粗粒度对象。

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

创建复合实体。

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

创建客户端类以使用复合实体。

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演示复合实体设计模式用法。

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();
   }
}

Step 6

验证输出。

Data: Test
Data: Data
Data: Second Test
Data: Data1

Data Access Object Pattern

数据访问对象模式或DAO模式用于将低级数据访问API或操作与高级业务服务分开。 以下是数据访问对象模式的参与者。

  • Data Access Object Interface - 此接口定义要对模型对象执行的标准操作。

  • Data Access Object concrete class - 该类实现上面的接口。 此类负责从数据源获取数据,该数据源可以是database/xml或任何其他存储机制。

  • Model Object or Value Object - 此对象是包含get/set方法的简单POJO,用于存储使用DAO类检索的数据。

实现 (Implementation)

我们将创建一个充当模型或值对象的Student对象。 StudentDao是数据访问对象接口。 StudentDaoImpl是实现数据访问对象接口的具体类。 DaoPatternDemo ,我们的演示类将使用DaoPatternDemo演示使用Data Access Object模式。

数据访问对象模式UML图

Step 1

创建价值对象。

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

创建数据访问对象接口。

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

创建实现上面接口的concreate类。

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演示数据访问对象模式用法。

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()+" ]");		
   }
}

Step 5

验证输出。

Student: [RollNo : 0, Name : Robert ]
Student: [RollNo : 1, Name : John ]
Student: Roll No 0, updated in the database
Student: [RollNo : 0, Name : Michael ]

Front Controller Pattern

前端控制器设计模式用于提供集中的请求处理机制,以便所有请求将由单个处理程序处理。 此处理程序可以执行身份验证/授权/日志记录或跟踪请求,然后将请求传递给相应的处理程序。 以下是此类设计模式的实体。

  • Front Controller - 用于应用程序的所有类型请求的单个处理程序(基于Web /基于桌面)。

  • Dispatcher - Front Controller可以使用调度程序对象,该对象可以将请求分派给相应的特定处理程序。

  • View - 视图是发出请求的对象。

实现 (Implementation)

我们将创建一个FrontControllerDispatcher来相应地充当Front Controller和Dispatcher。 HomeViewStudentView代表各种视图,请求可以来自前端控制器。

FrontControllerPatternDemo ,我们的演示类将使用FrontController ato演示Front Controller Design Pattern。

前控制器模式UML图

Step 1

创建视图。

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

创建调度程序。

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

创建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

使用FrontController演示Front Controller设计模式。

FrontControllerPatternDemo.java

public class FrontControllerPatternDemo {
   public static void main(String[] args) {
      FrontController frontController = new FrontController();
      frontController.dispatchRequest("HOME");
      frontController.dispatchRequest("STUDENT");
   }
}

Step 5

验证输出。

Page requested: HOME
User is authenticated successfully.
Displaying Home Page
Page requested: STUDENT
User is authenticated successfully.
Displaying Student Page

Intercepting Filter Pattern

当我们想要对应用程序的请求或响应进行一些预处理/后处理时,使用拦截过滤器设计模式。 在将请求传递给实际目标应用程序之前,会在请求上定义和应用过滤器。 过滤器可以执行身份验证/授权/记录或跟踪请求,然后将请求传递给相应的处理程序。 以下是此类设计模式的实体。

  • Filter - 在请求处理程序执行请求之前或之后执行特定任务的过滤器。

  • Filter Chain - 过滤链带有多个过滤器,有助于在目标上按照定义的顺序执行它们。

  • Target - 目标对象是请求处理程序

  • Filter Manager - 过滤器管理器管理过滤器和过滤器链。

  • Client - 客户端是向Target对象发送请求的对象。

实现 (Implementation)

我们将创建一个FilterChainFilterManagerTargetClient作为代表我们实体的各种对象。 AuthenticationFilterDebugFilter表示具体的过滤器。

InterceptingFilterDemo ,我们的演示类将使用Client来演示拦截滤波器设计模式。

拦截过滤器模式UML图

Step 1

创建过滤器界面。

Filter.java

public interface Filter {
   public void execute(String request);
}

Step 2

创建具体过滤器。

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

创造目标

Target.java

public class Target {
   public void execute(String request){
      System.out.println("Executing request: " + request);
   }
}

Step 4

创建过滤器链

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

创建过滤管理器

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

创建客户端

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

使用Client演示拦截过滤器设计模式。

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");
   }
}

Step 8

验证输出。

Authenticating request: HOME
request log: HOME
Executing request: HOME

Service Locator Pattern

当我们想要使用JNDI查找定位各种服务时,使用服务定位器设计模式。 考虑到为服务查找JNDI的高成本,Service Locator模式使用缓存技术。 第一次需要服务时,Service Locator在JNDI中查找并缓存服务对象。 通过Service Locator进行进一步查找或相同的服务在其缓存中完成,这在很大程度上提高了应用程序的性能。 以下是此类设计模式的实体。

  • Service - 将处理请求的实际服务。 在JNDI服务器中查看此类服务的引用。

  • Context/Initial Context -JNDI上下文,包含用于查找目的的服务的引用。

  • Service Locator - 服务定位器是通过JNDI查找获取服务,缓存服务的单一联系点。

  • Cache - 用于存储服务引用的缓存以重用它们

  • Client - 客户端是通过ServiceLocator调用服务的对象。

实现 (Implementation)

我们将创建一个ServiceLocatorInitialContextCacheService作为代表我们实体的各种对象。 Service1Service2代表具体服务。

ServiceLocatorPatternDemo ,我们的演示类在这里充当客户端,并将使用ServiceLocator来演示服务定位器设计模式。

服务定位器模式UML图

Step 1

创建服务界面。

Service.java

public interface Service {
   public String getName();
   public void execute();
}

Step 2

创建具体服务。

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查找创建InitialContext

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

创建缓存

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

创建服务定位器

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演示服务定位器设计模式。

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();		
   }
}

Step 7

验证输出。

Looking up and creating a new Service1 object
Executing Service1
Looking up and creating a new Service2 object
Executing Service2
Returning cached  Service1 object
Executing Service1
Returning cached  Service2 object
Executing Service2

Transfer Object Pattern

当我们想要从客户端到服务器一次性传递具有多个属性的数据时,使用传输对象模式。 传输对象也称为值对象。 Transfer Object是一个简单的POJO类,具有getter/setter方法,并且是可序列化的,因此可以通过网络传输。 它没有任何行为。 服务器端业务类通常从数据库中提取数据并填充POJO并将其发送到客户端或按值传递。 对于客户端,传输对象是只读的。 客户端可以创建自己的传输对象并将其传递给服务器,以便一次性更新数据库中的值。 以下是此类设计模式的实体。

  • Business Object - 使用数据填充传输对象的业务服务。

  • Transfer Object -Simple POJO,具有仅设置/获取属性的方法。

  • Client - 客户端请求或将传输对象发送到业务对象。

实现 (Implementation)

我们将创建一个StudentBO作为业务对象, Student作为转移对象来表示我们的实体。

TransferObjectPatternDemo ,我们的演示类在这里充当客户端,并将使用StudentBOStudent来演示传输对象设计模式。

传递对象模式UML图

Step 1

创建传输对象。

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

创建业务对象。

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演示传输对象设计模式。

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()+" ]");
   }
}

Step 4

验证输出。

Student: [RollNo : 0, Name : Robert ]
Student: [RollNo : 1, Name : John ]
Student: Roll No 0, updated in the database
Student: [RollNo : 0, Name : Michael ]
↑回到顶部↑
WIKI教程 @2018