iT邦幫忙

2022 iThome 鐵人賽

DAY 17
0

今日目標,定義房間、房間列表。

Room

我們首先定義一個房間應該要有的資訊,房主(owner)、其他成員(guests)、房號(roomId),再來就實作這個類別吧!

  1. 先建立 package,名稱為 room
  2. 在 room package 底下建立一個 java class,名稱為 Room,內容為:
    package com.example.room;
    
    import lombok.Getter;
    
    import java.util.ArrayList;
    
    public class Room {
        private final String owner;
        private final ArrayList<String> guests;
        private final String roomId;
    
        public Room(String roomId,String ownerName) {
            this.roomId = roomId;
            this.owner = ownerName;
            this.guests = new ArrayList<>();
        }
    }
    
  3. 然後我們定義一下這些資訊的存取方法,加入成員(addGuest)、移除成員(removeGuest)、計算人數(count)、取得所有成員(getAllMembers)、取得房間資訊(getInfo),以及各成員變數的 getter,修改其內容為:
    package com.example.room;
    
    import lombok.Getter;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Map;
    
    public class Room {
        @Getter
        private final String owner;
    
        @Getter
        private final ArrayList<String> guests;
    
        @Getter
        private final String roomId;
    
        public Room(String roomId,String ownerName) {
            this.roomId = roomId;
            this.owner = ownerName;
            this.guests = new ArrayList<>();
        }
    
        public boolean addGuest(String guestName) {
            if (this.guests.size() >= 3) {
                return false;
            }
            this.guests.add(guestName);
            return true;
        }
    
        public void removeGuest(String guestName) {
            this.guests.remove(guestName);
        }
    
        public int count() {
            return 1 + this.guests.size();
        }
    
        public ArrayList<String> getAllMembers() {
            ArrayList<String> allPeople = new ArrayList<>();
            allPeople.add(this.owner);
            allPeople.addAll(this.guests);
            return allPeople;
        }
    
        public Map<String, Object> getInfo() {
            Map<String , Object> info = new HashMap<>();
            info.put("roomId", this.roomId);
            info.put("owner", this.owner);
            info.put("guests", this.guests);
            info.put("number", this.count());
            return info;
        }
    }
    

Random

我們希望房號由英數隨機組成 8 碼,並且這些房號都不重複,所以我們建構一個 RandomString 的類別來提供這個方法。

  1. 建立一個 package,名稱為 random
  2. 在 random package 底下建立一個 java class,名稱為 RandomString,內容為:
    package com.example.random;
    
    import java.util.Locale;
    import java.util.Random;
    
    public class RandomString {
        public static final String upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        public static final String lower = upper.toLowerCase(Locale.ROOT);
        public static final String digits = "0123456789";
        public static final String symbols = upper + lower + digits;
    
        public static String get(int length) {
            StringBuilder result = new StringBuilder();
            char[] array = symbols.toCharArray();
            for (int i=0; i<length; i++) {
                int randomInt = new Random().nextInt(array.length);
                result.append(array[randomInt]);
            }
            return result.toString();
        }
    }
    
  3. 呼叫的很簡單,RandomString.get(<長度>)

Room List

再來定義 RoomList 的類別吧,在這裡我們將它定義成一個 Component 的實例,也就是在這次程式運行中,只會產生一個實體,可以在不同 controller 使用其資料,而這個實體的內部是由一個 HashMap 實現,其中 key 是房號,value 是 Room 的物件:

  1. 在 room package 底下建立一個 java class,名稱為 RoomList,內容為:
    package com.example.room;
    
    import org.springframework.stereotype.Component;
    
    import java.util.HashMap;
    import java.util.Map;
    
    @Component
    public class RoomList {
        private final Map<String, Room> roomList = new HashMap<>();
    }
    
  2. 定義這個實例的一些存取方法,將 Room 加入(add)、建立一個合法的 Room 並將其加入(create)、判斷是否包含某房號(containRoomId)、取得所有房間(getRooms),完整內容為:
    package com.example.room;
    
    import com.example.random.RandomString;
    import org.springframework.stereotype.Component;
    
    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.Map;
    
    @Component
    public class RoomList {
        private final Map<String, Room> roomList = new HashMap<>();
    
        public boolean add(String roomId, Room room) {
            if (containRoomId(roomId)) {
                return false;
            }
            roomList.put(roomId, room);
            return true;
        }
    
        public String create(String username) {
            String roomId;
            do {
                roomId = RandomString.get(8);
            }
            while (containRoomId(roomId));
            Room newRoom = new Room(roomId, username);
            add(roomId, newRoom);
            return roomId;
        }
    
        public boolean containRoomId(String roomId) {
            return roomList.containsKey(roomId);
        }
    
        public Room getRoomById(String roomId) {
            if (containRoomId(roomId)) {
                return roomList.get(roomId);
            }
            return null;
        }
    
        public HashSet<Room> getRooms() {
            return new HashSet<>(roomList.values());
        }
    }
    

今天的程式碼比較容易一些,只是定義我們之後會用到的類型~~
「實例」的概念可能目前有些難以理解,但沒關係,之後我們使用 controller 來對這些實例做存取就會比較容易理解了!
/images/emoticon/emoticon07.gif
(其實小弟有點不太確定這邊的 RoomList 是否應該再為其定義一個 Service 來提供存取資料的方法?)


上一篇
Day 15 - WebSocket Config
下一篇
Day 17 - 記錄使用者的狀態
系列文
Spring Boot... 深不可測31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言