假設今天我們要架設一個網站的註冊系統,我們就會希望系統只有一個合法的註冊中心,所有使用者只能向它註冊。這時候就可以用單例模式來寫註冊中心的類別 RegisterCenter()
,確保只有一個RegisterCenter()
的instance。
首先是不同國籍使用者的類別,建構子設定變數registered
初始值為false,代表尚未註冊:
abstract public class Member {
public String name;
public String nationality;
boolean registered;
public void isRegistered(){
this.registered = true;
System.out.println("I'm "+name+", a member of this shopping site from now on");
}
}
public class Japanese extends Member {
public Japanese(String name){
nationality = "Japanese";
this.name = name;
this.registered = false;
System.out.println("I'm "+ name);
}
}
public class Taiwanese extends Member {
public Taiwanese(String name){
nationality = "Taiwanese";
this.name = name;
this.registered = false;
System.out.println("I'm "+ name);
}
}
這邊用懶漢模式來實現單例模式:
public class RegisterCenter {
private static RegisterCenter registerCenter;
protected ArrayList<Member> members = new ArrayList<Member>();
private RegisterCenter(){}
protected void setMember(Member member){
members.add(member);
}
protected void getMembers(){
System.out.print("Member List: ");
for (int i = 0; i < members.size(); i++) {
System.out.print(members.get(i).name + " ");
}
System.out.print("\n");
}
public static synchronized RegisterCenter getInstance(){
if(registerCenter == null){
registerCenter = new RegisterCenter();
}
return registerCenter;
}
public void registProcess(Member member){
try {
System.out.println("System: Working on "+member.name+"'s registration.....");
Thread.sleep(500);
System.out.println("System: member "+member.name+" register successful\n");
setMember(member);
//每次註冊完新會員,就顯示目前會員名單
getMembers();
} catch (Exception e) {
System.out.println(e);
}
}
}
在單例模式下,無論從哪裡註冊,都會用到同樣的RegisterCenter()
,最後測試一下:
public class Singleton {
public static void main(String[] args) {
RegisterCenter rc = RegisterCenter.getInstance();
Member Takuto = new Japanese("Takuto");
Member Ting = new Taiwanese("Ting");
Member Lin = new Taiwanese("Lin");
RegisterCenter japanRegisterCenter = RegisterCenter.getInstance();
japanRegisterCenter.registProcess(Takuto);
// 同時會有世界各地的使用者正在註冊
RegisterCenter taiwaRegisterCenter = RegisterCenter.getInstance();
taiwaRegisterCenter.registProcess(Ting);
taiwaRegisterCenter.registProcess(Lin);
}
}
輸出結果可以看到,員工名單都是同步更新的,表示會員都是跟同個註冊中心完成註冊:
https://github.com/changtintin/Design-Pattern/tree/master/Ch5/Singleton
Disclaimer
因為讀的是原文版,所以難免會有翻譯詞不達意或是專有名詞上的差異,有錯誤的話歡迎在留言區一起交流!