iT邦幫忙

2023 iThome 鐵人賽

DAY 19
0
自我挑戰組

深入淺出設計模式 (Head First Design Pattern) - 重點整理及範例分享系列 第 19

[深入淺出設計模式] Ch5 The Singleton Pattern (3) - 【單例模式】範例 Website registration

  • 分享至 

  • xImage
  •  

單例模式 範例 Website registration 網站註冊

假設今天我們要架設一個網站的註冊系統,我們就會希望系統只有一個合法的註冊中心,所有使用者只能向它註冊。這時候就可以用單例模式來寫註冊中心的類別 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://ithelp.ithome.com.tw/upload/images/20231004/20163178ezpIwsjw5H.png


參考資料:

  1. 《深入淺出設計模式 (Head First Design Patterns) 》
  2. 書中官方程式碼傳送門

本篇範例完整程式碼

https://github.com/changtintin/Design-Pattern/tree/master/Ch5/Singleton


Disclaimer
因為讀的是原文版,所以難免會有翻譯詞不達意或是專有名詞上的差異,有錯誤的話歡迎在留言區一起交流!


上一篇
[深入淺出設計模式] Ch5 The Singleton Pattern (2) - 【單例模式】多執行緒處理 方式 (已更新)
下一篇
[深入淺出設計模式] Ch6 The Command Pattern (1) - 【命令模式】概念講解
系列文
深入淺出設計模式 (Head First Design Pattern) - 重點整理及範例分享35
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言