Prototype Pattern thường được sử dụng để nhân bản một object
với lưu ý về mặt hiệu năng xử lý. Protype Pattern được xếp vào nhóm các pattern Khởi Tạo.
Prototype Pattern sử dụng một giao diện kiểu mẫu để tạo ra một bản sao clone
của một object
. Pattern này được sử dụng khi mà việc khởi tạo một object
trực tiếp gặp nhiều khó khăn và tiêu tốn tài nguyên về thời gian.
Ví dụ, một object
được tạo ra sau một lần mở kết nối tới CSDL có thể được cho là đắt đỏ. Chúng ta có thể ghi đệm lại object
này vào một cache
, và lần tới khi yêu cầu được gửi đến, chúng ta có thể tạo ra một bản sao clone
và trả về, đồng thời cập nhật CSDL, thay vì truy xuất lại thông tin từ CSDL và khởi tạo lại object
từ đầu.
Áp dụng triển khai
- Chúng ta sẽ tạo
01 abstract class Shape
. - Và các
class
mô tả thực thể mở rộngShape
. - Ở bước tiếp theo,
01 class Cache
ghi đệm cácobject
đã được tạo ra sẽ được định nghĩa. - Cuối cùng là code
main
ởPatternDemo
sẽ sử dụngCache
để yêu cầu lấy cácobject Shape
.
Về mặt quản lý code, chúng ta sẽ có 01 package
tên là shapeprototype
. Code sử dụng ở phía client sẽ chỉ có thể tham chiếu tới Cache
và Shape
được mở public
. Các thành phần còn lại của shapeprototype
đều được đặt access modifier
là default
.
Bước 1
Tạo 01 abstract class Shape
triển khai interface Cloneable
.
shapeprototype/Shape.java
packageshapeprototype;publicabstractclassShapeimplementsCloneable{privateString id;protectedString type;publicabstractvoiddraw();publicStringgetType(){return type;}publicvoidsetId(String id){this.id = id;}publicStringgetId(){return id;}@OverridepublicObjectclone(){Object clone =null;try{
clone =super.clone();}catch(CloneNotSupportedException e){
e.printStackTrace();}return clone;}}
Bước 2
Tạo các class
mô tả thực thể mở rộng Shape
.
shapeprototype/Circle.java
packageshapeprototype;classCircleextendsShape{publicCircle(){
type ="circle";}@Overridepublicvoiddraw(){System.out.println("Một hình tròn.");}}
shapeprototype/Triangle.java
packageshapeprototype;classTriangleextendsShape{publicTriangle(){
type ="triangle";}@Overridepublicvoiddraw(){System.out.println("Một hình tam giác.");}}
shapeprototype/Square.java
packageshapeprototype;classSquareextendsShape{publicSquare(){
type ="square";}@Overridepublicvoiddraw(){System.out.println("Một hình vuông.");}}
Bước 3
Tạo 01 class Cache
để truy vấn các object Shape
từ CSDL và ghi đệm vào một.
shapeprototype/Cache.java
packageshapeprototype;importjava.util.Hashtable;publicclassCache{privatestaticHashtable<String,Shape> cachedShapes =newHashtable<String,Shape>();publicstaticShapegetShape(String id){return(Shape) cachedShapes.get(id).clone();}publicstaticvoidload(){Circle circle =newCircle();
circle.setId("1");
cachedShapes.put(circle.getId(), circle);Triangle triangle =newTriangle();
triangle.setId("2");
cachedShapes.put(triangle.getId(), triangle);Square square =newSquare();
square.setId("3");
cachedShapes.put(square.getId(), square);}}
Bước 4
Tại PatternDemo
, sử dụng Cache
để tạo ra các bản sao của các object Shape
được ghi đệm trước đó trong Hashtable.
PatternDemo.java
importshapeprototype.Cache;importshapeprototype.Shape;publicclassPatternDemo{publicstaticvoidmain(String[] args){Cache.load();Shape clonedCircle =(Shape)Cache.getShape("1");System.out.println("=== Cloned "+ clonedCircle.getType());
clonedCircle.draw();Shape clonedTriangle =(Shape)Cache.getShape("2");System.out.println("=== Cloned "+ clonedTriangle.getType());
clonedTriangle.draw();Shape clonedSquare =(Shape)Cache.getShape("3");System.out.println("=== Cloned "+ clonedSquare.getType());
clonedSquare.draw();}}
Bước 5
Kiểm chứng lại thông tin được in ra ở console
.
console
===Cloned circle
Một hình tròn.===Cloned triangle
Một hình tam giác.===Cloned square
Một hình vuông.
Nguồn: viblo.asia