国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

程序員過關斬將--請不要隨便修改基類

monw3c / 2153人閱讀

摘要:而且修改老代碼,大大增加了出現的概率。這里菜菜再強調一遍架構設計的一項重要原則類應該對修改關閉,對擴展開放。附加在對象最外層的行為,不應該窺視被包裝的類型內部的一些特性。基于以上的設計思想,擴展的行為完全有能力修改,覆蓋玩家的某些行為。

初級版本

這是玩家的抽象基礎類,這個設計很好,把一些玩家共有的特性抽象出來

 //玩家的基礎抽象類
    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的行為接口,然后實現即可。但是這樣的設計就沒有問題了嗎?有,當然有

每次需求其實還是改動了已經存在的并且穩定運行的老代碼,這是不可取的。而且修改老代碼,大大增加了bug出現的概率。

假如現在我們的游戲有20種玩家類型,其中19種需要添加跳躍的行為,那我們需要修改19個玩家的子類,工作量是如此之大。

利用類似繼承的方式擴展對象的行為,是在編譯期就把對象的行為確定了。也就是說在設計層面,其實你已經把代碼寫死了。

有很多同學的代碼就到目前為止了

假設以下為產品狗一個月之后的新需求:

能跳躍的等級調整為11級

玩家添加能遁地的行為

新加了10種玩家類型

如果你讀到了這里,說明大家都是對于設計追求卓越的技術人。這里菜菜再強調一遍架構設計的一項重要原則

類應該對修改關閉,對擴展開放。

這里需要強調一點,設計的每個部分想要都遵循開放-關閉原則,通常很難做到。因為要想在不修改現有代碼的情況下,你需要花費許多時間和精力。遵循開放關閉原則,通常需要引入更多的抽象,增加更多的層次,增大代碼的復雜度。因此菜菜建議把注意力集中在業務中最有可能變化的點上,這些地方應用開放關閉原則。至于怎么確定哪些是變化的點,這需要對業務領域很強的理解和經驗了。

現在我們分析一下我們要做的事情,我們希望一個對象(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
重要提示

以上代碼級別上屬于演示代碼,但是設計的理念卻很重要。基于以上的設計思想,擴展的行為完全有能力修改,覆蓋玩家的某些行為。比如玩家對象本身有一個喊話的行為,那擴展類根據業務完全可以讓喊話行為執行兩次等等修改。

添加關注,查看更精美版本,收獲更多精彩

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/74744.html

相關文章

  • 開篇:二十三種設計模式的通俗理解

    摘要:里氏替換原則里氏代換原則面向對象設計的基本原則之一。里氏代換原則中說,任何基類可以出現的地方,子類一定可以出現。里氏代換原則是對開閉原則的補充。而基類與子類的繼承關系就是抽象化的具體實現,所以里氏代換原則是對實現抽象化的具體步驟的規范。 showImg(https://segmentfault.com/img/bVbuXAu?w=640&h=361); 本文為本次系列文章的第一篇,接下...

    morgan 評論0 收藏0
  • 序員過關斬將--面試官再問你Http求過程,懟回去!

    摘要:介紹超文本傳輸協議,是互聯網上應用最為廣泛的一種網絡協議。年美國人構思了一種通過計算機處理文本信息的方法,并稱之為超文本這成為了超文本傳輸協議標準架構的發展根基。 Http介紹 超文本傳輸協議(HTTP,HyperText Transfer Protocol)是互聯網上應用最為廣泛的一種網絡協議。所有的WWW文件都必須遵守這個標準。設計HTTP最初的目的是為了提供一種發布和接收HTML...

    luoyibu 評論0 收藏0
  • 必須知道的序員思維

    摘要:以及之前說過的,當程序員就是為了提高社會效率。寫高效的代碼是每個程序員的追求,寫易懂的代碼是每個程序員的美德。讓正確的程序更快,要比讓快速的程序正確容易得多。我覺得這樣才能當一個有格局的程序員。 在博客閱讀:https://ssshooter.com/2019-04... 工作 寫程序不是為了炫耀自己的技術,是要給公司創造價值,要確實幫助使用這個程序的人。以及之前說過的,當程序員就是為...

    Joyven 評論0 收藏0
  • Python “黑魔法” 之 Meta Classes

    摘要:幸而,提供了造物主的接口這便是,或者稱為元類。接下來我們將通過一個栗子感受的黑魔法,不過在此之前,我們要先了解一個語法糖。此外,在一些小型的庫中,也有元類的身影。 首發于 我的博客 轉載請注明出處 接觸過 Django 的同學都應該十分熟悉它的 ORM 系統。對于 python 新手而言,這是一項幾乎可以被稱作黑科技的特性:只要你在models.py中隨便定義一個Model的子類,Dj...

    LeoHsiun 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<