23中設計模式在遊戲伺服器裡面例子
遊戲裡面有很多資料有用XML 形式配置,有用資料庫生成。
建立型(6)
1.簡單工廠模式
由一個工廠物件決定創建出哪一種產品類的例項。
比如在遊戲活動設計的時候:每個活動配置資料的生成
public abstract class AbsLimitActivity{
private byte id;
private byte type;
private String nam
private long startTime;
private long endTime;
}
一個活動類的抽象類,當有新活動時繼承
在生成活動資料的時候外面可以用簡單工程更據活動ID 來生成放在manger裡面管理
public <T extends AbsActivity> T createActiviy(byte activityId){ AbsActivity absActivity=null; switch (activityId) { case TIME_CAMPAIGN:absActivity=new LimitActTimeCampaign();break; case RICH_CAT: absActivity=new LimitActRichCat();break; case DAY_CHARGE: absActivity=new LimitActDayCharge();break; case CHARGE_REWARD:absActivity=new LimitActChargeReward();break; default:return null; } return (T) absActivity; }
2、抽象工廠模式(Abstract Factory)
一個產品家族提供了統一的建立介面。當需要這個產品家族的某一系列的時候,可以從抽象工廠中選出相對系的系列來建立一個具體的工廠類別。
同樣活動裡面:
有2大類:一類是開服活動,另一類是配置活動開服,關服的時間
則可以有2個工廠來繼承
public abstract class AbsFactory {
public abstract <T extends AbsActivity> T createActiviy(int id);
}
public class OpenServerActivityFactory extends AbsFactory { @Override public <T extends AbsActivity> T createActiviy(int id) { // TODO Auto-generated method stub return null; } }
public class ScheduleActivityFactory extends AbsFactory{
@Override
public <T extends AbsActivity> T createActiviy(int id) {
// TODO Auto-generated method stub
return null;
}
}
public class ActiviytManager {
public static final int OPEN_SERVRE_FACTORY = 1;
public static final int SCHEDULE_FACTORY = 2;
public AbsActivity createActivity(int factoryType, int activityId) {
switch (factoryType) {
case OPEN_SERVRE_FACTORY: new OpenServerActivityFactory().createActiviy(activityId);
break;
case SCHEDULE_FACTORY:new ScheduleActivityFactory().createActiviy(activityId);
break;
default:
break;
}
return null;
}
}
抽象工廠模式是在工廠方法上加了一個維度,抽象工廠模式簡單地說及時把工廠進行了一次包裝,工廠模式是把產品生產進行包裝,對外提供介面。既然抽象工廠模式是站在工廠方法肩膀上的,所以繼承工廠方法的所有優點。 抽象工廠對於工廠進行了包裝,使得使用和工廠(工廠和生產兩個級別的概念)的解耦,使得工廠類的擴充套件得到了實現,進一步增強了擴充套件性。
3、單例模式(Singleton)
一種常用的設計模式。在Java應用中,單例物件能保證在一個JVM中,該物件只有一個例項存在。
public class ActiviytManager {
/**
* 單例說明
*/
public static ActiviytManager instance;
public static ActiviytManager getInstance() {
if(instance==null) {
synchronized(ActiviytManager.class){
instance =new ActiviytManager();
}
}
return instance;
}
}
單例類只能有一個例項。 單例類必須自己建立自己的唯一例項。 單例類必須給所有其他物件提供這一例項。(靜態方法get例項)
單例類比較靈活,畢竟從實現上只是一個普通的Java類,只要滿足單例的基本需求,你可以在裡面隨心所欲的實現一些其它功能,但是靜態類不行。
4、建造者模式(Builder)
建立單個類的模式,而建造者模式則是將各種產品集中起來進行管理,用來建立複合物件,所謂複合物件就是指某個類具有不同的屬性。
/**
* 簡單例子 麼有新增屬性
* @param dataList
* @return
*/
public List<AbsActivity> buildActivityList(List<DbActivityData> dataList){
List<AbsActivity> list=new ArrayList<>();
for(DbActivityData data:dataList) {
list.add(createActivity(data.getType(), data.getId()));
}
return list;
}
在接著ActiviytManager 裡面再加上這個方法在這裡就可以說是用到建造者模式
建造者模式將很多功能整合到一個類裡,這個類可以創造出比較複雜的東西。所以與工程模式的區別就是:工廠模式關注的是建立單個產品,而建造者模式則關注建立符合物件,多個部分。因此,是選擇工廠模式還是建造者模式,依實際情況而定。
eg:遊戲例子,這裡取真實工程裡面的程式碼例項
/**
* 道具建立(對歷史遺留做相容~~,簡單的整合)
* @author ganzhuolin
*/
public class ItemBuild {
private static Logger log = LoggerFactory.getLogger(ItemFactory.class);
/**
* 建立物品物件 帶有強化等級和卓越屬性的
* @param itemModelId 道具模型Id
* @param num 數量
* @param bind 是否繫結
* @param losttime 過期時間,秒數 (0 會讀配置的過期時間,其他值則直接賦值過期時間)
* @param grade 強化等級
* @param zhuoyue 卓越屬性
* @return {@link List<Item>} 道具集合
*/
public static List<Item> createItems(int itemModelId, int num, boolean bind, long losttime, int grade, String zhuoyue) {
return createItems(itemModelId, num, bind, losttime, grade, 0, zhuoyue);
}
/**
* 建立物品物件 帶有強化等級
* @param itemModelId 道具id
* @param num 是否繫結
* @param bind 是否繫結
* @param losttime 過期時間,秒數 (0 會讀配置的過期時間,其他值則直接賦值過期時間)
* @param grade 等級
* @param unuse 沒有用到
* @return {@link List<Item>} 道具集合
*/
public static List<Item> createItems(int itemModelId, int num, boolean bind, long losttime, int grade, int unuse) {
return createItems(itemModelId, num, bind, losttime, grade, 0, null);
}
/**
* 掉落物專用
* @param itemModelId 道具模型d
* @param num 是否繫結
* @param bind 是否繫結
* @param losttime 過期時間,秒數 (0 會讀配置的過期時間,其他值則直接賦值過期時間)
* @param grade 等級
* @param addAttribute 追加等級
* @return {@link List<Item>} 道具集合
*/
public static List<Item> createItemsForDropItem(int itemModelId, int num, boolean bind, long losttime, int grade, int addAttribute) {
return createItems(itemModelId, num, bind, losttime, grade, addAttribute, null);
}
/**
* 建立普通物品(忽略了堆疊數限制)
* @param itemModelId
* @param num
* @return
*/
public static Item createCommonGoods(int itemModelId, int num) {
Item item = new CommonGoods();
item.setItemModelId(itemModelId);
item.setNum(num);
item.setId(IdFactroy.getId());
return item;
}
}
5、原型模式(Prototype)
通過給出一個原型物件來指明所有建立的物件的型別,然後用複製這個原型物件的辦法創建出更多同類型的物件
與工程模式沒有關係,從名字即可看出,該模式的思想就是將一個物件作為原型,對其進行復制、克隆,產生一個和原物件類似的新物件。
一個原型類,只需要實現Cloneable介面,覆寫clone方法,此處clone方法可以改成任意的名稱,因為Cloneable介面是個空介面,你可以任意定義實現類的方法名,如cloneA或者cloneB,因為此處的重點是super.clone()這句話,super.clone()呼叫的是Object的clone()方法。
在遊戲中有很多道具,裝備,消耗品,等等,他們都是有一些共同的資料,在上獨有的資料構成
public abstract class Item implements Cloneable ,Serializable {
/**
* 原型Id
*/
protected int itemModelId;
/** 物品數量*/
protected int num;
/**
* 名字
*/
protected String name;
abstract Item clone();
}
淺複製:將一個物件複製後,基本資料型別的變數都會重新建立,而引用型別,指向的還是原物件所指向的。
深複製:將一個物件複製後,不論是基本資料型別還有引用型別,都是重新建立的。簡單來說,就是深複製進行了完全徹底的複製,而淺複製不徹底。
繼承上面抽象舉個例子:
public class Prototype extends Item {
/* 淺複製 */
@Override
public Object clone() throws CloneNotSupportedException {
Item proto = (Item) super.clone();
return proto;
}
/* 深複製 */
public Object deepClone() throws IOException, ClassNotFoundException {
/* 寫入當前物件的二進位制流 */
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
/* 讀出二進位制流產生的新物件 */
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return ois.readObject();
}
}
///更新中 待續.......