一、介紹
“享元”中“享”是共享的意思,“元”是對象的意思,享元模式意在降低系統(tǒng)內(nèi)存占用,通過共享對象的方法提高復用。在享元模式中,當系統(tǒng)中不存在所需對象時會創(chuàng)建,如果有那么則會復用,以此達到共享的目的。
二、UML類圖

享元模式
在這個例子中,Library作為系統(tǒng)中的抽象享元對象,book作為Library的內(nèi)部狀態(tài),不隨外部環(huán)境變化而變化,屬于Library的共享對象,不同的User都可以來借閱同一個book;User作為外部狀態(tài),隨外部環(huán)境變化而變化,在調用browse方法時傳進來。LibraryManager是抽象類Library的實現(xiàn)類,具體實現(xiàn)browse方法。此外還需要建立一個LibraryFactory工廠類,以聚合的方式保存Library實現(xiàn)類對象,這樣當客戶端Client通過工廠調用Library時,如果有book那么直接取出來用,不用新建,如果沒有那么新建,放到容器中去,方便下次再來取對象。
三、代碼實例
public abstract class Library {
private String mBook;
public Library(String name) {
this.mBook = name;
}
public String getName() {
return mBook;
}
public void setName(String mName) {
this.mBook = mName;
}
protected abstract void browser(User user);
}
public class LibraryManager extends Library{
public LibraryManager(String name) {
super(name);
}
@Override
protected void browser(User user) {
System.out.println("姓名:"+user.getName()+" 年齡:"+user.getAge()+" 借閱書籍:<<"+getName()+">>");
}
}
public class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class LibraryFactory {
private final HashMap<String, LibraryManager> map = new HashMap<>();
public void browse(String name,User user){
if (!map.containsKey(name)){
map.put(name,new LibraryManager(name));
}
map.get(name).browser(user);
}
}
四、總結
享元模式中,當系統(tǒng)中存在共享對象時,直接取出來復用,當系統(tǒng)中不存在時,新建一個對象返回,同時存到系統(tǒng)中方便下次取用。享元模式中分內(nèi)部狀態(tài)和外部狀態(tài)兩類對象,其中內(nèi)部狀態(tài)是指不隨外部環(huán)境變化而變化的變量,是可以用來共享的,外部狀態(tài)通常由外部傳進來,隨外部環(huán)境變化而變化,不能作為共享變量。
在Java中,常見的一些池技術就是基于享元模式實現(xiàn)的,比如線程池,String類型對象的創(chuàng)建等。