標籤:style blog http java io 資料 for ar
前幾天寫了一篇介紹枚舉功能強大的文章。有幾個朋友給我指正說,沒有案例單純描述不夠直觀。確實啊,在這裡我就在寫一個案例篇,對上次的文章做補充說明。
此案例是一個遊戲伺服器的訊息辨識器的簡化。做過遊戲開發都知道,用戶端和伺服器之間的互動需要定義很多的訊息類型,而且這個訊息類型是需要不斷擴充的。訊息辨識器就是根據用戶端發送過來的訊息編碼封裝成訊息實體物件,以供商務邏輯層處理。這裡就用這個簡化後的訊息辨識器展示一下枚舉的一個應用。(此處主要用作枚舉的一個應用執行個體示範,由於代碼做了簡化處理,設計上難免會有些不當之處,請見諒)
訊息實體類的一個介面:
public interface IMsg {public void setMsgCode(int code);public void execute();public void readData(IoBuffer bufer);public void writerData(IoBuffer bufer);}
訊息實體類的一個抽象類別:
public abstract class AbstractMsg implements IMsg{protected int msgCode;public AbstractMsg(int msgCode){this.msgCode = msgCode;}}
訊息實體的一個實作類別:
public class TestMsg extends AbstractMsg{public TestMsg(int msgCode) {super(msgCode);}private int data1;private int data2;@Overridepublic void setMsgCode(int code) {this.msgCode = code;}@Overridepublic void execute() {//訊息處理方法}@Overridepublic void readData(IoBuffer bufer) {this.data1 = bufer.getInt();this.data2 = bufer.getInt();}@Overridepublic void writerData(IoBuffer bufer) {}}
為了模組化管理,對枚舉類型抽出了一個介面,以後一個模組的訊息可以註冊到一個枚舉類上,而這些枚舉類都實現此介面
public interface IMsgCodeClass {public int getMsgCode();public Class<? extends AbstractMsg> getMsgClass();}
這是枚舉類,可以一個模組一個枚舉類,該模組下的訊息都註冊到該枚舉類下
public enum MsgCodeClassConstants implements IMsgCodeClass{test(1001,TestMsg.class)//在此就不多羅列一些了;private int msgCode;private Class<? extends AbstractMsg> msgClass;MsgCodeClassConstants(int msgCode,Class<? extends AbstractMsg> msgClass){this.msgCode = msgCode;this.msgClass = msgClass;}@Overridepublic int getMsgCode() {return msgCode;}@Overridepublic Class<? extends AbstractMsg> getMsgClass() {return msgClass;}}
最後是訊息辨識器類:
public class MsgRecogniser {Map<Integer, Class<? extends AbstractMsg>> msges = new ConcurrentHashMap<Integer, Class<? extends AbstractMsg>>();public void init(){MsgCodeClassConstants[] contants = MsgCodeClassConstants.values();for(int i=0;i<contants.length;i++){msges.put(contants[i].getMsgCode(), contants[i].getMsgClass());}}public IMsg getMsg(int msgCode){IMsg msg = null;Class clazz = msges.get(msgCode);try {Constructor constructor = clazz.getConstructor(int.class);msg= (IMsg) constructor.newInstance(msgCode);} catch (Exception e) {e.printStackTrace();}return msg;}}
訊息辨識器往往用在解碼器裡,解碼器接收到資料後首先讀取訊息編碼,然後根據編碼調用辨識器擷取訊息實體物件,調用訊息實體物件的readData方法把用戶端資料獨到訊息實體物件中。
以後要擴充訊息時,只需要編寫訊息實體類,然後註冊到枚舉類中就可以了。:)