成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

他們?cè)趯W(xué)校里不會(huì)教你的編程原則

開(kāi)發(fā) 前端
本文總結(jié)了軟件編程中的黃金原則,KISS?原則,DRY?原則,SOLID原則。這些原則不僅僅適用于編程,也可以指導(dǎo)我們?cè)诩軜?gòu)設(shè)計(jì)上。雖然其中有些原則很抽象,但是大家多多實(shí)踐和思考,會(huì)體會(huì)到這些原則的精妙。

前言

在大學(xué)的時(shí)候,學(xué)校一般只會(huì)教你你寫(xiě)編程語(yǔ)言,比如C、C++、JAVA等編程語(yǔ)言。但是當(dāng)你離開(kāi)大學(xué)進(jìn)入這個(gè)行業(yè)開(kāi)始工作時(shí),才知道編程不只是知道編程語(yǔ)言、語(yǔ)法等,要想寫(xiě)好代碼,必須還要了解一些編程原則才行。本文主要討論KISS、DRY和SOLID這些常見(jiàn)的編程原則,而且你會(huì)發(fā)現(xiàn)隨著工作時(shí)間越久,越能感受這些編程原則的精妙之處,歷久彌香。

KISS原則

Keep It Simple, Stupid!

你是不是有過(guò)接手同事的代碼感到十分頭疼的經(jīng)歷,明明可以有更加簡(jiǎn)單、明白的寫(xiě)法,非要繞來(lái)繞去,看不明白?

其實(shí),我們?cè)趯?xiě)代碼的時(shí)候應(yīng)該要遵守KISS原則,核心思想就是盡量保持簡(jiǎn)單。代碼的可讀性和可維護(hù)性是衡量代碼質(zhì)量非常重要的兩個(gè)標(biāo)準(zhǔn)。而 KISS 原則就是保持代碼可讀和可維護(hù)的重要手段。代碼足夠簡(jiǎn)單,也就意味著很容易讀懂,bug 比較難隱藏。即便出現(xiàn) bug,修復(fù)起來(lái)也比較簡(jiǎn)單。

我們寫(xiě)代碼的的時(shí)候要站在別人的角度出發(fā),就像馬丁·福勒說(shuō)的,我們寫(xiě)的代碼不是給機(jī)器看的,而是給人看的。

“任何傻瓜都可以編寫(xiě)計(jì)算機(jī)可以理解的代碼。優(yōu)秀的程序員編寫(xiě)出人類(lèi)可以理解的代碼。” — 馬丁·福勒

那么如何才能寫(xiě)出滿足KISS原則的代碼呢?

如何寫(xiě)出KISS原則的代碼?

我們直接上例子,下面的校驗(yàn)IP是否合法的3種實(shí)現(xiàn)方式,大家覺(jué)得哪個(gè)最KISS?

寫(xiě)法一

圖片

寫(xiě)法二

圖片

寫(xiě)法三

圖片

  • 寫(xiě)法一代碼量最少,正則表達(dá)式本身是比較復(fù)雜的,寫(xiě)出完全沒(méi)有 bug 的正則表達(dá)本身就比較有挑戰(zhàn);另一方面,并不是每個(gè)程序員都精通正則表達(dá)式。對(duì)于不怎么懂正則表達(dá)式的同事來(lái)說(shuō),看懂并且維護(hù)這段正則表達(dá)式是比較困難的。這種實(shí)現(xiàn)方式會(huì)導(dǎo)致代碼的可讀性和可維護(hù)性變差,所以,從 KISS 原則的設(shè)計(jì)初衷上來(lái)講,這種實(shí)現(xiàn)方式并不符合 KISS 原則。
  • 寫(xiě)法二使用了 StringUtils 類(lèi)、Integer 類(lèi)提供的一些現(xiàn)成的工具函數(shù),來(lái)處理 IP地址字符串,邏輯清晰,可讀性好。
  • 寫(xiě)法三不使用任何工具函數(shù),而是通過(guò)逐一處理 IP 地址中的字符,來(lái)判斷是否合法,容易出bug,不好理解。

所以說(shuō),符合KISS原則的代碼并不是代碼越少越好,還要考慮代碼是否邏輯清晰、是否容易理解、是否夠穩(wěn)定。

總結(jié)以下如何寫(xiě)出KISS原則的代碼:

  1. 不要使用同事可能不懂的技術(shù)來(lái)實(shí)現(xiàn)代碼。比如前面例子中的正則表達(dá)式,還有一些編程語(yǔ)言中過(guò)于高級(jí)的語(yǔ)法等。
  2. 不要重復(fù)造輪子,要善于使用已經(jīng)有的工具類(lèi)庫(kù)。經(jīng)驗(yàn)證明,自己去實(shí)現(xiàn)這些類(lèi)庫(kù),出bug 的概率會(huì)更高,維護(hù)的成本也比較高。
  3. 不要過(guò)度優(yōu)化。不要過(guò)度使用一些奇技淫巧(比如,位運(yùn)算代替算術(shù)運(yùn)算、復(fù)雜的條件語(yǔ)句代替if-else、使用一些過(guò)于底層的函數(shù)等)來(lái)優(yōu)化代碼,犧牲代碼的可讀性。
  4. 主觀站在別人的角度上編寫(xiě)代碼。你在編寫(xiě)代碼的時(shí)候就要思考我這個(gè)同事看這段代碼是不是很快就能夠明白理解。

DRY原則

Don't Repeat Yourself

你是不是有過(guò)這樣的經(jīng)歷,項(xiàng)目中很多重復(fù)邏輯的代碼,然后修改一個(gè)地方,另外一個(gè)地方忘記修改,導(dǎo)致測(cè)試給你提了很多bug?

DRY原則,英文全稱(chēng)Don’t Repeat Yourself,直譯過(guò)來(lái)就是不要重復(fù)你自己。這里的重復(fù)不僅僅是代碼一模一樣,還包括實(shí)現(xiàn)邏輯重復(fù)、功能語(yǔ)義重復(fù)、代碼執(zhí)行重復(fù)等。我們不要偷懶,有責(zé)任把這些存在重復(fù)的地方識(shí)別出來(lái),然后優(yōu)化它們。

如何寫(xiě)出DRY原則的代碼呢?

我們直接上例子,代碼重復(fù)的我就不講了,很好理解,關(guān)于實(shí)現(xiàn)邏輯或者功能語(yǔ)義重復(fù)的我覺(jué)個(gè)例子。

還是上面校驗(yàn)IP的例子,團(tuán)隊(duì)中兩個(gè)同事由于不知道就有了兩種寫(xiě)法。

  • 同事A寫(xiě)法

圖片

  • 同事B寫(xiě)法

圖片

盡管兩段代碼的實(shí)現(xiàn)邏輯不重復(fù),但語(yǔ)義重復(fù),也就是功能重復(fù),我們認(rèn)為它違反了 DRY 原則。我們應(yīng)該在項(xiàng)目中,統(tǒng)一一種實(shí)現(xiàn)思路,所有用到判斷 IP 地址是否合法的地方,都統(tǒng)一調(diào)用同一個(gè)函數(shù)。不然哪天校驗(yàn)規(guī)則變了,很容易只改了其中一個(gè),另外一個(gè)漏改,就會(huì)出現(xiàn)莫名其妙的bug。

其他的比如邏輯重復(fù)的意思是雖然功能是不一致的,但是里面的邏輯都是一模一樣的。舉個(gè)例子,比如校驗(yàn)用戶(hù)名和校驗(yàn)密碼,雖然功能不一致,但是校驗(yàn)邏輯都是相似,判空、字符長(zhǎng)度等等,這種情況我們就需要把相似的邏輯抽取到一個(gè)方法中,不然也是不符合DRY原則。

那么我們平時(shí)寫(xiě)代碼注意些什么才是符合DRY原則呢?

  • 使用現(xiàn)成的輪子,不輕易造輪子

其實(shí)最關(guān)鍵的就是寫(xiě)代碼帶腦子,用到一個(gè)方法先看看有沒(méi)有現(xiàn)成的,不要看看不看,就動(dòng)手在那里造輪子。

  • 減少代碼耦合

對(duì)于高度耦合的代碼,當(dāng)我們希望復(fù)用其中的一個(gè)功能,想把這個(gè)功能的代碼抽取出來(lái)成為一個(gè)獨(dú)立的模塊、類(lèi)或者函數(shù)的時(shí)候,往往會(huì)發(fā)現(xiàn)牽一發(fā)而動(dòng)全身。移動(dòng)一點(diǎn)代碼,就要牽連到很多其他相關(guān)的代碼。所以,高度耦合的代碼會(huì)影響到代碼的復(fù)用性,我們要盡量減少代碼耦合。

  • 滿足單一職責(zé)原則

我們前面講過(guò),如果職責(zé)不夠單一,模塊、類(lèi)設(shè)計(jì)得大而全,那依賴(lài)它的代碼或者它依賴(lài)的代碼就會(huì)比較多,進(jìn)而增加了代碼的耦合。根據(jù)上一點(diǎn),也就會(huì)影響到代碼的復(fù)用性。相反,越細(xì)粒度的代碼,代碼的通用性會(huì)越好,越容易被復(fù)用。

  • 模塊化

這里的“模塊”,不單單指一組類(lèi)構(gòu)成的模塊,還可以理解為單個(gè)類(lèi)、函數(shù)。我們要善于將功能獨(dú)立的代碼,封裝成模塊。獨(dú)立的模塊就像一塊一塊的積木,更加容易復(fù)用,可以直接拿來(lái)搭建更加復(fù)雜的系統(tǒng)。

  • 業(yè)務(wù)與非業(yè)務(wù)邏輯分離

越是跟業(yè)務(wù)無(wú)關(guān)的代碼越是容易復(fù)用,越是針對(duì)特定業(yè)務(wù)的代碼越難復(fù)用。所以,為了復(fù)用跟業(yè)務(wù)無(wú)關(guān)的代碼,我們將業(yè)務(wù)和非業(yè)務(wù)邏輯代碼分離,抽取成一些通用的框架、類(lèi)庫(kù)、組件等。

  • 通用代碼下沉

從分層的角度來(lái)看,越底層的代碼越通用、會(huì)被越多的模塊調(diào)用,越應(yīng)該設(shè)計(jì)得足夠可復(fù)用。一般情況下,在代碼分層之后,為了避免交叉調(diào)用導(dǎo)致調(diào)用關(guān)系混亂,我們只允許上層代碼調(diào)用下層代碼及同層代碼之間的調(diào)用,杜絕下層代碼調(diào)用上層代碼。所以,通用的代碼我們盡量下沉到更下層。

  • 繼承、多態(tài)、抽象、封裝

在講面向?qū)ο筇匦缘臅r(shí)候,我們講到,利用繼承,可以將公共的代碼抽取到父類(lèi),子類(lèi)復(fù)用父類(lèi)的屬性和方法。利用多態(tài),我們可以動(dòng)態(tài)地替換一段代碼的部分邏輯,讓這段代碼可復(fù)用。除此之外,抽象和封裝,從更加廣義的層面、而非狹義的面向?qū)ο筇匦缘膶用鎭?lái)理解的話,越抽象、越不依賴(lài)具體的實(shí)現(xiàn),越容易復(fù)用。代碼封裝成模塊,隱藏可變的細(xì)節(jié)、暴露不變的接口,就越容易復(fù)用。

  • 應(yīng)用模板等設(shè)計(jì)模式

一些設(shè)計(jì)模式,也能提高代碼的復(fù)用性。比如,模板模式利用了多態(tài)來(lái)實(shí)現(xiàn),可以靈活地替換其中的部分代碼,整個(gè)流程模板代碼可復(fù)用。

SOLID原則

SOLID原則不是一個(gè)單一的原則,而是對(duì)軟件開(kāi)發(fā)至關(guān)重要的 5 條原則,遵循這些原則有助于我們寫(xiě)出高內(nèi)聚、低耦合、可擴(kuò)展、可維護(hù)性好的代碼。

S—單一職責(zé)原則

一個(gè)類(lèi)應(yīng)該有一個(gè),而且只有一個(gè)改變它的理由。

單一職責(zé)原則在我看來(lái)是最容易理解也是最重要的一個(gè)原則。它的核心思想就是一個(gè)模塊、類(lèi)或者方法只做一件事,只有一個(gè)職責(zé),千萬(wàn)不要越俎代庖。它可以帶來(lái)下面的好處:

  • 可以讓代碼耦合度更低
  • 使代碼更容易理解和維護(hù)
  • 使代碼更易于測(cè)試和維護(hù),使軟件更易于實(shí)施,并有助于避免未來(lái)更改的意外副作用

舉個(gè)例子,我們有兩個(gè)類(lèi)Person和Account。 兩者都負(fù)有存儲(chǔ)其特定信息的單一責(zé)任。 如果要更改Person的狀態(tài),則無(wú)需修改類(lèi)Account,反之亦然, 不要把賬戶(hù)的行為比如修改賬戶(hù)名changeAcctName寫(xiě)在Person類(lèi)中。

public class Person {
     private Long personId;
     private String firstName;
     private String lastName;
     private String age;
     private List<Account> accounts;

        // 錯(cuò)誤做法
        public void changeAcctName(Account account, String acctName) {
            acccount.setAccountName(acctName);
            // 更新到數(shù)據(jù)庫(kù)
        }
    }

    public class Account {
     private Long guid;
     private String accountNumber;
     private String accountName;
     private String status;
     private String type;

    }

所以大家在編寫(xiě)代碼的時(shí)候,一定要停頓思考下這個(gè)段代碼真的寫(xiě)在這里嗎?另外很關(guān)鍵的一點(diǎn)是如果發(fā)現(xiàn)一個(gè)類(lèi)或者一個(gè)方法十分龐大,那么很有可能已經(jīng)違背單一職責(zé)原則了,后續(xù)維護(hù)可想而知十分痛苦。

O—開(kāi)閉原則

軟件實(shí)體(類(lèi)、模塊、函數(shù)等)應(yīng)該對(duì)擴(kuò)展開(kāi)放,對(duì)修改關(guān)閉。

對(duì)擴(kuò)展開(kāi)放,對(duì)修改關(guān)閉,什么意思?很簡(jiǎn)單,其實(shí)就是我們要盡量通過(guò)新增類(lèi)實(shí)現(xiàn)功能,而不是修改原有的類(lèi)或者邏輯。因?yàn)樾薷囊延写a很有可能對(duì)已有功能引入bug。

讓我們通過(guò)一個(gè)例子來(lái)理解這個(gè)原則,比如一個(gè)通知服務(wù)。

public class NotificationService {
     public void sendOTP(String medium) {
            if (medium.equals("email")) {
                //email 發(fā)送
            } else if (medium.equals("mobile")) {
                // 手機(jī)發(fā)送
         } 
    }

現(xiàn)在需要新增微信的方式通知,你要怎么做呢? 是在加一個(gè)if else嗎? 這樣就不符合開(kāi)閉原則了,我們看下開(kāi)閉原則該怎么寫(xiě)。

  • 定義一個(gè)通知服務(wù)接口
public interface NotificationService {
     public void sendOTP();
    }
  • E-mail方式通知類(lèi)EmailNotification
public class EmailNotification implements NotificationService{
     public void sendOTP(){
      // write Logic using JavaEmail api
     }
    }
  • 手機(jī)方式通知類(lèi)MobileNotification
public class MobileNotification implements NotificationService{
        public void sendOTP(){
      // write Logic using Twilio SMS API
     }
    }
  • 同樣可以添加微信通知服務(wù)的實(shí)現(xiàn)WechatNotification
public class WechatNotification implements NotificationService{
     public void sendOTP(String medium){
      // write Logic using wechat API
     }
    }

這樣的方式就是遵循開(kāi)閉原則的,你不用修改核心的業(yè)務(wù)邏輯,這樣可能帶來(lái)意向不到的后果,而是擴(kuò)展實(shí)現(xiàn)方式,由調(diào)用方根據(jù)他們的實(shí)際情況調(diào)用。

是不是想到了設(shè)計(jì)模式中的策略模式,其實(shí)設(shè)計(jì)模式就是指導(dǎo)我們寫(xiě)出高內(nèi)聚、低耦合的代碼。

L—里氏替換原則

派生類(lèi)或子類(lèi)必須可替代其基類(lèi)或父類(lèi)

這個(gè)原則稍微有點(diǎn)難以理解,它的核心思想是每個(gè)子類(lèi)或派生類(lèi)都應(yīng)該可以替代/等效于它們的基類(lèi)或父類(lèi)。這樣有一個(gè)好處,就是無(wú)論子類(lèi)是什么類(lèi)型,客戶(hù)端通過(guò)父類(lèi)調(diào)用都不會(huì)產(chǎn)生意外的后果。

理解不了?那我我們通過(guò)一個(gè)例子來(lái)理解一下。

讓我們考慮一下我有一個(gè)名為 SocialMedia 的抽象類(lèi),它支持所有社交媒體活動(dòng)供用戶(hù)娛樂(lè),如下所示:

package com.alvin.solid.lsp;

    public abstract class SocialMedia {
        
        public abstract  void chatWithFriend();
        
        public abstract void publishPost(Object post);
        
        public abstract  void sendPhotosAndVideos();
        
        public abstract  void groupVideoCall(String... users);
    }

社交媒體可以有多個(gè)實(shí)現(xiàn)或可以有多個(gè)子類(lèi),如 Facebook、Wechat、Weibo 和 Twitter 等。

現(xiàn)在讓我們假設(shè) Facebook 想要使用這個(gè)特性或功能。

package com.alvin.solid.lsp;

    public class Wechat extends SocialMedia {

        public void chatWithFriend() {
            //logic  
        }

        public void publishPost(Object post) {
            //logic  
        }

        public void sendPhotosAndVideos() {
            //logic  
        }

        public void groupVideoCall(String... users) {
            //logic  
        }
    }

我們都知道Facebook都提供了所有上述的功能,所以這里我們可以認(rèn)為Facebook是SocialMedia類(lèi)的完全替代品,兩者都可以無(wú)中斷地替代。

現(xiàn)在讓我們討論 Weibo 類(lèi)

package com.alvin.solid.lsp;

    public class Weibo extends SocialMedia {
        public void chatWithFriend() {
            //logic
        }

        public void publishPost(Object post) {
          //logic
        }

        public void sendPhotosAndVideos() {
          //logic
        }

        public void groupVideoCall(String... users) {
            //不適用
        }
    }

我們都知道Weibo微博這個(gè)產(chǎn)品是沒(méi)有群視頻功能的,所以對(duì)于 groupVideoCall方法來(lái)說(shuō) Weibo 子類(lèi)不能替代父類(lèi) SocialMedia。所以我們認(rèn)為它是不符合里式替換原則。

如果強(qiáng)行這么做的話,會(huì)導(dǎo)致客戶(hù)端用父類(lèi)SocialMedia調(diào)用,但是實(shí)現(xiàn)類(lèi)注入的可能是個(gè)Weibo的實(shí)現(xiàn),調(diào)用groupVideoCall行為,產(chǎn)生意想不到的后果。

那有什么解決方案嗎?

那就把功能拆開(kāi)唄。

public interface SocialMedia {   
       public void chatWithFriend(); 
       public void sendPhotosAndVideos() 
    }
public interface SocialPostAndMediaManager { 
        public void publishPost(Object post); 
    }
public interface VideoCallManager{ 
       public void groupVideoCall(String... users); 
    }

現(xiàn)在,如果您觀察到我們將特定功能隔離到單獨(dú)的類(lèi)以遵循LSP。

現(xiàn)在由實(shí)現(xiàn)類(lèi)決定支持功能,根據(jù)他們所需的功能,他們可以使用各自的接口,例如 Weibo 不支持視頻通話功能,因此 Weibo 實(shí)現(xiàn)可以設(shè)計(jì)成這樣:

public class Instagram implements SocialMedia,SocialPostAndMediaManager{
     public void chatWithFriend(){
        //logic
        }
        public void sendPhotosAndVideos(){
        //logic
        }
        public void publishPost(Object post){
        //logic
        }
    }

這樣子就是符合里式替換原則LSP。

I—接口隔離原則

接口不應(yīng)該強(qiáng)迫他們的客戶(hù)依賴(lài)它不使用的方法。

大家可以看看自己的工程,是不是一個(gè)接口類(lèi)中有很多很多的接口,每次調(diào)用API方法的時(shí)候IDE工具給你彈出一大堆,十分的"臃腫肥胖"。所以該原則的核心思想要將你的接口拆小,拆細(xì),打破”胖接口“,不用強(qiáng)迫客戶(hù)端實(shí)現(xiàn)他們不需要的接口。是不是和單一職責(zé)原則有點(diǎn)像?

例如,假設(shè)有一個(gè)名為 UPIPayment 的接口,如下所示

public interface UPIPayments {
        
        public void payMoney();
        
        public void getScratchCard();
        
        public void getCashBackAsCreditBalance();
    }

現(xiàn)在讓我們談?wù)?nbsp;UPIPayments 的一些實(shí)現(xiàn),比如 Google Pay 和 AliPay。

Google Pay 支持這些功能所以他可以直接實(shí)現(xiàn)這個(gè) UPIPayments 但 AliPay 不支持 getCashBackAsCreditBalance()功能所以這里我們不應(yīng)該強(qiáng)制客戶(hù)端 AliPay 通過(guò)實(shí)現(xiàn) UPIPayments 來(lái)覆蓋這個(gè)方法。

我們需要根據(jù)客戶(hù)需要分離接口,所以為了滿足接口隔離原則,我們可以如下設(shè)計(jì):

  • 創(chuàng)建一個(gè)單獨(dú)的接口來(lái)處理現(xiàn)金返還。
public interface CashbackManager{ 
     public void getCashBackAsCreditBalance(); 
    }

現(xiàn)在我們可以從 UPIPayments 接口中刪除getCashBackAsCreditBalance ,AliPay也不需要實(shí)現(xiàn)getCashBackAsCreditBalance()這個(gè)它沒(méi)有的方法了。

D—依賴(lài)倒置原則

高層模塊不應(yīng)該依賴(lài)低層模塊,兩者都應(yīng)該依賴(lài)于抽象(接口)。抽象不應(yīng)該依賴(lài)于細(xì)節(jié)(具體實(shí)現(xiàn)),細(xì)節(jié)應(yīng)該取決于抽象。

這個(gè)原則我覺(jué)得也不是很好理解,所謂高層模塊和低層模塊的劃分,簡(jiǎn)單來(lái)說(shuō)就是,在調(diào)用鏈上,調(diào)用者屬于高層,被調(diào)用者屬于低層。比如大家都知道的MVC模式,controller是調(diào)用service層接口這個(gè)抽象,而不是實(shí)現(xiàn)類(lèi)。這也是我們經(jīng)常說(shuō)的要面向接口編程,而非細(xì)節(jié)或者具體實(shí)現(xiàn),因?yàn)榻涌谝馕吨跫s,更加穩(wěn)定。

我們通過(guò)一個(gè)例子加深一下理解。

  • 借記卡
public class DebitCard { 
     public void doTransaction(int amount){ 
            System.out.println("tx done with DebitCard"); 
        } 
    }
  • 信用卡
public class CreditCard{ 
     public void doTransaction(int amount){ 
            System.out.println("tx done with CreditCard"); 
        } 
    }

現(xiàn)在用這兩張卡你去購(gòu)物中心購(gòu)買(mǎi)了一些訂單并決定使用信用卡支付

public class ShoppingMall {
     private DebitCard debitCard;
     public ShoppingMall(DebitCard debitCard) {
            this.debitCard = debitCard;
        }
     public void doPayment(Object order, int amount){              
            debitCard.doTransaction(amount); 
      }
     public static void main(String[] args) {
          DebitCard debitCard=new DebitCard();
          ShoppingMall shoppingMall=new ShoppingMall(debitCard);
          shoppingMall.doPayment("some order",5000);
        }
    }

上面的做法是一個(gè)錯(cuò)誤的方式,因?yàn)?nbsp;ShoppingMall 類(lèi)與 DebitCard 緊密耦合。

現(xiàn)在你的借記卡余額不足,想使用信用卡,那么這是不可能的,因?yàn)?nbsp;ShoppingMall 與借記卡緊密結(jié)合。

當(dāng)然你也可以這樣做,從構(gòu)造函數(shù)中刪除借記卡并注入信用卡。但這不是一個(gè)好的方式,它不符合依賴(lài)倒置原則。

那該如何正確設(shè)計(jì)呢?

  • 定義依賴(lài)的抽象接口BankCard
public interface BankCard { 
      public void doTransaction(int amount); 
    }
  • 現(xiàn)在 DebitCard 和 CreditCard 都實(shí)現(xiàn)BankCard
public class CreditCard implements BankCard{
     public void doTransaction(int amount){            
            System.out.println("tx done with CreditCard");
        }
    }
public class DebitCard implements BankCard { 
     public void doTransaction(int amount){ 
      System.out.println("tx done with DebitCard"); 
        } 
    }
  • 現(xiàn)在重新設(shè)計(jì)購(gòu)物中心這個(gè)高級(jí)類(lèi),他也是去依賴(lài)這個(gè)抽象,而不是直接低級(jí)模塊的實(shí)現(xiàn)類(lèi)
public class ShoppingMall {
     private BankCard bankCard;
     public ShoppingMall(BankCard bankCard) {
            this.bankCard = bankCard;
        }
     public void doPayment(Object order, int amount){
            bankCard.doTransaction(amount);
        }
     public static void main(String[] args) {
            BankCard bankCard=new CreditCard();
            ShoppingMall shoppingMall1=new ShoppingMall(bankCard);
            shoppingMall1.doPayment("do some order", 10000);
        }
    }

我們還可以拿 Tomcat這個(gè) Servlet 容器作為例子來(lái)解釋一下。

Tomcat 是運(yùn)行Java Web應(yīng)用程序的容器。我們編寫(xiě)的 Web 應(yīng)用程序代碼只需要部署在Tomcat 容器下,便可以被 Tomcat 容器調(diào)用執(zhí)行。按照之前的劃分原則,Tomcat 就是高層模塊,我們編寫(xiě)的 Web 應(yīng)用程序代碼就是低層模塊。Tomcat 和應(yīng)用程序代碼之間并沒(méi)有直接的依賴(lài)關(guān)系,兩者都依賴(lài)同一個(gè)“抽象”,也就是 Sevlet 規(guī)范。Servlet 規(guī)范不依賴(lài)具體的 Tomcat 容器和應(yīng)用程序的實(shí)現(xiàn)細(xì)節(jié),而 Tomcat 容器和應(yīng)用程序依賴(lài) Servlet規(guī)范。

總結(jié)

本文總結(jié)了軟件編程中的黃金原則,KISS原則,DRY原則,SOLID原則。這些原則不僅僅適用于編程,也可以指導(dǎo)我們?cè)诩軜?gòu)設(shè)計(jì)上。雖然其中有些原則很抽象,但是大家多多實(shí)踐和思考,會(huì)體會(huì)到這些原則的精妙。

責(zé)任編輯:武曉燕 來(lái)源: JAVA旭陽(yáng)
相關(guān)推薦

2022-06-15 09:54:51

PythonIDELinux

2022-06-16 16:08:00

Python初學(xué)者IDE

2015-10-12 11:00:23

編程學(xué)校工作

2019-04-08 15:48:45

程序員技能編程

2017-03-07 15:43:28

編程語(yǔ)言函數(shù)數(shù)據(jù)結(jié)構(gòu)

2018-08-22 10:27:35

編程人工智能機(jī)器人

2016-10-31 20:02:21

WordPress網(wǎng)站數(shù)據(jù)集大數(shù)據(jù)轉(zhuǎn)型戰(zhàn)略

2018-06-21 08:38:05

編程語(yǔ)言程序員代碼

2024-01-23 09:07:29

Unix哲學(xué)工具

2013-06-20 11:15:00

編程技能編程技巧如何選編程

2018-07-18 08:48:11

2014-11-10 09:46:57

程序員

2015-10-10 14:40:36

編程游戲

2020-06-01 08:35:36

編程語(yǔ)言JavaPython

2018-07-18 15:05:01

2012-09-10 09:43:21

編程編程學(xué)習(xí)編程錯(cuò)誤

2011-11-02 09:57:28

程序員

2011-11-22 10:33:11

手機(jī)名詞

2015-03-10 13:43:00

JavaSocket編程編程

2009-01-16 08:52:26

面向?qū)ο?/a>OOP編程
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 成人免费观看视频 | 狠狠色狠狠色综合日日92 | 国产一区二区三区在线免费观看 | 日日干日日 | 欧美精品一区二区三区蜜桃视频 | 91久久久久久久久久久久久 | 天天夜夜操 | 亚洲欧美日韩成人在线 | 国产又爽又黄的视频 | 欧日韩在线观看 | 波多野结衣在线观看一区二区三区 | 一区二区三区四区国产精品 | 久久精品一区 | 亚洲国产高清高潮精品美女 | 人操人人 | 国内精品在线视频 | 永久精品| 日韩成人在线观看 | 激情一区二区三区 | 99精品免费久久久久久久久日本 | 在线观看免费av网 | 欧美黄色一级毛片 | 亚洲毛片在线观看 | 天天视频一区二区三区 | 国产精品无码久久久久 | 国产91在线播放 | 日本福利一区 | 91在线影院 | 99精品国产一区二区三区 | 免费一级淫片aaa片毛片a级 | 亚洲精品9999久久久久 | 欧美精品日韩精品 | av免费网址 | 欧美精品一区在线 | 综合久久色 | 国产一区二区在线播放 | 欧美日韩视频在线播放 | 国产精品久久久久久久岛一牛影视 | 国产成人亚洲精品 | 久久蜜桃精品 | 午夜精品91 |