我眼中的面向?qū)ο蠓治?/h1>

面向?qū)ο?/h1>

似乎我也沒學(xué)過其他的編程思維方式了瓦侮,面向?qū)ο笫俏揖幊虝r(shí)常用的思維方式壶笼,因?yàn)槲矣X得它更加貼近于我們的生活狮腿,更加容易地去理解和定義程序想要表達(dá)的內(nèi)容腿宰。正是因?yàn)槿绱耍慨?dāng)項(xiàng)目要開啟的時(shí)候缘厢,我都會(huì)使用該種思維來分析和設(shè)計(jì)程序吃度。多年下來發(fā)現(xiàn)它確實(shí)有著它的魅力,幫助我解決了很多設(shè)計(jì)中的問題贴硫。于是我總結(jié)了一下椿每,在下面章節(jié)中說說面向?qū)ο笫褂蒙系囊恍┬牡谩?/p>

給你的程序分“類”

面向?qū)ο蟮幕A(chǔ)就是“類”的設(shè)計(jì),其設(shè)計(jì)好壞直接影響到程序的結(jié)構(gòu)英遭。那么间护,如何才能設(shè)計(jì)出合理的類型呢?本人覺得應(yīng)該從實(shí)際需求出發(fā)挖诸,提取需求中各種實(shí)體對(duì)象汁尺,最終形成程序中使用的對(duì)象。某些同學(xué)喜歡為自己的程序埋點(diǎn)多律,添加很多為日后作擴(kuò)展的類型痴突,其實(shí)我是不建議過度設(shè)計(jì),我覺得可以在需求中提及的實(shí)體預(yù)留一些功能性的擴(kuò)展狼荞,但是不建議為需求中沒有的功能點(diǎn)設(shè)計(jì)類型辽装,因?yàn)椋阌肋h(yuǎn)都把握不準(zhǔn)產(chǎn)品日后的發(fā)展會(huì)是什么樣子的相味,最終形態(tài)是怎么樣拾积,也有可能你埋下的點(diǎn)還沒來得及實(shí)現(xiàn),程序就需要進(jìn)行重構(gòu)了等等的情況都會(huì)導(dǎo)致你的額外工作變成無用功。

假如公司要求你做一個(gè)附近的陌生人交友的App拓巧。從這個(gè)App的需求斯碌,可以提取出附近陌生人以及交友三個(gè)關(guān)鍵字玲销,附近描述的是一種相對(duì)的地理位置所以它應(yīng)該是一個(gè)類的屬性输拇,而陌生人也是相對(duì)于某個(gè)人來說的一種人與人的關(guān)系,所以這里會(huì)被分解為一個(gè)的實(shí)體贤斜,還有一個(gè)與其它實(shí)體的關(guān)系。而最后一個(gè)交友關(guān)鍵字其實(shí)隱含了一種建立關(guān)系的行為逛裤,這里可以是聊天瘩绒,也可以是其它的交友方式。我們?cè)龠M(jìn)一步分析带族,如果App里面提供了聊天功能锁荔,那么需求中還隱含了一個(gè)實(shí)體,那就是聊天的內(nèi)容蝙砌。所以阳堕,根據(jù)需求這些點(diǎn),我們可以設(shè)計(jì)出兩個(gè)類型

//用戶類型
class User
{
    //地理位置
    property location : Location;
    
    //用戶的好友
    property friends : Array<User>;

    //給某個(gè)用戶發(fā)送消息
    function sendMessage(user : User,  message : Message) : void;
}

//聊天內(nèi)容
class Message
{
}

這就由需求所驅(qū)動(dòng)產(chǎn)生的類型择克,以這些類型為核心類圍繞需求進(jìn)行補(bǔ)充和擴(kuò)展來不斷滿足后續(xù)的需求恬总。

讓類型也符合數(shù)據(jù)庫(kù)實(shí)體設(shè)計(jì)

關(guān)系數(shù)據(jù)庫(kù)設(shè)計(jì)中常會(huì)提及第三范式,其特點(diǎn)是去除表中直接依賴肚邢。這意思是說兩個(gè)實(shí)體對(duì)象不應(yīng)該被設(shè)計(jì)在同一個(gè)表中壹堰,如:評(píng)論表中有記錄是某個(gè)用戶發(fā)表的評(píng)論,可能會(huì)把用戶名稱等信息歸類到評(píng)論表中骡湖,那這樣是不符合第三范式要求的贱纠,正確的做法是把用戶信息放入用戶表,評(píng)論表中可以保留一個(gè)用戶id來標(biāo)識(shí)用戶表中的用戶記錄响蕴,從而取消在評(píng)論表中直接依賴用戶信息谆焊,導(dǎo)致用戶信息的冗余。

其實(shí)我個(gè)人覺得這種范式要求很好地劃分了實(shí)體之間的界線浦夷,對(duì)于類的設(shè)計(jì)也同樣適用辖试。譬如:你定義了一個(gè)人類,該類型有四肢屬性和說話的行為军拟。這樣很好理解剃执,因?yàn)楝F(xiàn)實(shí)中人就具備這些特性。但是在后續(xù)的開發(fā)過程中由于需求的變動(dòng)懈息,出現(xiàn)了人類因?yàn)橛酗w行道具可以進(jìn)行飛行肾档。而把飛行的行為直接賦予人類,這種圖省事的做法其實(shí)是存在很多弊端的:

  • 首先是不容易讀懂,因?yàn)槌WR(shí)性的認(rèn)為人是不會(huì)飛的怒见,人會(huì)飛的話那肯定是個(gè)鳥人俗慈。所以會(huì)讓人摸不著頭腦。

  • 再者就是這樣的定義往往會(huì)限制其它跟你協(xié)作開發(fā)的同事遣耍。因?yàn)榇蠖鄶?shù)情況下我們都會(huì)秉持著能盡量不動(dòng)舊代碼就不要去動(dòng)闺阱,以免動(dòng)出問題來。那么你這樣的設(shè)計(jì)就讓人不得不按照現(xiàn)有的思維去進(jìn)行擴(kuò)展舵变。直到哪一天是在沒有辦法了酣溃,再進(jìn)行徹底的重構(gòu)。

所以更優(yōu)的做法應(yīng)該是定義出一個(gè)道具類纪隙。至于道具實(shí)現(xiàn)什么功能赊豌,由其子類實(shí)現(xiàn):

// 道具基類
class Item
{
    //道具的行為
     function action(target : Person);
}

//飛行道具
class FlyingItem :Item
{
    function action(target : Person)
    {
        //飛行的實(shí)現(xiàn)代碼
    }
}

類似這樣的實(shí)現(xiàn)就可以分離人類和道具類型的耦合,而且也提高了道具類型的擴(kuò)展绵咱。所以碘饼,在設(shè)計(jì)類型時(shí)一定要給實(shí)體分清界線。

另外一個(gè)數(shù)據(jù)庫(kù)設(shè)計(jì)時(shí)使用較多的就是實(shí)體的關(guān)系描述悲伶。實(shí)體的關(guān)系不同艾恼,在設(shè)計(jì)表存儲(chǔ)數(shù)據(jù)時(shí)也有所不同。通常有三種實(shí)體關(guān)系:

  • 一對(duì)一麸锉,即兩個(gè)實(shí)體之間的關(guān)系是一一對(duì)應(yīng)的钠绍。如:一個(gè)中國(guó)公民跟他的身份證是唯一綁定的,知道身份證就能夠找到對(duì)應(yīng)的人淮椰,同樣對(duì)應(yīng)的人也能夠找到與其對(duì)應(yīng)的唯一的身份證五慈。類似這種關(guān)系,通常是建立兩張實(shí)體數(shù)據(jù)表主穗,然后關(guān)系可以同時(shí)放兩個(gè)實(shí)體表中泻拦。

  • 一對(duì)多,即兩種實(shí)體之間忽媒,第一種實(shí)體可以對(duì)應(yīng)多個(gè)第二種實(shí)體争拐,但是第二種實(shí)體只能對(duì)應(yīng)唯一的第一種實(shí)體。如用戶評(píng)論的例子晦雨,用戶可以發(fā)多條評(píng)論架曹,但是一條評(píng)論只能夠是特定的一個(gè)用戶發(fā)出來。對(duì)于這種關(guān)系闹瞧,通常也是建立兩張實(shí)體數(shù)據(jù)表绑雄,然后會(huì)在對(duì)應(yīng)多個(gè)實(shí)體的數(shù)據(jù)表中記錄關(guān)系,拿上面的例子來說奥邮,就是用戶表和評(píng)論表万牺,然后評(píng)論表會(huì)放入一個(gè)userId之類的標(biāo)識(shí)來記錄與用戶的對(duì)應(yīng)關(guān)系罗珍。

  • 多對(duì)多,即兩種實(shí)體之間脚粟,第一種實(shí)體可以對(duì)應(yīng)多個(gè)第二種實(shí)體覆旱,第二種實(shí)體也可以對(duì)應(yīng)多個(gè)第一種實(shí)體。例如作者和書籍的關(guān)系就是一種多對(duì)多的關(guān)系核无,一個(gè)作者可以寫多本書扣唱,同時(shí),一本書有可能有多個(gè)作者共同寫成团南。對(duì)于這種關(guān)系噪沙,則需要建立兩種實(shí)體數(shù)據(jù)表以及一張關(guān)系表來進(jìn)行描述。

說了這么多實(shí)體關(guān)系的東西已慢,其實(shí)最想說的一點(diǎn)就是曲聂,在進(jìn)行面向?qū)ο蠓治龊驮O(shè)計(jì)時(shí),關(guān)系的分析也是不可缺少的佑惠。但是需要怎么來評(píng)估關(guān)系的劃分和歸屬,我覺得按照數(shù)據(jù)庫(kù)的關(guān)系設(shè)計(jì)標(biāo)準(zhǔn)來進(jìn)行也是一種不錯(cuò)的方法齐疙。

  • 一對(duì)一膜楷,在該種關(guān)系下,其實(shí)關(guān)系的描述可以同時(shí)放在兩個(gè)類型上贞奋,如上面所說的中國(guó)公民與身份證的例子赌厅,用類可以描述為:
class Chinese
{
    //姓名
    property name:String;
    
    //對(duì)應(yīng)的身份證
    property idCard:IDCard;
}

class IDCard
{
    //身份證號(hào)
    property id:String;
    
    //對(duì)應(yīng)的人
    property person:Chinese;
}
  • 一對(duì)多,該種關(guān)系下轿塔,稍微與數(shù)據(jù)庫(kù)表設(shè)計(jì)有點(diǎn)不同特愿,由于數(shù)據(jù)表可以通過查詢的方式來找出實(shí)體對(duì)應(yīng)的多個(gè)另一種實(shí)體,這已經(jīng)超出了類設(shè)計(jì)階段的范疇勾缭。因此揍障,對(duì)應(yīng)多個(gè)類實(shí)例的類型需要定義一個(gè)集合的屬性來保留對(duì)應(yīng)的多個(gè)類實(shí)例。這樣在閱讀代碼時(shí)也能夠很好理解俩由,拿用戶評(píng)論的例子來說:
class User
{
    property comments:Set<Comment>;
}

class Comment
{
   property user:User;
}

類似這樣能夠很好的描述用戶進(jìn)行過多少的評(píng)論毒嫡,然后哪條評(píng)論是哪個(gè)用戶評(píng)論的。

  • 多對(duì)多幻梯,這是一種很復(fù)雜的關(guān)系兜畸,主要是很多情況下,我們都會(huì)忽略這樣的一種關(guān)系碘梢,把它直接給變成了一對(duì)多的關(guān)系設(shè)計(jì)咬摇。其實(shí)對(duì)于種情況我們都可以將其關(guān)系的處理交由另外一個(gè)類型進(jìn)行處理,與數(shù)據(jù)庫(kù)表設(shè)計(jì)一樣煞躬,兩個(gè)實(shí)體類型肛鹏,一個(gè)關(guān)系類型逸邦。拿剛才作者跟書籍的關(guān)系為例,可以設(shè)計(jì)成下面的樣子:
//作者書籍關(guān)系管理類型
class AuthorBookRelationshipManager
{
   //設(shè)置書籍的作者信息
   static function setBookAuthor(book : Book, authors : Array<Author>) : void;

    //獲取指定書籍的作者
    static function getAuthors(book : Book) : Array<Author>;

    //獲取指定作者的書籍
    static function getBooks(author : Author) : Array<Book>;
}

//作者類型
class Author
{
    //作者名稱
    property name : String;

    //獲取作者出版過的書籍
    function getBooks() : Array<Book>
    {
        return AuthorBookRelationshipManager.getBooks(this);
    }
}

//書籍類型
class Book
{
    //書籍名稱
    property name : String;
    
    //獲取書籍的作者信息
    function getAuthors():Array<Author>
    {
        return AuthorBookRelationshipManager.getAuthors(this);
    }
}

上面的代碼可以看出龄坪,使用了一個(gè)AuthorBookRelationshipManager類型來管理書籍和作者的關(guān)系昭雌。然后實(shí)體類型不再保存之間的關(guān)系,要獲取相關(guān)的實(shí)體需要通過AuthorBookRelationshipManager類型來獲取健田。

上面所說的實(shí)體劃分和關(guān)系劃分在面向?qū)ο笾杏兄浅V匾囊饬x烛卧。平時(shí)要多加練習(xí)才能夠在面臨實(shí)際項(xiàng)目開發(fā)時(shí)做出合理的分類,讓自己開發(fā)的架構(gòu)更加靈活更加強(qiáng)大。

以上對(duì)于類型的設(shè)計(jì)基本上是講完了寺鸥,是時(shí)候要說說繼承方面的事情了陕见,這是面向?qū)ο蟮囊粋€(gè)很強(qiáng)大的特性。它可以改善代碼結(jié)構(gòu)的問題局雄,節(jié)省代碼的書寫工作量。下面將會(huì)圍繞它來聊聊我的看法存炮。

萬物的始祖

其實(shí)不管是寫C++炬搭、C#還是寫Java等等這些高級(jí)語言,我們都會(huì)發(fā)現(xiàn)只要是創(chuàng)建的類它們都會(huì)直接或者間接地繼承自O(shè)bject這個(gè)類穆桂。而這個(gè)Object類就是我這要說的萬物的始祖宫盔,其被所有的事物所繼承是一個(gè)根類型。Object這個(gè)名字也起得相當(dāng)好享完,泛指了所有的物體灼芭,給予了一種無形態(tài)的抽象的定義。意味著我們作為程序中的造物主般又,需要將這種無形態(tài)的物體彼绷,變化成各種具體形態(tài)的事物,這就需要繼承茴迁。

那么寄悯,Object中所做的功能其實(shí)并不多,因?yàn)樗簧婕熬唧w的功能笋熬,因此它很多時(shí)候在實(shí)現(xiàn)上面僅僅能區(qū)分是否是同一個(gè)對(duì)象isEqual热某,又或者是告訴我們它的描述toString。但是這樣已經(jīng)是有很大的引導(dǎo)意義胳螟,因?yàn)橹灰^承了Object類型昔馋,那么你的類型將會(huì)得到這樣功能,闡述了繼承功能的強(qiáng)大糖耸;同時(shí)秘遏,你還可以把你的子類型對(duì)象賦予給一個(gè)Object的實(shí)例,因?yàn)镺bject是根類嘉竟,它可以保留任意的子類類型對(duì)象邦危,這是面向?qū)ο蠖鄳B(tài)的基本體現(xiàn)洋侨。

有了Object這樣的一個(gè)例子,更加表明了我們?cè)陂_發(fā)項(xiàng)目過程中也應(yīng)該為項(xiàng)目的代碼設(shè)計(jì)基類倦蚪。而這里的基類要比Object的功能稍微具體一點(diǎn)希坚。因?yàn)樗婕暗骄唧w要實(shí)現(xiàn)的功能需求,而且還應(yīng)該不止是一個(gè)基類陵且。下面來說一下我是怎么樣設(shè)計(jì)基類的裁僧。

和基類來個(gè)約定

要怎么設(shè)計(jì)基類,其實(shí)還是要根據(jù)實(shí)際的項(xiàng)目需求而定慕购。假設(shè)你所開發(fā)的項(xiàng)目包含很多的后臺(tái)服務(wù)聊疲,那么就應(yīng)該定義一個(gè)叫BaseService的基類,然后通過這個(gè)基類來分化成多種服務(wù)類型沪悲。如果你的項(xiàng)目涉及到多種UI的處理获洲,那么你就應(yīng)該考慮可能需要一個(gè)基礎(chǔ)的UI管理類型(通常UI組件有自己的基類,這里需要的是對(duì)UI進(jìn)行管理和維護(hù)的基礎(chǔ)類型)殿如,如:UIController贡珊。然后根據(jù)這個(gè)基類分化出各種的UI展現(xiàn)。

基本上是根據(jù)如果程序存在多種特性相近或相似的功能模塊涉馁,那么就應(yīng)該為這些模塊建立基類飞崖,以便日后更好的進(jìn)行擴(kuò)展。這里不建議要給未來有可能會(huì)有多種近似功能的模塊定義基類谨胞,還是老話,你的假設(shè)不一定成立蒜鸡。而且等到出現(xiàn)這樣的需求在進(jìn)行定義也不遲胯努,畢竟要改造的也只是一個(gè)類型而已。

上面我們知道如何去抽象出基類逢防,那么基類應(yīng)該要如何封裝屬性和方法叶沛,其實(shí)完全可以視其子類而定,因?yàn)檫@樣是最貼近需求的忘朝。如前面所說的多種后臺(tái)服務(wù)灰署,假設(shè)有如下服務(wù)類型:

class ServiceA
{
    //服務(wù)名稱
    property name:String;
    
   //調(diào)用服務(wù)
    function exec(config:Dicationary):void
    {
          //執(zhí)行服務(wù)
    }
}

class ServiceB
{
    //服務(wù)名稱
    property name:String;
    
    //調(diào)用服務(wù)
     function call():void
     {
          //執(zhí)行服務(wù)
     }
}

上面所描述的服務(wù)從代碼結(jié)構(gòu)上面其實(shí)不大相同,特別是在執(zhí)行服務(wù)的行為上接收參數(shù)也不一樣局嘁。如果要從它們身上抽象出基類溉箕,確實(shí)會(huì)讓人有所困惑。但是悦昵,我們既然要抽象基類肴茄,那么就肯定會(huì)改造子類。我自己總結(jié)一些抽象的規(guī)則:

  • 子類中相同的屬性和方法但指,要封裝到基類中寡痰。
  • 對(duì)于大多數(shù)子類存在的屬性和方法(如5個(gè)子類中有3個(gè)以上類型存在相同的屬性和方法)抗楔,可以考慮封裝到基類中,沒用到類型可以對(duì)基類的屬性和方法進(jìn)行忽略拦坠。
  • 對(duì)于意義相近的屬性连躏,可以考慮將屬性合并或替換(如:子類中分別用id或者name屬性來表示對(duì)象的唯一,那么基類可以考慮只取其中一項(xiàng)屬性或者創(chuàng)建一個(gè)集合兩者的屬性定義)贞滨。
  • 對(duì)于子類相同行為的方法入热,如果聲明的方法參數(shù)的數(shù)量或類型不同時(shí),可以考慮基類的方法集合子類該方法中的所有參數(shù)(即取方法參數(shù)的并集)或者考慮定義共有參數(shù)疲迂,特殊參數(shù)則由子類轉(zhuǎn)換為屬性來實(shí)現(xiàn)(一般可以持續(xù)持有的參數(shù)可以這樣設(shè)計(jì)才顿,如系統(tǒng)的配置)。

基于上面所說的尤蒿,我們可以把ServiceAServiceB郑气,通過抽象基類改成下面的樣子:

class BaseService
{
    //服務(wù)名稱
    property name:String;

    //調(diào)用服務(wù)
    function exec():void;
}

class ServiceA extends BaseService
{
    //這里將參數(shù)設(shè)定為屬性
    property config:Dictionary;

    function exec():void
    {
          //執(zhí)行服務(wù)
    }
}

class ServiceB extends BaseService
{
    function exec():void
    {
         //執(zhí)行服務(wù)
     }
}

類似這樣腰池,我們就可以把基類給抽象出來了尾组。

讓類型進(jìn)化

在開發(fā)和維護(hù)代碼的過程里面,難免會(huì)碰到由于產(chǎn)品的迭代示弓,導(dǎo)致需求發(fā)生重大的變更讳侨。那么可能會(huì)出現(xiàn)某些功能的廢棄或者功能的合并或演進(jìn)。這時(shí)候奏属,之前定義的類型就要面臨著重構(gòu)或者調(diào)整的命運(yùn)跨跨。

遇到這樣的問題我們先別急著把之前的東西全盤否定,然后徹底重寫囱皿。而是先考慮之前的定義中是否還存在可用的東西勇婴。要把可以重用的模塊給提取出來,那么嘱腥,模塊的取舍就是我們需要評(píng)估的事情耕渴。

如果新的需求中已經(jīng)廢棄的功能,那么模塊所涉及的類型都可以進(jìn)行廢棄齿兔。對(duì)于這些模塊的處理橱脸,我個(gè)人比較喜歡對(duì)相關(guān)的類型進(jìn)行直接刪除,然后進(jìn)行編譯分苇,報(bào)錯(cuò)后直接修改引用到該類型的代碼添诉,直到編譯成功為止。對(duì)于缺失該類型后需要改造的方法组砚,我會(huì)暫時(shí)不進(jìn)行改造吻商,而是打上標(biāo)記(如TODO或者warning宏),等待正式開發(fā)新功能時(shí)再尋找會(huì)這些標(biāo)記一一進(jìn)行解決糟红。

如果新需求中包含該類功能艾帐,但是又融合了一些新的元素乌叶,那么,我們的類型還不能直接拿來使用柒爸。要評(píng)估新的元素是否作為類型的一部分准浴,還是作一種新的類型。例如:一款聊天應(yīng)用捎稚,剛開始的時(shí)候只有私聊(一對(duì)一聊天)乐横,那么,發(fā)送消息就在User類型中:

//用戶類型
class User
{
    //給某個(gè)用戶發(fā)送消息
    function sendMessage(user : User,  message : Message) : void;
}

到了第二個(gè)版本的時(shí)候今野,可能支持用戶給好友群發(fā)消息葡公。那么,明顯上面的代碼不能滿足需求条霜,這時(shí)候需要對(duì)類型進(jìn)行改造:

//用戶類型
class User
{
    //給某個(gè)用戶發(fā)送消息
    function sendMessage(user : User,  message : Message) : void;

    //給多個(gè)用戶發(fā)送消息
    function sendMessage(users : Arrray<User>,  message : Message) : void
    {
        for (User user in users)
        {
            this.sendMessage(user, message);
        }
    }
}

增加了一個(gè)sendMessage多態(tài)版本的方法用于群發(fā)消息催什。這樣既能保證方法的出口統(tǒng)一,又能保證之前的方法不被修改宰睡,就可以輕松地解決群發(fā)問題蒲凶。

那么,到了第三個(gè)版本的時(shí)候出現(xiàn)了聊天室的概念拆内,這時(shí)候需求中多了一個(gè)聊天室的關(guān)鍵字旋圆,運(yùn)用之前提到的方法,這里應(yīng)該需要新增一個(gè)類型麸恍,不能直接在User類型中進(jìn)行擴(kuò)展灵巧。那么,可以設(shè)計(jì)為:

//聊天室
class ChatRoom
{
    //聊天室名稱
    property name:String;

    //聊天室用戶
    property users:Array<User>;
    
    //發(fā)送消息
    function sendMessage(user:User, message:Message):void;
}

這里增加了一個(gè)ChatRoom的類型抹沪,主要是用來記錄那些人在哪個(gè)聊天室中孩等。該類型有一個(gè)sendMessage的方法,用于表示哪個(gè)用戶要在聊天室中發(fā)言采够,發(fā)言的內(nèi)容是什么。

由上面的例子可以看出來冰垄,產(chǎn)品迭代有時(shí)候需要讓類型進(jìn)行蹬癌,有時(shí)候也需要誕生新的類型。要做那種選擇則需要根據(jù)產(chǎn)品需求來決定虹茶。

只要這種多態(tài)

多態(tài)在我的理解中就是多種狀態(tài)逝薪。就好比我們用手拿東西的時(shí)候,如果拿的是球蝴罪,那么我們可能是想要打球董济,如果拿的是蘋果,那么我們可能要把它吃掉要门。根據(jù)不同東西我們可能會(huì)作出不同的反映虏肾。在面向?qū)ο笾卸鄳B(tài)就是用于解決這類的問題廓啊。我們來假設(shè)一下沒有多態(tài)的時(shí)候,我們的代碼看起來會(huì)是多挫:

function doSomething(obj:Object):void
{
    if (obj instanceof ObjectA)
    {
        //do something by ObjectA
    }
    else if (obj instanceof ObjectB)
    {
        //do something by ObjectB
    }
}

要判斷的類型越多封豪,if的語句就越長(zhǎng)谴轮。那么有了多態(tài)后,我們可以很優(yōu)雅地設(shè)計(jì):

function doSomething(obj:ObjectA):void
{
    //do something by ObjectA
}

function doSomething(obj:ObjectB):void
{
    //do something by ObjectB
}

多態(tài)可以保證代碼設(shè)計(jì)的出口名字統(tǒng)一吹埠,不需要外部調(diào)用的人要根據(jù)不同的類型調(diào)用不同名字的方法第步,對(duì)于外部調(diào)用只需要傳入的類型不同即可決定要調(diào)用哪個(gè)方法。

如果不是解決上面所說的問題缘琅,我不建議使用多態(tài)粘都。因?yàn)槎鄳B(tài)會(huì)使到類型變得復(fù)雜,如果這個(gè)使用多態(tài)的類型被繼承刷袍,然后繼承的子類進(jìn)行了多態(tài)處理翩隧,那么會(huì)影響到程序的質(zhì)量,并且一旦出現(xiàn)問題做个,排查的難度會(huì)有所增加鸽心。

后話

以上說的都是我個(gè)人在這些年的開發(fā)中所理解的東西,面向?qū)ο筮@東西已經(jīng)存在我腦海里面許多個(gè)日夜了居暖,總想著寫些什么顽频,今天總算把它給完成了。后續(xù)我會(huì)繼續(xù)寫下其他的一些關(guān)于程序思維的文章太闺,希望大家支持糯景。

寫這篇文章的時(shí)候沒有參考其他資料,可能存在錯(cuò)漏的地方省骂。如果你是一位好心的猿/媛蟀淮,麻煩給我指正一下。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者

  • 序言:七十年代末钞澳,一起剝皮案震驚了整個(gè)濱河市怠惶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌轧粟,老刑警劉巖策治,帶你破解...
    沈念sama閱讀 219,366評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異兰吟,居然都是意外死亡通惫,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門混蔼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來履腋,“玉大人,你說我怎么就攤上這事∽窈” “怎么了悔政?”我有些...
    開封第一講書人閱讀 165,689評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)奄侠。 經(jīng)常有香客問我卓箫,道長(zhǎng),這世上最難降的妖魔是什么垄潮? 我笑而不...
    開封第一講書人閱讀 58,925評(píng)論 1 295
  • 正文 為了忘掉前任烹卒,我火速辦了婚禮,結(jié)果婚禮上弯洗,老公的妹妹穿的比我還像新娘旅急。我一直安慰自己,他們只是感情好牡整,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評(píng)論 6 392
  • 文/花漫 我一把揭開白布藐吮。 她就那樣靜靜地躺著,像睡著了一般逃贝。 火紅的嫁衣襯著肌膚如雪谣辞。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,727評(píng)論 1 305
  • 那天沐扳,我揣著相機(jī)與錄音泥从,去河邊找鬼。 笑死沪摄,一個(gè)胖子當(dāng)著我的面吹牛躯嫉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播杨拐,決...
    沈念sama閱讀 40,447評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼祈餐,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了哄陶?” 一聲冷哼從身側(cè)響起帆阳,我...
    開封第一講書人閱讀 39,349評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎屋吨,沒想到半個(gè)月后舱痘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,820評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡离赫,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了塌碌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片渊胸。...
    茶點(diǎn)故事閱讀 40,127評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖台妆,靈堂內(nèi)的尸體忽然破棺而出翎猛,到底是詐尸還是另有隱情胖翰,我是刑警寧澤,帶...
    沈念sama閱讀 35,812評(píng)論 5 346
  • 正文 年R本政府宣布切厘,位于F島的核電站萨咳,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏疫稿。R本人自食惡果不足惜培他,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望遗座。 院中可真熱鬧舀凛,春花似錦、人聲如沸途蒋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)号坡。三九已至懊烤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間宽堆,已是汗流浹背腌紧。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留日麸,地道東北人寄啼。 一個(gè)月前我還...
    沈念sama閱讀 48,388評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像代箭,于是被迫代替她去往敵國(guó)和親墩划。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容