這是玩家的抽象基礎類,這個設計很好,把一些玩家共有的特性抽象出來bash
//玩家的基礎抽象類
abstract class Player
{
//玩家的級別
public int Level { get; set; }
//其餘屬性代碼省略一萬字
}
複製代碼
這是新加需求:10級能夠跳躍,具體跳躍動做是客戶端作處理架構
//玩家的基礎抽象類
abstract class Player
{
//玩家的級別
public int Level { get; set; }
//其餘屬性代碼省略一萬字
//新加玩家跳躍動做,因爲須要到達10級因此須要判斷level
public virtual bool Jump()
{
if (Level >= 10)
{
return true;
}
return false;
}
}
複製代碼
這種代碼初級人員很容易犯,有什麼問題呢?測試
因爲需求是增長玩家一個行爲,根據上一節的介紹,咱們應該瞭解到,行爲在代碼級別更傾向於用接口來表示。並且不是全部的玩家類型都須要附加跳躍這個行爲。據此優化以下:優化
//玩家跳躍的行爲
interface IJump
{
bool Jump();
}
//玩家的基礎抽象類
abstract class Player
{
//玩家的級別
public int Level { get; set; }
//其餘屬性代碼省略一萬字
}
//真實玩家
class PersonPlayer : Player, IJump
{
public bool Jump()
{
if (Level >= 10)
{
return true;
}
return false;
}
}
複製代碼
不錯,到此咱們已經避免了初級人員所犯的錯誤了,每種玩家類型能夠根據須要自行去擴展行爲,改天產品狗在加一個10級玩家能夠飛的行爲,頂多在加一個IFly的行爲接口,而後實現便可。可是這樣的設計就沒有問題了嗎?有,固然有ui
有不少同窗的代碼就到目前爲止了spa
假設如下爲產品狗一個月以後的新需求:架構設計
若是你讀到了這裏,說明你們都是對於設計追求卓越的技術人。這裏菜菜再強調一遍架構設計的一項重要原則設計
類應該對修改關閉,對擴展開放。code
這裏須要強調一點,設計的每一個部分想要都遵循開放-關閉原則,一般很難作到。由於要想在不修改現有代碼的狀況下,你須要花費許多時間和精力。遵循開放關閉原則,一般須要引入更多的抽象,增長更多的層次,增大代碼的複雜度。所以菜菜建議把注意力集中在業務中最有可能變化的點上,這些地方應用開放關閉原則。至於怎麼肯定哪些是變化的點,這須要對業務領域很強的理解和經驗了。cdn
如今咱們分析一下咱們要作的事情,咱們但願一個對象(player)在不改動的狀況下動態的給它賦予新的行爲,在業務上實現的功能和用繼承的結果相似。總之一句話:
現有的類型優雅的添加新行爲,而且能夠靈活疊加和替換
理想中的設計圖大體以下:
如今咱們認真分析一下,若是每一個新的行爲要想擴展對象而又能保持該對象的自身特性,新行爲對象必須是擴展對象的子類,還必須包含對象的一個引用才能實現。
假設如今真實玩家的定義以下:
//玩家的基礎抽象類
public abstract class Player
{
//玩家的級別
public int Level { get; set; }
//其餘屬性代碼省略一萬字
}
//真實玩家
public class PersonPlayer : Player
{
}
複製代碼
如今的需求是給真實玩家添加一個10級能跳躍的行爲,在不修改原有玩家代碼的狀況下,擴展跳躍行爲代碼以下
//玩家行爲的擴展積累
public class PlayerExtension : Player
{
protected Player player;
}
//跳躍玩家的行爲擴展類
public class PlayerJumpExtension: PlayerExtension
{
public PlayerJumpExtension(Player _player)
{
player = _player;
}
public bool Jump()
{
if (player. Level >= 10)
{
return true;
}
return false;
}
}
複製代碼
測試代碼以下:
PersonPlayer player = new PersonPlayer();
//給用戶動態添加跳躍的行爲
PlayerJumpExtension jumpPlayer = new PlayerJumpExtension(player);
var ret= jumpPlayer.Jump();
Console.WriteLine("玩家能不能跳躍:"+ret);
//如今玩家升級到10級了
player.Level = 10;
ret = jumpPlayer.Jump();
Console.WriteLine("玩家能不能跳躍:" + ret);
複製代碼
測試加過以下:
玩家能不能跳躍:False
玩家能不能跳躍:True
複製代碼
一個月後產品狗新加一個需求:真實玩家20級得到飛行的行爲,無序改動現有代碼,只需繼續添加一個能夠飛行的新擴展
//玩家能夠飛行的擴展
public class PlayerFlyExtension : PlayerExtension
{
public PlayerFlyExtension(Player _player)
{
player = _player;
}
public bool Fly()
{
if (player.Level >= 20)
{
return true;
}
return false;
}
}
複製代碼
測試代碼以下:
PlayerFlyExtension flyPlayer = new PlayerFlyExtension(player);
Console.WriteLine( "玩家能不能飛行"+flyPlayer.Fly());
player.Level = 20;
Console.WriteLine("玩家能不能飛行" + flyPlayer.Fly());
複製代碼
測試結果:
玩家能不能飛行False
玩家能不能飛行True
複製代碼
以上代碼級別上屬於演示代碼,可是設計的理念卻很重要。基於以上的設計思想,擴展的行爲徹底有能力修改,覆蓋玩家的某些行爲。好比玩家對象自己有一個喊話的行爲,那擴展類根據業務徹底可讓喊話行爲執行兩次等等修改。
添加關注,查看更精美版本,收穫更多精彩