Hướng dẫn nhanh về mẫu thiết kế

Các mẫu thiết kế đại diện cho các phương pháp hay nhất được các nhà phát triển phần mềm hướng đối tượng có kinh nghiệm sử dụng. Mẫu thiết kế là giải pháp cho các vấn đề chung mà các nhà phát triển phần mềm gặp phải trong quá trình phát triển phần mềm. Những giải pháp này đã được nhiều nhà phát triển phần mềm thu được bằng cách thử và sai trong một khoảng thời gian khá dài.

Gang of Four (GOF) là gì?

Năm 1994, bốn tác giả Erich Gamma, Richard Helm, Ralph Johnson và John Vlissides đã xuất bản một cuốn sách có tựa đề Design Patterns - Elements of Reusable Object-Oriented Software đã khởi xướng khái niệm Mẫu thiết kế trong phát triển phần mềm.

Các tác giả này được gọi chung là Gang of Four (GOF). Theo các tác giả này, các mẫu thiết kế chủ yếu dựa trên các nguyên tắc sau của thiết kế hướng đối tượng.

  • Chương trình cho một giao diện không phải là một triển khai

  • Thành phần đối tượng ủng hộ hơn kế thừa

Sử dụng mẫu thiết kế

Mẫu thiết kế có hai cách sử dụng chính trong phát triển phần mềm.

Nền tảng chung cho các nhà phát triển

Các mẫu thiết kế cung cấp một thuật ngữ tiêu chuẩn và cụ thể cho từng trường hợp cụ thể. Ví dụ, một mẫu thiết kế singleton biểu thị việc sử dụng một đối tượng duy nhất, vì vậy tất cả các nhà phát triển quen thuộc với mẫu thiết kế đơn sẽ sử dụng một đối tượng duy nhất và họ có thể nói với nhau rằng chương trình đang tuân theo một mẫu singleton.

Thực hành tốt nhất

Các mẫu thiết kế đã được phát triển trong một thời gian dài và chúng cung cấp các giải pháp tốt nhất cho một số vấn đề nhất định gặp phải trong quá trình phát triển phần mềm. Học các mẫu này giúp các nhà phát triển chưa có kinh nghiệm học thiết kế phần mềm một cách dễ dàng và nhanh hơn.

Các loại mẫu thiết kế

Theo sách tham khảo mẫu thiết kế Design Patterns - Elements of Reusable Object-Oriented Software, có 23 mẫu thiết kế. Các mẫu này có thể được phân thành ba loại: Mẫu sáng tạo, Cấu trúc và hành vi. Chúng ta cũng sẽ thảo luận về một loại mẫu thiết kế khác: mẫu thiết kế J2EE.

SN Mô hình & Mô tả
1 Creational Patterns
Các mẫu thiết kế này cung cấp cách tạo đối tượng trong khi ẩn logic tạo, thay vì khởi tạo đối tượng trực tiếp bằng toán tử mới. Điều này giúp chương trình linh hoạt hơn trong việc quyết định đối tượng nào cần được tạo cho một trường hợp sử dụng nhất định.
2 Structural Patterns
Các mẫu thiết kế này liên quan đến thành phần lớp và đối tượng. Khái niệm kế thừa được sử dụng để soạn các giao diện và xác định các cách soạn các đối tượng để có được các chức năng mới.
3 Behavioral Patterns
Các mẫu thiết kế này đặc biệt quan tâm đến giao tiếp giữa các đối tượng.
4 J2EE Patterns
Các mẫu thiết kế này đặc biệt quan tâm đến tầng trình bày. Các mẫu này được xác định bởi Sun Java Center.

Factory pattern là một trong những mẫu thiết kế được sử dụng nhiều nhất trong Java. Loại mẫu thiết kế này thuộc mẫu sáng tạo vì mẫu này cung cấp một trong những cách tốt nhất để tạo một đối tượng.

Trong Factory pattern, chúng tôi tạo đối tượng mà không để lộ logic tạo cho máy khách và tham chiếu đến đối tượng mới được tạo bằng giao diện chung.

Thực hiện

Chúng ta sẽ tạo giao diện Shape và các lớp cụ thể triển khai giao diện Shape . Một lớp nhà máy ShapeFactory được xác định là bước tiếp theo.

FactoryPatternDemo , lớp demo của chúng ta sẽ sử dụng ShapeFactory để lấy một đối tượng Shape . Nó sẽ chuyển thông tin ( CIRCLE / RECTANGLE / SQUARE ) đến ShapeFactory để lấy loại đối tượng mà nó cần.

Bước 1

Tạo giao diện.

Shape.java

public interface Shape {
   void draw();
}

Bước 2

Tạo các lớp cụ thể triển khai cùng một giao diện.

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

Bước 3

Tạo một Nhà máy để tạo đối tượng của lớp cụ thể dựa trên thông tin đã cho.

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

Bước 4

Sử dụng Factory để lấy đối tượng của lớp cụ thể bằng cách truyền một thông tin như kiểu.

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

Bước 5

Xác minh kết quả đầu ra.

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

Các mẫu nhà máy trừu tượng hoạt động xung quanh một siêu nhà máy tạo ra các nhà máy khác. Nhà máy này còn được gọi là nhà máy của các nhà máy. Loại mẫu thiết kế này thuộc mẫu sáng tạo vì mẫu này cung cấp một trong những cách tốt nhất để tạo một đối tượng.

Trong mẫu Abstract Factory, một giao diện chịu trách nhiệm tạo một nhà máy của các đối tượng liên quan mà không chỉ định rõ ràng các lớp của chúng. Mỗi nhà máy được tạo có thể cung cấp các đối tượng theo mẫu Nhà máy.

Thực hiện

Chúng ta sẽ tạo một giao diện Shape và một lớp cụ thể triển khai nó. Chúng ta tạo một lớp nhà máy trừu tượng AbstractFactory như bước tiếp theo. Lớp Factory ShapeFactory được định nghĩa, mở rộng AbstractFactory. Một lớp tạo nhà máy / trình tạo FactoryProductioner được tạo.

AbstractFactoryPatternDemo, lớp demo của chúng tôi sử dụng FactoryProductioner để lấy một đối tượng AbstractFactory. Nó sẽ chuyển thông tin (CIRCLE / RECTANGLE / SQUARE cho Shape) đến AbstractFactory để lấy loại đối tượng mà nó cần.

Bước 1

Tạo giao diện cho Shapes.

Shape.java

public interface Shape {
   void draw();
}

Bước 2

Tạo các lớp cụ thể triển khai cùng một giao diện.

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

Bước 3

Tạo một lớp Trừu tượng để lấy các nhà máy cho các Đối tượng Hình dạng Thường và Hình tròn.

AbstractFactory.java

public abstract class AbstractFactory {
   abstract Shape getShape(String shapeType) ;
}

Bước 4

Tạo các lớp Factory mở rộng AbstractFactory để tạo đối tượng của lớp cụ thể dựa trên thông tin đã cho.

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

Bước 5

Tạo một lớp Nhà sản xuất / nhà sản xuất để nhận các nhà máy bằng cách chuyển một thông tin như Hình dạng

FactoryProductioner.java

public class FactoryProducer {
   public static AbstractFactory getFactory(boolean rounded){   
      if(rounded){
         return new RoundedShapeFactory();         
      }else{
         return new ShapeFactory();
      }
   }
}

Bước 6

Sử dụng FactoryProductioner để lấy AbstractFactory để lấy các nhà máy của các lớp cụ thể bằng cách chuyển một thông tin như kiểu.

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

Bước 7

Xác minh kết quả đầu ra.

Inside Rectangle::draw() method.
Inside Square::draw() method.
Inside RoundedRectangle::draw() method.
Inside RoundedSquare::draw() method.

Singleton pattern là một trong những mẫu thiết kế đơn giản nhất trong Java. Loại mẫu thiết kế này thuộc mẫu sáng tạo vì mẫu này cung cấp một trong những cách tốt nhất để tạo một đối tượng.

Mẫu này liên quan đến một lớp duy nhất chịu trách nhiệm tạo đối tượng riêng trong khi đảm bảo rằng chỉ một đối tượng duy nhất được tạo. Lớp này cung cấp một cách để truy cập đối tượng duy nhất của nó có thể được truy cập trực tiếp mà không cần khởi tạo đối tượng của lớp.

Thực hiện

Chúng ta sẽ tạo một lớp SingleObject . Lớp SingleObject có hàm tạo của nó là private và có một thể hiện tĩnh của chính nó.

Lớp SingleObject cung cấp một phương thức tĩnh để đưa thể hiện tĩnh của nó ra thế giới bên ngoài. SingletonPatternDemo , lớp demo của chúng ta sẽ sử dụng lớp SingleObject để lấy một đối tượng SingleObject .

Bước 1

Tạo một lớp 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!");
   }
}

Bước 2

Lấy đối tượng duy nhất từ ​​lớp singleton.

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

Bước 3

Xác minh kết quả đầu ra.

Hello World!

Mẫu Builder xây dựng một đối tượng phức tạp bằng cách sử dụng các đối tượng đơn giản và sử dụng phương pháp tiếp cận từng bước. Loại mẫu thiết kế này thuộc mẫu sáng tạo vì mẫu này cung cấp một trong những cách tốt nhất để tạo một đối tượng.

Một lớp Builder xây dựng đối tượng cuối cùng theo từng bước. Trình xây dựng này độc lập với các đối tượng khác.

Thực hiện

Chúng tôi đã xem xét một trường hợp kinh doanh của nhà hàng thức ăn nhanh, nơi một bữa ăn điển hình có thể là bánh mì kẹp thịt và đồ uống lạnh. Burger có thể là Veg Burger hoặc Chicken Burger và sẽ được đóng gói bằng giấy gói. Đồ uống lạnh có thể là coca hoặc pepsi và sẽ được đóng trong chai.

Chúng ta sẽ tạo một giao diện Item đại diện cho các mặt hàng thực phẩm như bánh mì kẹp thịt và đồ uống lạnh và các lớp cụ thể triển khai giao diện Item và một giao diện Đóng gói đại diện cho việc đóng gói các mặt hàng thực phẩm và các lớp cụ thể triển khai giao diện Đóng gói vì bánh mì kẹp thịt sẽ được đóng gói trong giấy gói và lạnh đồ uống sẽ được đóng gói dưới dạng chai.

Sau đó, chúng tôi tạo một lớp Bữa ănArrayList of ItemMealBuilder để xây dựng các loại đối tượng Bữa ăn khác nhau bằng cách kết hợp Item . BuilderPatternDemo , lớp demo của chúng ta sẽ sử dụng MealBuilder để xây dựng Bữa ăn .

Bước 1

Tạo giao diện Mục đại diện cho mặt hàng thực phẩm và đóng gói.

Item.java

public interface Item {
   public String name();
   public Packing packing();
   public float price();	
}

Packing.java

public interface Packing {
   public String pack();
}

Bước 2

Tạo các lớp kết hợp thực hiện giao diện Đóng gói.

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

Bước 3

Tạo các lớp trừu tượng triển khai giao diện mục cung cấp các chức năng mặc định.

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

Bước 4

Tạo các lớp cụ thể mở rộng các lớp Burger và 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";
   }
}

Bước 5

Tạo một lớp Bữa ăn có các đối tượng Item được định nghĩa ở trên.

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

Bước 6

Tạo một lớp MealBuilder, lớp người xây dựng thực tế chịu trách nhiệm tạo các đối tượng Bữa ăn.

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

Bước 7

BuiderPatternDemo sử dụng MealBuider để chứng minh mẫu trình tạo.

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

Bước 8

Xác minh kết quả đầu ra.

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

Mẫu nguyên mẫu đề cập đến việc tạo đối tượng trùng lặp trong khi vẫn lưu ý đến hiệu suất. Loại mẫu thiết kế này thuộc mẫu sáng tạo vì mẫu này cung cấp một trong những cách tốt nhất để tạo một đối tượng.

Mẫu này liên quan đến việc triển khai một giao diện nguyên mẫu yêu cầu tạo một bản sao của đối tượng hiện tại. Mẫu này được sử dụng khi việc tạo đối tượng trực tiếp là tốn kém. Ví dụ, một đối tượng sẽ được tạo sau một hoạt động cơ sở dữ liệu tốn kém. Chúng ta có thể lưu vào bộ nhớ cache của đối tượng, trả về bản sao của nó theo yêu cầu tiếp theo và cập nhật cơ sở dữ liệu khi cần thiết, do đó giảm các lệnh gọi cơ sở dữ liệu.

Thực hiện

Chúng ta sẽ tạo một lớp trừu tượng Shape và các lớp cụ thể mở rộng lớp Shape . Một lớp ShapeCache được định nghĩa là bước tiếp theo lưu trữ các đối tượng hình dạng trong Hashtable và trả về bản sao của chúng khi được yêu cầu.

PrototypPatternDemo , lớp demo của chúng ta sẽ sử dụng lớp ShapeCache để lấy một đối tượng Shape .

Bước 1

Tạo một lớp trừu tượng triển khai giao diện 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;
   }
}

Bước 2

Tạo các lớp cụ thể mở rộng lớp trên.

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

Bước 3

Tạo một lớp để tạo các lớp tương ứng từ cơ sở dữ liệu và lưu trữ chúng trong 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);
   }
}

Bước 4

PrototypePatternDemo sử dụng lớp ShapeCache để nhận bản sao của các hình dạng được lưu trữ trong 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());		
   }
}

Bước 5

Xác minh kết quả đầu ra.

Shape : Circle
Shape : Square
Shape : Rectangle

Mẫu bộ điều hợp hoạt động như một cầu nối giữa hai giao diện không tương thích. Loại mẫu thiết kế này thuộc mẫu cấu trúc vì mẫu này kết hợp khả năng của hai giao diện độc lập.

Mẫu này liên quan đến một lớp duy nhất chịu trách nhiệm tham gia các chức năng của các giao diện độc lập hoặc không tương thích. Một ví dụ thực tế có thể là một trường hợp đầu đọc thẻ hoạt động như một bộ chuyển đổi giữa thẻ nhớ và máy tính xách tay. Bạn cắm thẻ nhớ vào đầu đọc thẻ và đầu đọc thẻ vào laptop để thẻ nhớ đọc được qua laptop.

Chúng tôi đang trình diễn việc sử dụng mẫu Bộ điều hợp thông qua ví dụ sau, trong đó thiết bị trình phát âm thanh chỉ có thể phát tệp mp3 và muốn sử dụng trình phát âm thanh nâng cao có khả năng phát tệp vlc và mp4.

Thực hiện

Chúng tôi có một giao diện MediaPlayer giao diện và một AudioPlayer lớp cụ thể triển khai giao diện MediaPlayer . AudioPlayer có thể phát các tệp âm thanh định dạng mp3 theo mặc định.

Chúng tôi đang có một giao diện khác AdvancedMediaPlayer và các lớp cụ thể triển khai giao diện AdvancedMediaPlayer. Các lớp này có thể phát các tệp định dạng vlc và mp4.

Chúng tôi muốn tạo AudioPlayer để phát các định dạng khác. Để đạt được điều này, chúng tôi đã tạo một lớp bộ điều hợp MediaAdapter triển khai giao diện MediaPlayer và sử dụng các đối tượng AdvancedMediaPlayer để phát định dạng cần thiết.

AudioPlayer sử dụng lớp bộ điều hợp MediaAdapter chuyển cho nó loại âm thanh mong muốn mà không cần biết lớp thực tế có thể phát định dạng mong muốn. AdapterPatternDemo , lớp demo của chúng tôi sẽ sử dụng lớp AudioPlayer để phát nhiều định dạng khác nhau.

Bước 1

Tạo giao diện cho Media Player và 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);
}

Bước 2

Tạo các lớp cụ thể triển khai giao diện 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);		
   }
}

Bước 3

Tạo lớp bộ điều hợp triển khai giao diện 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);
      }
   }
}

Bước 4

Tạo lớp cụ thể triển khai giao diện 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");
      }
   }   
}

Bước 5

Sử dụng Trình phát âm thanh để phát các loại định dạng âm thanh khác nhau.

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

Bước 6

Xác minh kết quả đầu ra.

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 được sử dụng khi chúng ta cần tách một phần trừu tượng khỏi việc triển khai nó để cả hai có thể khác nhau một cách độc lập. Loại mẫu thiết kế này nằm dưới mẫu cấu trúc vì mẫu này tách lớp thực thi và lớp trừu tượng bằng cách cung cấp cấu trúc cầu nối giữa chúng.

Mẫu này liên quan đến một giao diện hoạt động như một cầu nối làm cho chức năng của các lớp cụ thể độc lập với các lớp của trình triển khai giao diện. Cả hai loại lớp đều có thể được thay đổi cấu trúc mà không ảnh hưởng đến nhau.

Chúng tôi đang trình diễn việc sử dụng mẫu Bridge thông qua ví dụ sau trong đó một vòng tròn có thể được vẽ bằng các màu khác nhau bằng cách sử dụng cùng một phương thức lớp trừu tượng nhưng các lớp trình triển khai cầu khác nhau.

Thực hiện

Chúng tôi có một giao diện DrawAPI giao diện hoạt động như một trình triển khai cầu nối và các lớp cụ thể RedCircle , GreenCircle triển khai giao diện DrawAPI . Shape là một lớp trừu tượng và sẽ sử dụng đối tượng của DrawAPI . BridgePatternDemo , lớp demo của chúng ta sẽ sử dụng lớp Shape để vẽ các vòng tròn có màu khác nhau.

Bước 1

Tạo giao diện trình triển khai cầu nối.

DrawAPI.java

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

Bước 2

Tạo các lớp triển khai cầu bê tông thực hiện giao diện 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 +"]");
   }
}

Bước 3

Tạo một Hình dạng lớp trừu tượng bằng giao diện DrawAPI .

Shape.java

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

Bước 4

Tạo lớp cụ thể thực hiện giao diện 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);
   }
}

Bước 5

Sử dụng các lớp ShapeDrawAPI để vẽ các vòng tròn màu khác nhau.

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

Bước 6

Xác minh kết quả đầu ra.

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

Mẫu bộ lọc hoặc Mẫu tiêu chí là một mẫu thiết kế cho phép các nhà phát triển lọc một tập hợp các đối tượng, sử dụng các tiêu chí khác nhau, xâu chuỗi chúng theo cách tách rời thông qua các phép toán logic. Loại mẫu thiết kế này thuộc mẫu cấu trúc vì mẫu này kết hợp nhiều tiêu chí để có được các tiêu chí duy nhất.

Thực hiện

Chúng ta sẽ tạo một đối tượng Person , giao diện Criteria và các lớp cụ thể triển khai giao diện này để lọc danh sách các đối tượng Person . CriteriaPatternDemo , lớp demo của chúng tôi sử dụng các đối tượng Criteria để lọc các đối tượng List of Person dựa trên các tiêu chí khác nhau và sự kết hợp của chúng.

Bước 1

Tạo một lớp dựa trên các tiêu chí sẽ được áp dụng.

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

Bước 2

Tạo giao diện cho Tiêu chí.

Criteria.java

import java.util.List;

public interface Criteria {
   public List<Person> meetCriteria(List<Person> persons);
}

Bước 3

Tạo các lớp cụ thể thực hiện giao diện 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;
   }
}

Bước 4

Sử dụng các Tiêu chí khác nhau và sự kết hợp của chúng để lọc ra những người.

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

Bước 5

Xác minh kết quả đầu ra.

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 ]

Mẫu phức hợp được sử dụng khi chúng ta cần xử lý một nhóm đối tượng theo cách tương tự như một đối tượng duy nhất. Mẫu tổng hợp bao gồm các đối tượng dưới dạng cấu trúc cây để đại diện cho một phần cũng như toàn bộ hệ thống phân cấp. Loại mô hình thiết kế này nằm dưới mô hình cấu trúc vì mô hình này tạo ra một cấu trúc cây gồm các nhóm đối tượng.

Mẫu này tạo ra một lớp chứa nhóm các đối tượng của chính nó. Lớp này cung cấp các cách để sửa đổi nhóm các đối tượng giống nhau của nó.

Chúng tôi đang chứng minh việc sử dụng mẫu Composite thông qua ví dụ sau, trong đó hiển thị thứ bậc nhân viên của một tổ chức.

Thực hiện

Chúng ta có một lớp Employee hoạt động như lớp diễn viên mẫu tổng hợp. CompositePatternDemo , lớp demo của chúng tôi sẽ sử dụng lớp Nhân viên để thêm hệ thống phân cấp cấp bộ phận và in tất cả nhân viên.

Bước 1

Tạo lớp Nhân viên có danh sách các đối tượng Nhân viên .

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

Bước 2

Sử dụng lớp Nhân viên để tạo và in hệ thống phân cấp nhân viên.

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

Bước 3

Xác minh kết quả đầu ra.

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 cho phép thêm chức năng mới vào một đối tượng hiện có mà không làm thay đổi cấu trúc của nó. Loại mẫu thiết kế này nằm dưới mẫu cấu trúc vì mẫu này hoạt động như một lớp bao bọc cho lớp hiện có.

Mẫu này tạo ra một lớp decorator bao bọc lớp ban đầu và cung cấp chức năng bổ sung giữ nguyên chữ ký của các phương thức lớp.

Chúng tôi đang trình diễn việc sử dụng Decorator pattern thông qua ví dụ sau, trong đó chúng tôi sẽ trang trí một hình dạng với một số màu mà không làm thay đổi lớp hình dạng.

Thực hiện

Chúng ta sẽ tạo giao diện Shape và các lớp cụ thể triển khai giao diện Shape . Sau đó, chúng tôi tạo một lớp trang trí trừu tượng ShapeDecorator triển khai giao diện Shape và có đối tượng Shape làm biến thể hiện của nó.

RedShapeDecorator là lớp cụ thể triển khai ShapeDecorator .

DecoratorPatternDemo , lớp demo của chúng ta sẽ sử dụng RedShapeDecorator để trang trí các đối tượng Shape .

Bước 1

Tạo giao diện.

Shape.java

public interface Shape {
   void draw();
}

Bước 2

Tạo các lớp cụ thể triển khai cùng một giao diện.

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

Bước 3

Tạo lớp trang trí trừu tượng triển khai giao diện Shape .

ShapeDecorator.java

public abstract class ShapeDecorator implements Shape {
   protected Shape decoratedShape;

   public ShapeDecorator(Shape decoratedShape){
      this.decoratedShape = decoratedShape;
   }

   public void draw(){
      decoratedShape.draw();
   }	
}

Bước 4

Tạo lớp trang trí bê tông mở rộng lớp 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");
   }
}

Bước 5

Sử dụng RedShapeDecorator để trang trí các đối tượng 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();
   }
}

Bước 6

Xác minh kết quả đầu ra.

Circle with normal border
Shape: Circle

Circle of red border
Shape: Circle
Border Color: Red

Rectangle of red border
Shape: Rectangle
Border Color: Red

Mẫu mặt tiền che giấu sự phức tạp của hệ thống và cung cấp một giao diện cho khách hàng bằng cách sử dụng mà khách hàng có thể truy cập hệ thống. Loại mẫu thiết kế này nằm dưới mẫu cấu trúc vì mẫu này thêm một giao diện vào hệ thống thoát để che giấu sự phức tạp của nó.

Mẫu này liên quan đến một lớp duy nhất cung cấp các phương thức đơn giản hóa được yêu cầu bởi máy khách và ủy quyền các cuộc gọi đến các phương thức lớp hệ thống hiện có.

Thực hiện

Chúng ta sẽ tạo giao diện Shape và các lớp cụ thể triển khai giao diện Shape . Một lớp mặt tiền ShapeMaker được định nghĩa là bước tiếp theo.

Lớp ShapeMaker sử dụng các lớp cụ thể để ủy quyền các cuộc gọi của người dùng đến các lớp này. FacadePatternDemo , lớp demo của chúng ta sẽ sử dụng lớp ShapeMaker để hiển thị kết quả.

Bước 1

Tạo giao diện.

Shape.java

public interface Shape {
   void draw();
}

Bước 2

Tạo các lớp cụ thể triển khai cùng một giao diện.

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

Bước 3

Tạo lớp mặt tiền.

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

Bước 4

Sử dụng mặt tiền để vẽ nhiều loại hình dạng khác nhau.

FacadePatternDemo.java

public class FacadePatternDemo {
   public static void main(String[] args) {
      ShapeMaker shapeMaker = new ShapeMaker();

      shapeMaker.drawCircle();
      shapeMaker.drawRectangle();
      shapeMaker.drawSquare();		
   }
}

Bước 5

Xác minh kết quả đầu ra.

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

Flyweight pattern chủ yếu được sử dụng để giảm số lượng đối tượng được tạo, để giảm dung lượng bộ nhớ và tăng hiệu suất. Loại mẫu thiết kế này nằm dưới mẫu cấu trúc vì mẫu này cung cấp các cách để giảm số lượng đối tượng do đó cải thiện cấu trúc đối tượng được yêu cầu của ứng dụng.

Mẫu Flyweight cố gắng sử dụng lại các đối tượng loại tương tự đã có bằng cách lưu trữ chúng và tạo đối tượng mới khi không tìm thấy đối tượng phù hợp. Chúng tôi sẽ chứng minh mô hình này bằng cách vẽ 20 vòng tròn ở các vị trí khác nhau nhưng chúng tôi sẽ chỉ tạo ra 5 đối tượng. Chỉ có 5 màu có sẵn nên thuộc tính màu được sử dụng để kiểm tra các đối tượng Hình tròn đã có .

Thực hiện

Chúng ta sẽ tạo một giao diện Shape và lớp cụ thể Circle thực hiện giao diện Shape . Một lớp nhà máy ShapeFactory được xác định là bước tiếp theo.

ShapeFactoryHashMap of Circle có khóa là màu của đối tượng Circle . Bất cứ khi nào có yêu cầu, hãy tạo một vòng tròn có màu cụ thể cho ShapeFactory . ShapeFactory kiểm tra đối tượng vòng tròn trong HashMap của nó , nếu đối tượng của Vòng tròn được tìm thấy, đối tượng đó sẽ được trả lại nếu không một đối tượng mới được tạo, được lưu trữ trong bản đồ băm để sử dụng trong tương lai và trả lại cho khách hàng.

FlyWeightPatternDemo , lớp demo của chúng ta sẽ sử dụng ShapeFactory để lấy một đối tượng Shape . Nó sẽ chuyển thông tin ( đỏ / xanh lá cây / xanh dương / đen / trắng ) đến ShapeFactory để có được vòng tròn có màu mong muốn mà nó cần.

Bước 1

Tạo giao diện.

Shape.java

public interface Shape {
   void draw();
}

Bước 2

Tạo lớp cụ thể thực hiện cùng một giao diện.

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

Bước 3

Tạo một Nhà máy để tạo đối tượng của lớp cụ thể dựa trên thông tin đã cho.

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

Bước 4

Sử dụng Factory để lấy đối tượng của lớp cụ thể bằng cách chuyển một thông tin chẳng hạn như màu sắc.

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

Bước 5

Xác minh kết quả đầu ra.

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

Trong mẫu Proxy, một lớp đại diện cho chức năng của một lớp khác. Loại mô hình thiết kế này thuộc mô hình cấu trúc.

Trong Proxy pattern, chúng ta tạo đối tượng có đối tượng gốc để giao diện chức năng của nó với thế giới bên ngoài.

Thực hiện

Chúng ta sẽ tạo một giao diện Hình ảnh và các lớp cụ thể triển khai giao diện Hình ảnh . ProxyImage là một lớp proxy để giảm dung lượng bộ nhớ tải đối tượng RealImage .

ProxyPatternDemo , lớp demo của chúng tôi sẽ sử dụng ProxyImage để có được một hình ảnh đối tượng để tải và hiển thị như nó cần.

Bước 1

Tạo giao diện.

Image.java

public interface Image {
   void display();
}

Bước 2

Tạo các lớp cụ thể triển khai cùng một giao diện.

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

Bước 3

Sử dụng ProxyImage để lấy đối tượng của lớp RealImage khi được yêu cầu.

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

Bước 4

Xác minh kết quả đầu ra.

Loading test_10mb.jpg
Displaying test_10mb.jpg

Displaying test_10mb.jpg

Như tên gợi ý, chuỗi mẫu trách nhiệm tạo ra một chuỗi các đối tượng người nhận cho một yêu cầu. Mẫu này phân tách người gửi và người nhận một yêu cầu dựa trên loại yêu cầu. Mô hình này nằm dưới các khuôn mẫu hành vi.

Trong mô hình này, thông thường mỗi bộ thu chứa tham chiếu đến bộ thu khác. Nếu một đối tượng không thể xử lý yêu cầu thì nó sẽ chuyển tương tự đến người nhận tiếp theo, v.v.

Thực hiện

Chúng tôi đã tạo một lớp trừu tượng AbstractLogger với mức độ ghi nhật ký. Sau đó, chúng tôi đã tạo ba loại trình ghi nhật ký mở rộng AbstractLogger . Mỗi trình ghi nhật ký kiểm tra mức độ của thông báo đến mức của nó và in tương ứng, nếu không sẽ không in và chuyển thông báo đến bộ ghi tiếp theo của nó.

Bước 1

Tạo một lớp trình ghi tóm tắt.

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

Bước 2

Tạo các lớp cụ thể mở rộng bộ ghi nhật ký.

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

Bước 3

Tạo các loại ghi nhật ký khác nhau. Gán chúng mức độ lỗi và đặt trình ghi tiếp theo trong mỗi trình ghi. Trình ghi tiếp theo trong mỗi trình ghi đại diện cho một phần của chuỗi.

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

Bước 4

Xác minh kết quả đầu ra.

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.

Mẫu lệnh là một mẫu thiết kế theo hướng dữ liệu và thuộc danh mục mẫu hành vi. Một yêu cầu được bao bọc dưới một đối tượng dưới dạng lệnh và được chuyển đến đối tượng invoker. Đối tượng Invoker tìm kiếm đối tượng thích hợp có thể xử lý lệnh này và truyền lệnh cho đối tượng tương ứng và đối tượng đó thực hiện lệnh.

Thực hiện

Chúng tôi đã tạo một Lệnh giao diện hoạt động như một lệnh. Chúng tôi đã tạo một lớp Cổ phiếu hoạt động như một yêu cầu. Chúng tôi có các lớp lệnh cụ thể BuyStockSellStock triển khai giao diện Order sẽ thực hiện xử lý lệnh thực tế. Một nhà môi giới lớp được tạo ra hoạt động như một đối tượng invoker. Nó có thể nhận đơn đặt hàng và đặt hàng.

Đối tượng Broker sử dụng mẫu lệnh để xác định đối tượng nào sẽ thực hiện lệnh nào dựa trên loại lệnh. CommandPatternDemo , lớp demo của chúng ta sẽ sử dụng lớp Broker để thể hiện mẫu lệnh.

Bước 1

Tạo giao diện lệnh.

Order.java

public interface Order {
   void execute();
}

Bước 2

Tạo một lớp yêu cầu.

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

Bước 3

Tạo các lớp cụ thể thực hiện giao diện Order .

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

Bước 4

Tạo lớp invoker lệnh.

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

Bước 5

Sử dụng lớp Broker để nhận và thực hiện các lệnh.

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

Bước 6

Xác minh kết quả đầu ra.

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

Mẫu phiên dịch cung cấp cách đánh giá ngữ pháp hoặc cách diễn đạt ngôn ngữ. Loại khuôn mẫu này nằm trong khuôn mẫu hành vi. Mẫu này liên quan đến việc triển khai một giao diện biểu thức để diễn giải một ngữ cảnh cụ thể. Mẫu này được sử dụng trong phân tích cú pháp SQL, công cụ xử lý ký hiệu, v.v.

Thực hiện

Chúng ta sẽ tạo một giao diện Biểu thức và các lớp cụ thể triển khai giao diện Biểu thức . Một lớp TerminalExpression được định nghĩa hoạt động như một trình thông dịch chính của ngữ cảnh được đề cập. Các lớp khác OrExpression , AndExpression được sử dụng để tạo các biểu thức tổ hợp.

InterpreterPatternDemo , lớp demo của chúng ta sẽ sử dụng lớp Expression để tạo các quy tắc và trình diễn phân tích cú pháp các biểu thức.

Bước 1

Tạo giao diện biểu thức.

Expression.java

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

Bước 2

Tạo các lớp cụ thể thực hiện giao diện trên.

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

Bước 3

InterpreterPatternDemo sử dụng lớp Expression để tạo các quy tắc và sau đó phân tích cú pháp chúng.

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

Bước 4

Xác minh kết quả đầu ra.

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

Mẫu lặp lại là mẫu thiết kế được sử dụng rất phổ biến trong môi trường lập trình Java và .Net. Mẫu này được sử dụng để có cách truy cập các phần tử của đối tượng tập hợp theo cách tuần tự mà không cần biết biểu diễn cơ bản của nó.

Mẫu lặp lại thuộc danh mục mẫu hành vi.

Thực hiện

Chúng ta sẽ tạo một giao diện Iterator trình bày lại phương thức điều hướng và một giao diện Container sẽ chạy lại trình vòng lặp. Các lớp cụ thể triển khai giao diện Container sẽ chịu trách nhiệm triển khai giao diện Iterator và sử dụng nó

IteratorPatternDemo , lớp demo của chúng ta sẽ sử dụng NamesRepository , một triển khai lớp cụ thể để in Tên được lưu trữ dưới dạng tập hợp trong NamesRepository .

Bước 1

Tạo giao diện.

Iterator.java

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

Container.java

public interface Container {
   public Iterator getIterator();
}

Bước 2

Tạo lớp cụ thể thực hiện giao diện Container . Lớp này có NameIterator lớp bên trong thực hiện giao diện Iterator .

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

Bước 3

Sử dụng NameRepository để lấy tên trình lặp và in.

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

Bước 4

Xác minh kết quả đầu ra.

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

Mẫu dàn xếp được sử dụng để giảm độ phức tạp trong giao tiếp giữa nhiều đối tượng hoặc lớp. Mẫu này cung cấp một lớp trung gian thường xử lý tất cả các thông tin liên lạc giữa các lớp khác nhau và hỗ trợ khả năng bảo trì mã dễ dàng bằng cách ghép nối lỏng. Mẫu hòa giải thuộc danh mục mẫu hành vi.

Thực hiện

Chúng tôi đang trình diễn mô hình hòa giải viên bằng ví dụ về Phòng trò chuyện nơi nhiều người dùng có thể gửi tin nhắn đến Phòng trò chuyện và Phòng trò chuyện có trách nhiệm hiển thị thông báo cho tất cả người dùng. Chúng tôi đã tạo hai lớp ChatRoomNgười dùng . Đối tượng người dùng sẽ sử dụng phương thức ChatRoom để chia sẻ thông điệp của họ.

MediatorPatternDemo , lớp demo của chúng tôi sẽ sử dụng các đối tượng Người dùng để hiển thị giao tiếp giữa chúng.

Bước 1

Tạo lớp hòa giải viên.

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

Bước 2

Tạo lớp người dùng

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

Bước 3

Sử dụng đối tượng Người dùng để hiển thị thông tin liên lạc giữa họ.

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

Bước 4

Xác minh kết quả đầu ra.

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

Memento pattern được sử dụng để giảm nơi chúng ta muốn khôi phục trạng thái của một đối tượng về trạng thái trước đó. Mẫu hình lưu niệm thuộc danh mục mẫu hành vi.

Thực hiện

Memento pattern sử dụng ba lớp diễn viên. Memento chứa trạng thái của một đối tượng được khôi phục. Originator tạo và lưu trữ trạng thái trong các đối tượng Memento và đối tượng Caretaker chịu trách nhiệm khôi phục trạng thái đối tượng từ Memento. Chúng tôi đã tạo các lớp Memento , OriginatorCareTaker .

MementoPatternDemo , lớp demo của chúng ta sẽ sử dụng các đối tượng CareTakerOriginator để hiển thị khôi phục trạng thái đối tượng.

Bước 1

Tạo lớp Memento.

Memento.java

public class Memento {
   private String state;

   public Memento(String state){
      this.state = state;
   }

   public String getState(){
      return state;
   }	
}

Bước 2

Tạo lớp 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();
   }
}

Bước 3

Tạo lớp 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);
   }
}

Bước 4

Sử dụng các đối tượng 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());
   }
}

Bước 5

Xác minh kết quả đầu ra.

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

Mẫu quan sát được sử dụng khi có một đến nhiều mối quan hệ giữa các đối tượng, chẳng hạn như nếu một đối tượng được sửa đổi, các đối tượng phụ thuộc của nó sẽ được thông báo tự động. Mẫu người quan sát thuộc danh mục mẫu hành vi.

Thực hiện

Mẫu quan sát sử dụng ba lớp tác nhân. Chủ thể, Người quan sát và Khách hàng. Chủ thể, một đối tượng có các phương pháp để gắn và hủy gắn các quan sát viên vào một đối tượng khách. Chúng tôi đã tạo các lớp Chủ đề , lớp trừu tượng Người quan sát và các lớp cụ thể mở rộng lớp trừu tượng Người quan sát .

ObserverPatternDemo , lớp demo của chúng tôi sẽ sử dụng Chủ đề và các đối tượng lớp cụ thể để hiển thị mẫu người quan sát đang hoạt động.

Bước 1

Tạo lớp Chủ đề.

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

Bước 2

Tạo lớp Observer.

Observer.java

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

Bước 3

Tạo các lớp quan sát cụ thể

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

Bước 4

Sử dụng Chủ thể và các đối tượng quan sát cụ thể.

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

Bước 5

Xác minh kết quả đầu ra.

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

Trong State pattern, một hành vi của lớp thay đổi dựa trên trạng thái của nó. Loại mẫu thiết kế này nằm dưới mẫu hành vi.

Trong State pattern, chúng ta tạo các đối tượng đại diện cho các trạng thái khác nhau và một đối tượng ngữ cảnh có hành vi thay đổi khi đối tượng trạng thái của nó thay đổi.

Thực hiện

Chúng ta sẽ tạo giao diện Trạng thái xác định một hành động và các lớp trạng thái cụ thể triển khai giao diện Trạng thái . Context là một lớp mang State.

StaePatternDemo , lớp demo của chúng tôi sẽ sử dụng các đối tượng Context và trạng thái để chứng minh sự thay đổi trong hành vi của Context dựa trên loại trạng thái mà nó đang ở.

Bước 1

Tạo giao diện.

Image.java

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

Bước 2

Tạo các lớp cụ thể triển khai cùng một giao diện.

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

Bước 3

Tạo lớp ngữ cảnh .

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

Bước 4

Sử dụng Ngữ cảnh để xem sự thay đổi trong hành vi khi Trạng thái thay đổi.

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

Bước 5

Xác minh kết quả đầu ra.

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

Trong mẫu đối tượng Null, một đối tượng null thay thế kiểm tra đối tượng NULL. Thay vì đặt nếu kiểm tra giá trị null, Null Object phản ánh mối quan hệ không làm gì cả. Đối tượng Null như vậy cũng có thể được sử dụng để cung cấp hành vi mặc định trong trường hợp dữ liệu không có sẵn.

Trong mẫu Null Object, chúng ta tạo một lớp trừu tượng chỉ định các hoạt động khác nhau sẽ được thực hiện, tạo các lớp nối tiếp mở rộng lớp này và một lớp đối tượng null cung cấp không thực hiện gì cho lớp này và sẽ được sử dụng dường như khi chúng ta cần kiểm tra giá trị null.

Thực hiện

Chúng ta sẽ tạo một lớp trừu tượng AbstractCustomer xác định các hoạt động, ở đây là tên của khách hàng và các lớp cụ thể mở rộng lớp AbstractCustomer . Một lớp nhà máy CustomerFactory được tạo ra để trở về hoặc là RealCustomer hoặc NullCustomer đối tượng dựa trên tên của khách hàng được truyền cho nó.

NullPatternDemo , lớp demo của chúng tôi sẽ sử dụng CustomerFactory để chứng minh việc sử dụng mẫu Null Object.

Bước 1

Tạo một lớp trừu tượng.

AbstractCustomer.java

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

Bước 2

Tạo các lớp cụ thể mở rộng lớp trên.

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

Bước 3

Tạo lớp 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();
   }
}

Bước 4

Sử dụng các CustomerFactory có được một trong hai RealCustomer hoặc NullCustomer đối tượng dựa trên tên của khách hàng được truyền cho nó.

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

Bước 5

Xác minh kết quả đầu ra.

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

Trong mẫu Chiến lược, một hành vi của lớp hoặc thuật toán của nó có thể được thay đổi tại thời điểm chạy. Loại mẫu thiết kế này nằm dưới mẫu hành vi.

Trong mẫu Chiến lược, chúng tôi tạo các đối tượng đại diện cho các chiến lược khác nhau và một đối tượng ngữ cảnh có hành vi thay đổi tùy theo đối tượng chiến lược của nó. Đối tượng chiến lược thay đổi thuật toán thực thi của đối tượng ngữ cảnh.

Thực hiện

Chúng ta sẽ tạo giao diện Chiến lược xác định một hành động và các lớp chiến lược cụ thể triển khai giao diện Chiến lược . Ngữ cảnh là một lớp sử dụng Chiến lược.

StrategyPatternDemo , lớp demo của chúng tôi sẽ sử dụng các đối tượng Ngữ cảnh và chiến lược để thể hiện sự thay đổi trong hành vi của Ngữ cảnh dựa trên chiến lược mà nó triển khai hoặc sử dụng.

Bước 1

Tạo giao diện.

Strategy.java

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

Bước 2

Tạo các lớp cụ thể triển khai cùng một giao diện.

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

Bước 3

Tạo lớp ngữ cảnh .

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

Bước 4

Sử dụng Ngữ cảnh để xem sự thay đổi trong hành vi khi nó thay đổi Chiến lược .

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

Bước 5

Xác minh kết quả đầu ra.

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

Trong mẫu Template, một lớp trừu tượng trình bày (các) cách / (các) mẫu đã xác định để thực thi các phương thức của nó. Các lớp con của nó có thể ghi đè các triển khai phương thức theo cơ sở cần thiết nhưng lời gọi phải theo cách giống như được định nghĩa bởi một lớp trừu tượng. Mẫu này nằm trong danh mục mẫu hành vi.

Thực hiện

Chúng ta sẽ tạo một lớp trừu tượng Trò chơi xác định các hoạt động với một phương thức mẫu được đặt thành cuối cùng để nó không thể bị ghi đè. CricketFootball là các lớp cụ thể mở rộng Trò chơi và ghi đè các phương thức của nó.

TemplatePatternDemo , lớp demo của chúng tôi sẽ sử dụng Game để chứng minh việc sử dụng mẫu mẫu.

Bước 1

Tạo một lớp trừu tượng với một phương thức mẫu là cuối cùng.

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

Bước 2

Tạo các lớp cụ thể mở rộng lớp trên.

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

Bước 3

Sử dụng các trò chơi mẫu phương pháp chơi 's () để chứng minh một cách xác định chơi trò chơi.

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

Bước 4

Xác minh kết quả đầu ra.

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!

Trong kiểu khách truy cập, chúng tôi sử dụng lớp khách truy cập để thay đổi thuật toán thực thi của một lớp phần tử. Bằng cách này, thuật toán thực thi của phần tử có thể thay đổi khi khách truy cập thay đổi. Mẫu này nằm trong danh mục mẫu hành vi. Theo mẫu, đối tượng phần tử phải chấp nhận đối tượng khách truy cập để đối tượng khách truy cập xử lý hoạt động trên đối tượng phần tử.

Thực hiện

Chúng ta sẽ tạo một giao diện ComputerPart xác định việc chọn chấp nhận. Bàn phím , Chuột , Màn hìnhMáy tính là các lớp cụ thể triển khai giao diện ComputerPart . Chúng tôi sẽ xác định một giao diện ComputerPartVisitor khác sẽ xác định các hoạt động của lớp khách truy cập. Máy tính sử dụng khách truy cập cụ thể để thực hiện hành động tương ứng.

VisitorPatternDemo , lớp demo của chúng tôi sẽ sử dụng máy tính , ComputerPartVisitor lớp học để chứng minh sử dụng các mô hình khách truy cập.

Bước 1

Xác định một giao diện để đại diện cho phần tử.

ComputerPart.java

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

Bước 2

Tạo các lớp cụ thể mở rộng lớp trên.

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

Bước 3

Xác định một giao diện để đại diện cho khách truy cập.

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

Bước 4

Tạo khách truy cập cụ thể thực hiện lớp trên.

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

Bước 5

Sử dụng ComputerPartDisplayVisitor để hiển thị các bộ phận của Máy tính .

VisitorPatternDemo.java

public class VisitorPatternDemo {
   public static void main(String[] args) {

      ComputerPart computer = new Computer();
      computer.accept(new ComputerPartDisplayVisitor());
   }
}

Bước 6

Xác minh kết quả đầu ra.

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

MVC Pattern là viết tắt của Model-View-Controller Pattern. Mẫu này được sử dụng để phân tách các mối quan tâm của ứng dụng.

  • Model- Mô hình đại diện cho một đối tượng hoặc JAVA POJO mang dữ liệu. Nó cũng có thể có logic để cập nhật bộ điều khiển nếu dữ liệu của nó thay đổi.

  • View - View thể hiện sự trực quan của dữ liệu mà mô hình chứa.

  • Controller- Bộ điều khiển hoạt động trên cả Model và view. Nó kiểm soát luồng dữ liệu vào đối tượng mô hình và cập nhật chế độ xem bất cứ khi nào dữ liệu thay đổi. Nó giữ Chế độ xem và Mô hình tách biệt.

Thực hiện

Chúng ta sẽ tạo một đối tượng Student hoạt động như một mô hình. StudentView sẽ là một lớp xem có thể in thông tin chi tiết của sinh viên trên bảng điều khiển và StudentController là lớp điều khiển chịu trách nhiệm lưu trữ dữ liệu trong đối tượng Student và cập nhật dạng xem StudentView cho phù hợp.

MVCPatternDemo , lớp demo của chúng tôi sẽ sử dụng StudentController để chứng minh việc sử dụng mẫu MVC.

Bước 1

Tạo mô hình.

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

Bước 2

Tạo Chế độ xem.

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

Bước 3

Tạo Bộ điều khiển.

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

Bước 4

Sử dụng các phương thức StudentController để chứng minh việc sử dụng mẫu thiết kế 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;
   }
}

Bước 5

Xác minh kết quả đầu ra.

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

Mẫu Đại biểu Doanh nghiệp được sử dụng để phân tách cấp trình bày và cấp kinh doanh. Về cơ bản, nó được sử dụng để giảm chức năng giao tiếp hoặc tra cứu từ xa đối với mã cấp nghiệp vụ trong mã cấp trình bày. Trong cấp doanh nghiệp, chúng tôi đã theo dõi các thực thể.

  • Client - Mã bậc trình bày có thể là mã JSP, servlet hoặc UI java.

  • Business Delegate - Một lớp điểm vào duy nhất cho các thực thể khách hàng để cung cấp quyền truy cập vào các phương thức Dịch vụ Doanh nghiệp.

  • LookUp Service - Đối tượng dịch vụ tra cứu chịu trách nhiệm triển khai nghiệp vụ tương đối và cung cấp quyền truy cập đối tượng nghiệp vụ vào đối tượng ủy nhiệm nghiệp vụ.

  • Business Service- Giao diện Business Service. Các lớp Concrete thực hiện dịch vụ nghiệp vụ này để cung cấp logic triển khai nghiệp vụ thực tế.

Thực hiện

Chúng ta sẽ tạo một Client , BusinessDelegate , BusinessService , LookUpService , JMSServiceEJBService đại diện cho các thực thể khác nhau của mẫu Business Delegate.

BusinessDelegatePatternDemo , lớp demo của chúng tôi sẽ sử dụng BusinessDelegateClient để chứng minh việc sử dụng mẫu Business Delegate.

Bước 1

Tạo giao diện BusinessService.

BusinessService.java

public interface BusinessService {
   public void doProcessing();
}

Bước 2

Tạo lớp dịch vụ kết hợp.

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

Bước 3

Tạo Dịch vụ Tra cứu Doanh nghiệp.

BusinessLookUp.java

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

Bước 4

Tạo Đại diện Doanh nghiệp.

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

Bước 5

Tạo khách hàng.

Student.java

public class Client {
	
   BusinessDelegate businessService;

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

   public void doTask(){		
      businessService.doTask();
   }
}

Bước 6

Sử dụng các lớp BusinessDelegate và Client để thể hiện mẫu 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();
   }
}

Bước 7

Xác minh kết quả đầu ra.

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

Mẫu thực thể tổng hợp được sử dụng trong cơ chế bền vững EJB. Thực thể hỗn hợp là một bean thực thể EJB đại diện cho một đồ thị của các đối tượng. Khi một thực thể kết hợp được cập nhật, các đối tượng phụ thuộc nội bộ sẽ được cập nhật tự động khi được quản lý bởi bean thực thể EJB. Sau đây là những người tham gia Composite Bean Entity.

  • Composite Entity - Nó là bean thực thể chính, nó có thể là hạt thô hoặc có thể chứa một đối tượng hạt thô được sử dụng cho mục đích bền bỉ.

  • Coarse-Grained Object-Đối tượng này chứa các đối tượng phụ thuộc. Nó có vòng đời riêng và cũng quản lý vòng đời của các đối tượng phụ thuộc.

  • Dependent Object - Đối tượng phụ thuộc là một đối tượng phụ thuộc vào đối tượng Coarse-Grained cho vòng đời bền bỉ của nó.

  • Strategies - Các chiến lược thể hiện cách triển khai Thực thể tổng hợp.

Thực hiện

Chúng ta sẽ tạo đối tượng CompositeEntity hoạt động như CompositeEntity. CoarseGrainedObject sẽ là một lớp chứa các đối tượng phụ thuộc. CompositeEntityPatternDemo , lớp demo của chúng tôi sẽ sử dụng lớp Client để chứng minh việc sử dụng mẫu Composite Entity.

Bước 1

Tạo các đối tượng phụ thuộc.

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

Bước 2

Tạo đối tượng hạt thô.

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

Bước 3

Tạo đối tượng kết hợp.

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

Bước 4

Tạo lớp Client để sử dụng 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);
   }
}

Bước 5

Sử dụng Máy khách để chứng minh việc sử dụng mẫu thiết kế Đối tượng kết hợp.

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

Bước 6

Xác minh kết quả đầu ra.

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

Mẫu đối tượng truy cập dữ liệu hoặc mẫu DAO được sử dụng để tách API hoặc hoạt động truy cập dữ liệu cấp thấp khỏi các dịch vụ kinh doanh cấp cao. Sau đây là những người tham gia Mẫu đối tượng truy cập dữ liệu.

  • Data Access Object Interface - Giao diện này xác định các hoạt động tiêu chuẩn được thực hiện trên (các) đối tượng mô hình.

  • Data Access Object concrete class-Lớp này thực hiện giao diện trên. Lớp này chịu trách nhiệm lấy dữ liệu từ nguồn dữ liệu có thể là cơ sở dữ liệu / xml hoặc bất kỳ cơ chế lưu trữ nào khác.

  • Model Object or Value Object - Đối tượng này là POJO đơn giản chứa các phương thức get / set để lưu trữ dữ liệu được truy xuất bằng lớp DAO.

Thực hiện

Chúng ta sẽ tạo một đối tượng Student hoạt động như một Mô hình hoặc Đối tượng Giá trị. StudentDao là Giao diện Đối tượng Truy cập Dữ liệu. StudentDaoImpl là lớp cụ thể triển khai Giao diện đối tượng truy cập dữ liệu. DaoPatternDemo , lớp demo của chúng tôi sẽ sử dụng StudentDao chứng minh việc sử dụng mẫu Đối tượng truy cập dữ liệu.

Bước 1

Tạo Đối tượng Giá trị.

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

Bước 2

Tạo giao diện đối tượng truy cập dữ liệu.

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

Bước 3

Tạo lớp concreate triển khai giao diện trên.

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

Bước 4

Sử dụng StudentDao để chứng minh cách sử dụng mẫu Đối tượng truy cập dữ liệu.

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

Bước 5

Xác minh kết quả đầu ra.

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

Mẫu thiết kế bộ điều khiển phía trước được sử dụng để cung cấp cơ chế xử lý yêu cầu tập trung để tất cả các yêu cầu sẽ được xử lý bởi một trình xử lý duy nhất. Trình xử lý này có thể thực hiện xác thực / ủy quyền / ghi nhật ký hoặc theo dõi yêu cầu và sau đó chuyển các yêu cầu đến trình xử lý tương ứng. Sau đây là các thực thể của kiểu thiết kế này.

  • Front Controller - Trình xử lý duy nhất cho tất cả các loại yêu cầu đến ứng dụng (dựa trên web / dựa trên máy tính để bàn).

  • Dispatcher - Front Controller có thể sử dụng đối tượng điều phối có thể gửi yêu cầu đến trình xử lý cụ thể tương ứng.

  • View - Các khung nhìn là đối tượng mà các yêu cầu được thực hiện.

Thực hiện

Chúng ta sẽ tạo FrontController , Dispatcher để hoạt động như Front Controller và Dispatcher tương ứng. HomeViewStudentView đại diện cho các chế độ xem khác nhau mà các yêu cầu có thể đến với bộ điều khiển phía trước.

FrontControllerPatternDemo , lớp demo của chúng tôi sẽ sử dụng FrontController để trình diễn Mẫu thiết kế Front Controller.

Bước 1

Tạo Chế độ xem.

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

Bước 2

Tạo Điều phối viên.

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

Bước 3

Tạo 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);
      }	
   }
}

Bước 4

Sử dụng FrontController để thể hiện Mẫu thiết kế bộ điều khiển phía trước.

FrontControllerPatternDemo.java

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

Bước 5

Xác minh kết quả đầu ra.

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

Mẫu thiết kế bộ lọc chặn được sử dụng khi chúng ta muốn thực hiện một số xử lý trước / xử lý sau với yêu cầu hoặc phản hồi của ứng dụng. Bộ lọc được xác định và áp dụng theo yêu cầu trước khi chuyển yêu cầu đến ứng dụng đích thực tế. Bộ lọc có thể thực hiện xác thực / ủy quyền / ghi nhật ký hoặc theo dõi yêu cầu và sau đó chuyển các yêu cầu đến các trình xử lý tương ứng. Sau đây là các thực thể của kiểu thiết kế này.

  • Filter - Bộ lọc sẽ thực hiện nhiệm vụ nhất định trước hoặc sau khi thực hiện yêu cầu bởi trình xử lý yêu cầu.

  • Filter Chain - Chuỗi Bộ lọc mang nhiều bộ lọc và giúp thực thi chúng theo thứ tự xác định trên mục tiêu.

  • Target - Đối tượng đích là trình xử lý yêu cầu

  • Filter Manager - Trình quản lý Bộ lọc quản lý các bộ lọc và Chuỗi bộ lọc.

  • Client - Client là đối tượng gửi yêu cầu đến đối tượng Target.

Thực hiện

Chúng ta sẽ tạo FilterChain , FilterManager , Target , Client dưới dạng các đối tượng khác nhau đại diện cho các thực thể của chúng ta. AuthenticationFilterDebugFilter đại diện cho các bộ lọc bê tông.

InterceptingFilterDemo , lớp demo của chúng tôi sẽ sử dụng Client để chứng minh Mẫu thiết kế bộ lọc chặn.

Bước 1

Tạo giao diện Bộ lọc.

Filter.java

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

Bước 2

Tạo bộ lọc bê tông.

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

Bước 3

Tạo mục tiêu

Target.java

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

Bước 4

Tạo chuỗi bộ lọc

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

Bước 5

Tạo trình quản lý bộ lọc

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

Bước 6

Tạo khách hàng

Client.java

public class Client {
   FilterManager filterManager;

   public void setFilterManager(FilterManager filterManager){
      this.filterManager = filterManager;
   }

   public void sendRequest(String request){
      filterManager.filterRequest(request);
   }
}

Bước 7

Sử dụng Máy khách để chứng minh Mẫu thiết kế bộ lọc chặn.

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

Bước 8

Xác minh kết quả đầu ra.

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

Mẫu thiết kế bộ định vị dịch vụ được sử dụng khi chúng ta muốn định vị các dịch vụ khác nhau bằng cách sử dụng tra cứu JNDI. Xem xét chi phí tìm kiếm JNDI cho một dịch vụ cao, mẫu Service Locator sử dụng kỹ thuật bộ nhớ đệm. Lần đầu tiên một dịch vụ được yêu cầu, Service Locator sẽ tìm kiếm trong JNDI và lưu vào bộ nhớ cache đối tượng dịch vụ. Tra cứu thêm hoặc cùng một dịch vụ thông qua Service Locator được thực hiện trong bộ nhớ cache của nó, giúp cải thiện hiệu suất của ứng dụng ở mức độ lớn. Sau đây là các thực thể của kiểu thiết kế này.

  • Service- Dịch vụ thực tế sẽ xử lý yêu cầu. Tham chiếu của dịch vụ như vậy sẽ được xem xét trong máy chủ JNDI.

  • Context / Initial Context -JNDI Context, mang tham chiếu đến dịch vụ được sử dụng cho mục đích tra cứu.

  • Service Locator - Service Locator là một điểm liên hệ duy nhất để nhận các dịch vụ bằng cách tra cứu JNDI, lưu vào bộ nhớ đệm của các dịch vụ.

  • Cache - Bộ nhớ đệm để lưu trữ các tham chiếu của các dịch vụ để sử dụng lại chúng

  • Client - Client là đối tượng gọi ra các dịch vụ thông qua ServiceLocator.

Thực hiện

Chúng ta sẽ tạo ServiceLocator , InitialContext , Cache , Service như các đối tượng khác nhau đại diện cho các thực thể của chúng ta. Service1Service2 đại diện cho các dịch vụ cụ thể.

ServiceLocatorPatternDemo , lớp demo của chúng tôi đang hoạt động như một ứng dụng khách ở đây và sẽ sử dụng ServiceLocator để chứng minh Mẫu thiết kế Service Locator.

Bước 1

Tạo giao diện Dịch vụ.

Service.java

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

Bước 2

Tạo ra các dịch vụ cụ thể.

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

Bước 3

Tạo InitialContext để tra cứu JNDI

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

Bước 4

Tạo bộ nhớ đệm

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

Bước 5

Tạo bộ định vị dịch vụ

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

Bước 6

Sử dụng ServiceLocator để chứng minh Mẫu thiết kế Service Locator.

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

Bước 7

Xác minh kết quả đầu ra.

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

Mẫu Đối tượng Truyền được sử dụng khi chúng ta muốn truyền dữ liệu có nhiều thuộc tính trong một lần từ máy khách đến máy chủ. Đối tượng chuyển giao còn được gọi là Đối tượng giá trị. Đối tượng chuyển giao là một lớp POJO đơn giản có các phương thức getter / setter và có thể tuần tự hóa để nó có thể được truyền qua mạng. Nó không có bất kỳ hành vi nào. Lớp nghiệp vụ Server Side thường lấy dữ liệu từ cơ sở dữ liệu và điền vào POJO và gửi nó đến máy khách hoặc chuyển nó theo giá trị. Đối với máy khách, đối tượng chuyển là chỉ đọc. Máy khách có thể tạo đối tượng truyền của riêng mình và chuyển nó đến máy chủ để cập nhật các giá trị trong cơ sở dữ liệu trong một lần. Sau đây là các thực thể của kiểu thiết kế này.

  • Business Object - Dịch vụ Kinh doanh điền vào Đối tượng chuyển với dữ liệu.

  • Transfer Object - POJO đơn giản, chỉ có các phương thức để đặt / lấy thuộc tính.

  • Client - Khách hàng yêu cầu hoặc gửi Đối tượng chuyển đến Đối tượng kinh doanh.

Thực hiện

Chúng ta sẽ tạo một StudentBO làm Đối tượng Doanh nghiệp, Student là Đối tượng Chuyển giao đại diện cho các thực thể của chúng ta.

TransferObjectPatternDemo , lớp demo của chúng tôi đang hoạt động như một ứng dụng khách ở đây và sẽ sử dụng StudentBOStudent để trình diễn Mẫu thiết kế đối tượng chuyển.

Bước 1

Tạo đối tượng chuyển giao.

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

Bước 2

Tạo Đối tượng Kinh doanh.

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

Bước 3

Sử dụng StudentBO để chứng minh Mẫu thiết kế đối tượng chuyển.

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

Bước 4

Xác minh kết quả đầu ra.

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