Flyweight được sử dụng chủ yếu để giảm thiểu số lượng object
cần được khởi tạo để tiết kiệm
bộ nhớ đệm và cải thiện hiệu năng hoạt động của phần mềm. Flyweight được xếp vào nhóm các
pattern Kiến Trúc.
Flyweight luôn cố gắng tái sử dụng những object
cùng loại đã tồn tại trước đó và chỉ khởi tạo
object
mới khi không tìm thấy object
nào phù hợp.
Áp dụng triển khai
Ở đây chúng ta có một phần mềm vẽ các hình tròn 2D. Phần mềm này sẽ vẽ khoảng 20 hình tròn
có màu sắc và vị trí khác nhau. Tuy nhiên nhờ có Flyweight, chúng ta sẽ chỉ cần tạo ra 5 object
mô tả thực thể hình tròn tương ứng với 5 màu sắc khả dụng.
Chúng ta có class
mô tả thực thể Circle
và sau đó là Factory
được định nghĩa để thực hiện
công việc khởi tạo các object Circle
khi cần thiết. Tuy nhiên, ở đây Factory
có một HashMap
để lưu lại những object Circle
đã từng khởi tạo với mỗi màu sắc. Do đó, khi có yêu cầu khởi
tạo một object Circle
với một màu sắc cụ thể, Factory
sẽ kiểm tra xem trước đó đã tạo ra
thứ tương tự hay chưa. Nếu như có object
phù hợp được tìm thấy trong HashMap
đã lưu trữ
thì sẽ trả về object
đó, còn nếu như chưa có thì khởi tạo object
mới và đồng thời lưu lại.
Bước 1
Tạo class Circle
mô tả thực thể hình tròn 2D.
flyweightpatter/Circle.java
packageflyweightpattern;publicclassCircle{privateString color;privateint x;privateint y;privateint r;publicCircle(String color){this.color = color;}publicvoidsetX(int x){this.x = x;}publicvoidsetY(int y){this.y = y;}publicvoidsetR(int r){this.r = r;}publicvoiddraw(){System.out.println("Circle::Draw() [ Color: "+ color +", x: "+ x +", y: "+ y +", radius: "+ r +" ]");}}
Bước 2
Tạo Factory
thực hiện công việc khởi tạo các object Circle
.
flyweightpattern/Factory.java
packageflyweightpattern;importjava.util.HashMap;publicclassFactory{privatestaticfinalHashMap<String,Circle> circleMap =newHashMap<String,Circle>();publicstaticCirclegetCircle(String color){if(circleMap.containsKey(color)){return circleMap.get(color);}else{System.out.println("Creating circle of color: "+ color);Circle c =newCircle(color);
circleMap.put(color, c);return c;}}}
Bước 3
Sử dụng Factory
để yêu cầu lấy các object Circle
bằng cách truyền vào thông tin về màu sắc.
PatternDemo.java
importflyweightpattern.Circle;importflyweightpattern.Factory;publicclassPatternDemo{privatestaticfinalString colorList[]={"Red","Green","Blue","White","Black"};publicstaticvoidmain(String[] args){for(int i=0; i<20; i++){Circle c =Factory.getCircle(randomCollor());
c.setX(randomX());
c.setY(randomY());
c.setR(100);
c.draw();}}privatestaticStringrandomCollor(){return colorList[(int)(Math.random()* colorList.length)];}privatestaticintrandomX(){return(int)(Math.random()*100);}privatestaticintrandomY(){return(int)(Math.random()*100);}}
Bước 4
Kiểm chứng lại kết quả được in ra ở console
.
console
Creating circle of color:RedCircle::Draw()[Color:Red, x:20, y:91, radius:100]Circle::Draw()[Color:Red, x:93, y:33, radius:100]Creating circle of color:WhiteCircle::Draw()[Color:White, x:49, y:40, radius:100]Creating circle of color:GreenCircle::Draw()[Color:Green, x:82, y:60, radius:100]Circle::Draw()[Color:White, x:27, y:73, radius:100]Creating circle of color:BlackCircle::Draw()[Color:Black, x:66, y:5, radius:100]Circle::Draw()[Color:Red, x:71, y:69, radius:100]Circle::Draw()[Color:White, x:39, y:87, radius:100]Circle::Draw()[Color:Black, x:82, y:25, radius:100]Circle::Draw()[Color:Green, x:24, y:69, radius:100]Circle::Draw()[Color:Black, x:83, y:17, radius:100]Circle::Draw()[Color:Red, x:60, y:27, radius:100]Circle::Draw()[Color:Black, x:48, y:73, radius:100]Circle::Draw()[Color:Red, x:99, y:10, radius:100]Circle::Draw()[Color:Red, x:86, y:74, radius:100]Creating circle of color:BlueCircle::Draw()[Color:Blue, x:94, y:85, radius:100]Circle::Draw()[Color:White, x:87, y:51, radius:100]Circle::Draw()[Color:Red, x:82, y:81, radius:100]Circle::Draw()[Color:White, x:94, y:2, radius:100]Circle::Draw()[Color:White, x:75, y:74, radius:100]
Nguồn: viblo.asia