模式定義:
引用共享技術(shù)有效的支持大量細(xì)粒度顆粒。
模式場(chǎng)景
- 五子棋,五子棋除去顏色不一樣外剩下的全都一樣,我們不需要每次都去創(chuàng)建一個(gè)新的五子棋,我們只需要每次改變它的顏色即可。
模式結(jié)構(gòu)
模式結(jié)構(gòu)
Flyweight:享元接口,通過(guò)這個(gè)接口Flyweight可以接受并作用于外部狀態(tài)。痛過(guò)這個(gè)接口可以傳入外部的狀態(tài),在享元對(duì)象的方法處理中可能會(huì)使用這些外部的數(shù)據(jù)。
ConcreteFlyweight:具體的享元實(shí)現(xiàn)對(duì)象,必須是共享的,需要封裝Flyweight的內(nèi)部狀態(tài)。
UnshareConcreteFlyweight:非共享的享元實(shí)現(xiàn)對(duì)象,并不是所有的Flyweight實(shí)現(xiàn)對(duì)象都需要共享。非共享的享元實(shí)現(xiàn)對(duì)象通常是對(duì)享元對(duì)象的組合對(duì)象。
FlyweightFactoty:享元工廠,主要用來(lái)創(chuàng)建并管理共享的享元對(duì)象,并對(duì)外提供訪問(wèn)共享享元的接口。
Client: 享元客戶端,主要的工作就是維持一個(gè)對(duì)Flyweight的引用,計(jì)算或存儲(chǔ)享元的外部狀態(tài),當(dāng)然這里可訪問(wèn)共享和不共享的Flyweight對(duì)象。
代碼實(shí)現(xiàn)
UML圖
源碼
public interface ChessFlyWeight {
void setColor(String c);
String getColor();
void display(Coordinate c);
}
@Data
class ConcreteChess implements ChessFlyWeight {
private String color;
public ConcreteChess(String color) {
super();
this.color = color;
}
public void display(Coordinate c) {
System.out.println("棋子顏色:" + color);
System.out.println("棋子位置:" + c.getX() + "----" + c.getY());
}
}
public class ChessFlyWeightFactory {
//享元池
private static Map<String,ChessFlyWeight> map = new HashMap<String, ChessFlyWeight>();
public ChessFlyWeight getChess(String color){
if(map.get(color)!=null){
return map.get(color);
}else{
ChessFlyWeight cfw = new ConcreteChess(color);
map.put(color, cfw);
return cfw;
}
}
}
@Data
@AllArgsConstructor
public class Coordinate {
private int x, y;
}
public class Client {
public static void main(String[] args) {
ChessFlyWeightFactory factory = new ChessFlyWeightFactory();
ChessFlyWeight chess1 = factory.getChess("黑色");
ChessFlyWeight chess2 = factory.getChess("黑色");
System.out.println(chess1);
System.out.println(chess2);
System.out.println("增加外部狀態(tài)的處理===========");
chess1.display(new Coordinate(10, 10));
chess2.display(new Coordinate(20, 20));
}
}
模式的優(yōu)缺點(diǎn)
模式的優(yōu)點(diǎn)
- 減少對(duì)象數(shù)量,節(jié)省內(nèi)存空間。
模式的缺點(diǎn)
- 維護(hù)共享對(duì)象,需要額外開(kāi)銷(xiāo)。(比如:一個(gè)線程來(lái)回收垃圾)
思考
模式本質(zhì):分離和共享
開(kāi)發(fā)中的應(yīng)用場(chǎng)景:
享元模式由于其共享的特征,可以在任何“池”中操作,比如:線程池,數(shù)據(jù)庫(kù)連接池。
String類(lèi)的設(shè)計(jì)也是享元模式。