偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

違反這些設(shè)計原則,系統(tǒng)就等著“腐爛”

開發(fā)
雖然在日常開發(fā)的時候項目進(jìn)度比較緊張,我們很多時候也不去深度設(shè)計代碼實現(xiàn),但是我們在寫代碼的時候保證心中有一桿秤其實還是必要的。

在燦爛的陽光下,龍年重磅來臨。讓我們放下過去的困惑和猶豫,張開懷抱,迎接嶄新的希望和機(jī)遇。祝大家龍年快樂,事業(yè)有成!老貓在此給大家拜年了。

老貓的設(shè)計模式專欄已經(jīng)偷偷發(fā)車了。不甘愿做crud boy?看了好幾遍的設(shè)計模式還記不?。磕蔷筒灰桃庥浟?,跟上老貓的步伐,在一個個有趣的職場故事中領(lǐng)悟設(shè)計模式的精髓吧。還等什么?趕緊上車吧。

故事

這段時間以來,小貓按照之前的系統(tǒng)梳理方案【系統(tǒng)梳理大法&代碼梳理大法】一直在整理著文檔。

系統(tǒng)中涉及的業(yè)務(wù)以及模型也基本了然于胸,但是這代碼寫的真的是...

小貓也終于知道了為什么每天都有客訴,為什么每天都要去調(diào)用curl語句去訂正生產(chǎn)的數(shù)據(jù),為什么每天都在Hotfix...

整理了一下,大概出于這些原因,業(yè)務(wù)流程復(fù)雜暫且不議,光從技術(shù)角度來看,整個代碼體系臃腫不堪,出問題之后定位困難,后面接手的幾任開發(fā)為了解決問題都是“曲線救國”,不從正面去解決問題,為了解決一時的客訴問題而去解決問題,于是定義了各種新的修復(fù)流程去解決問題,這么一來,軟件系統(tǒng)“無序”總量一直在增加,整個系統(tǒng)體系其實在初版之后就已經(jīng)在“腐爛”了,如此?且拋開運(yùn)維穩(wěn)定性不談,就系統(tǒng)本身穩(wěn)定性而言,能好?

所以那兩次事故還真不能怪小貓【事故1,事故2

整個系統(tǒng),除了堆業(yè)務(wù)還是堆業(yè)務(wù),但凡有點軟件設(shè)計原則,系統(tǒng)也不會寫成這樣了。

關(guān)于設(shè)計原則

大家在產(chǎn)品提出需求之后,一般都會去設(shè)計數(shù)據(jù)模型,還有系統(tǒng)流程。但是各位有沒有深度去設(shè)計一下代碼的實現(xiàn)呢?還是說上手就直接照著流程圖開始擼業(yè)務(wù)了?估計有很多的小伙伴由于各種原因不會去考慮代碼設(shè)計,其實老貓很多時候也一樣。主要原因比如:項目催得緊,哪有時間考慮那么多,功能先做出來,剩下的等到后面慢慢優(yōu)化。然而隨著時間的推移,我們會發(fā)現(xiàn)我們一直很忙,說好的把以前的代碼重構(gòu)好一點,哪有時間!于是,就這樣“技術(shù)債”越來越多,就像滾雪球一樣,整個系統(tǒng)逐漸“腐爛”到了根。最終坑的可能是自己,也有可能是“下一個他”。

雖然在日常開發(fā)的時候項目進(jìn)度比較緊張,我們很多時候也不去深度設(shè)計代碼實現(xiàn),但是我們在寫代碼的時候保證心中有一桿秤其實還是必要的。

那咱們就結(jié)合各種案來聊聊“這桿秤”————軟件設(shè)計原則。

下面我們通過各種小例子來協(xié)助大家理解軟件設(shè)計原則,案例是老貓構(gòu)想的,有的時候不要太過較真,主要目的是講清楚原則。另外后文中也會有相關(guān)的類圖表示實體之間的關(guān)系,如果大家對類圖不太熟悉的,也可以看一下這里【類圖傳送門

開閉原則

開閉原則,英文(Open-Closed Principle,簡稱:OCP)。只要指一個軟件實體(例如,類,模塊和函數(shù)),應(yīng)該對擴(kuò)展開放,對修改關(guān)閉。其重點強(qiáng)調(diào)的是抽象構(gòu)建框架,實現(xiàn)擴(kuò)展細(xì)節(jié),從而提升軟件系統(tǒng)的可復(fù)用性以及可維護(hù)性。

概念是抽象,但是案例是具體的,所以咱們直接看案例,通過案例去理解可能更容易。

由于小貓最近在維護(hù)商城類業(yè)務(wù),所以咱們就從商品折價售賣這個案例出發(fā)。業(yè)務(wù)是這樣的,商城需要對商品進(jìn)行做打折活動,目前針對不同品類的商品可能打折的力度不一樣,例如生活用品和汽車用品的打折情況不同。創(chuàng)建一個基礎(chǔ)商品接口:

public interface IProduct {
    String getSpuCode(); //獲取商品編號
    String getSpuName(); //獲取商品名稱
    BigDecimal getPrice(); //獲取商品價格
}

基礎(chǔ)商品實現(xiàn)該接口,于是我們就有了如下代碼:

/**
 * @Author: 公眾號:程序員老貓
 * @Date: 2024/2/7 23:39
 */
public class Product implements IProduct {
    private String spuCode;
    private String spuName;
    private BigDecimal price;
    private Integer categoryTag;

    public Product(String spuCode, String spuName, BigDecimal price, Integer categoryTag) {
        this.spuCode = spuCode;
        this.spuName = spuName;
        this.price = price;
        this.categoryTag = categoryTag;
    }

    public Integer getCategoryTag() {
        return categoryTag;
    }

    @Override
    public String getSpuCode() {
        return spuCode;
    }

    @Override
    public String getSpuName() {
        return spuName;
    }

    @Override
    public BigDecimal getPrice() {
        return price;
    }
}

按照上面的業(yè)務(wù),現(xiàn)在搞活動,咱們需要針對不同品類的商品進(jìn)行促銷活動,例如生活用品需要進(jìn)行折扣。當(dāng)然我們有兩種方式實現(xiàn)這個功能,如果咱們不改變原有代碼,咱們可以如下實現(xiàn)。

public class DailyDiscountProduct extends Product {
    private static final BigDecimal daily_discount_factor = new BigDecimal(0.95);
    private static final Integer DAILY_PRODUCT = 1;

    public DailyDiscountProduct(String spuCode, String spuName, BigDecimal price) {
        super(spuCode, spuName, price, DAILY_PRODUCT);
    }

    public BigDecimal getOriginPrice() {
        return super.getPrice();
    }

    @Override
    public BigDecimal getPrice() {
        return super.getPrice().multiply(daily_discount_factor);
    }
}

上面我們看到直接打折的日常用品的商品繼承了標(biāo)準(zhǔn)商品,并且對其進(jìn)行了價格重寫,這樣就完成了生活用品的打折。當(dāng)然這種打折系數(shù)的話我們一般可以配置到數(shù)據(jù)庫中。

對汽車用品的打折其實也是一樣的實現(xiàn)。繼承之后重寫價格即可。咱們并不需要去基礎(chǔ)商品Product中根據(jù)不同的品類去更改商品的價格。

錯誤案例:

如果我們一味地在原始類別上去做邏輯應(yīng)該就是如下這樣:

public class Product implements IProduct {
    private static final Integer DAILY_PRODUCT = 1;
    private static final BigDecimal daily_discount_factor = new BigDecimal(0.95);
    private String spuCode;
    private String spuName;
    private BigDecimal price;
    private Integer categoryTag;
    ....
    @Override
    public BigDecimal getPrice() {
      if(categotyTag.equals(DAILY_PRODUCT)){
        return price.multiply(daily_discount_factor);
      }
      return price;
    }
}

后續(xù)隨著業(yè)務(wù)的演化,后面如果提出對商品名稱也要定制,那么咱們可能還是會動當(dāng)前的代碼,我們一直在改當(dāng)前類,代碼越堆越多,越來越臃腫,這種實現(xiàn)方式就破壞了開閉原則。

咱們看一下開閉原則的類圖。如下:

開閉原則類圖

依賴倒置原則

依賴倒置原則,英文名(Dependence Inversion Principle,簡稱DIP),指的是高層模塊不應(yīng)該依賴低層模塊,二者都應(yīng)該依賴其抽象。通過依賴倒置,可以減少類和類之間的耦合性,從而提高系統(tǒng)的穩(wěn)定性。這里主要強(qiáng)調(diào)的是,咱們寫代碼要面向接口編程,不要面向?qū)崿F(xiàn)去編程。

定義看起來不夠具體,咱們來看一下下面這樣一個業(yè)務(wù)。針對不同的大客戶,我們定制了很多商城,有些商城是專門售賣電器的,有些商城是專門售賣生活用品的。有個大客,由于對方是電器供應(yīng)商,所以他們想售賣自己的電器設(shè)備,于是,我們就有了下面的業(yè)務(wù)。

//定義了一個電器設(shè)備商城,并且支持特有的電器設(shè)備下單流程
public class ElectricalShop {
    public String doOrder(){
        return "電器商城下單";
    }
}
//用戶進(jìn)行下單購買電器設(shè)備
public class Consumer extends ElectricalShop {
    public void shopping() {
        super.doOrder();
    }
}

我們看到,當(dāng)客戶可選擇的只有一種商城的時候,這種實現(xiàn)方式確實好像沒有什么問題,但是現(xiàn)在需求變了,馬上要過年了,大客戶不想僅僅給他們的客戶提供電器設(shè)備,他們還想賣海鮮產(chǎn)品,這樣,以前的這種下單模式好像會有點問題,因為以前我們直接繼承了ElectricalShop,這樣寫的話,業(yè)務(wù)可拓展性就太差了,所以我們就需要抽象出一個接口,然后客戶在下單的時候可以選擇不同的商城進(jìn)行下單。于是改造之后,咱們就有了如下代碼:

//抽象出一個更高維度的商城接口
public interface Shop {
    String doOrder();
}
//電器商城實現(xiàn)該接口實現(xiàn)自有下單流程
public class ElectricalShop implements Shop {
    public String doOrder(){
        return "電器商城下單";
    }
}
//海鮮商城實現(xiàn)該接口實現(xiàn)自有下單流程
public class SeaFoodShop implements Shop{
    @Override
    public String doOrder() {
        return "售賣一些海鮮產(chǎn)品";
    }
}
//消費(fèi)者注入不同的商城商品信息
public class Consumer {
    private Shop shop;
    public Consumer(Shop shop) {
        this.shop = shop;
    }
    public String shopping() {
        return shop.doOrder();
    }
}
//消費(fèi)者在不同商城隨意切換下單測試
public class ConsumerTest {
    public static void main(String[] args) {
        //電器商城下單
        Consumer consumer = new Consumer(new ElectricalShop());
        System.out.println(consumer.shopping());
        //海鮮商城下單
        Consumer consumer2 = new Consumer(new SeaFoodShop());
        System.out.println(consumer2.shopping());
    }
}

上面這樣改造之后,原本繼承詳細(xì)商城實現(xiàn)的Consumer類,現(xiàn)在直接將更高維度的商城接口注入到了類中,這樣相信后面再多幾個新的商城的下單流程都可以很方便地就完成拓展。

這其實也就是依賴倒置原則帶來的好處,咱們最終來看一下類圖。

DIP

單一職責(zé)原則

單一職責(zé)原則,英文名(SimpleResponsibility Pinciple,簡稱SRP)指的是不要存在多余一個導(dǎo)致類變更的原因。這句話看起來還是比較抽象的,老貓個人的理解是單一職責(zé)原則重點是區(qū)分業(yè)務(wù)邊界,做到合理地劃分業(yè)務(wù),根據(jù)產(chǎn)品的需求不斷去重新規(guī)劃設(shè)計當(dāng)前的類信息。關(guān)于單一職責(zé)老貓其實之前已經(jīng)和大家分享過了,在此不多贅述,大家可以進(jìn)入這個傳送門【單一職責(zé)原則】。

接口隔離原則

接口隔離原則(Interface Segregation Principle,簡稱ISP)指的是指盡量提供專門的接口,而非使用一個混合的復(fù)雜接口對外提供服務(wù)。

聊到接口隔離原則,其實這種原則和單一職責(zé)原則有點類似,但是又不同:

  • 聯(lián)系:接口隔離原則和單一職責(zé)原則都是為了提高代碼的可維護(hù)性和可拓展性以及可重用性,其核心的思想都是“高內(nèi)聚低耦合”。
  • 區(qū)別:針對性不同,接口隔離原則針對的是接口,而單一職責(zé)原則針對的是類。

下面,咱們用一個業(yè)務(wù)例子來說明一下吧。我們用簡單的動物行為這樣一個例子來說明一下,動物從大的方面有能飛的,能吃,能跑,有的也會游泳等等。如果我們定義一個比較大的接口就是這樣的。

public interface IAnimal {
    void eat();
    void fly();
    void swim();
    void run();
    ...
}

我們用貓咪實現(xiàn)了該方法,于是就有了。

public class Cat implements IAnimal{
    @Override
    public void eat() {
        System.out.println("老貓喜歡吃小魚干");
    }
    @Override
    public void fly() {
    }
    @Override
    public void swim() {
    }
    @Override
    public void run() {
        System.out.println("老貓還喜歡奔跑");
    }
}

我們很容易就能發(fā)現(xiàn),如果老貓不是“超人貓”的話,老貓就沒辦法飛翔以及游泳,所以當(dāng)前的類就有兩個空著的方法。同樣的如果有一只百靈鳥,那么實現(xiàn)Animal接口之后,百靈鳥的游泳方法也是空著的。那么這種實現(xiàn)我們發(fā)現(xiàn)只會讓代碼變得很臃腫,所以,我們發(fā)現(xiàn)IAnimal這個接口的定義太大了,我們需要根據(jù)不同的行為進(jìn)行二次拆分。拆分之后的結(jié)果如下:

//所有的動物都會吃東西
public interface IAnimal {
    void eat();
}
//專注飛翔的接口
public interface IFlyAnimal {
    void fly();
}
//專注游泳的接口
public interface ISwimAnimal {
    void swim();
}

那如果現(xiàn)在有一只鴨子和百靈鳥,咱們分別去實現(xiàn)的時候如下:

public class Duck implements IAnimal,ISwimAnimal{
    @Override
    public void eat() {
        System.out.println("鴨子吃食");
    }

    @Override
    public void swim() {
        System.out.println("鴨子在河里游泳");
    }
}

public class Lark implements IAnimal,IFlyAnimal{
    @Override
    public void eat() {
        System.out.println("百靈鳥吃食");
    }

    @Override
    public void fly() {
        System.out.println("百靈鳥會飛");
    }
}

我們可以看到,這樣在我們具體的實現(xiàn)類中就不會存在空方法的情況,代碼隨著業(yè)務(wù)的發(fā)展也不會變得過于臃腫。咱們看一下最終的類圖。

ISP

迪米特原則

迪米特原則(Law of Demeter,簡稱 LoD),指的是一個對象應(yīng)該對其他對象保持最少的了解,如果上面這個原則名稱不容易記,其實這種設(shè)計原則還有另外一個名稱,叫做最少知道原則(Least Knowledge Principle,簡稱LKP)。其實主要強(qiáng)調(diào)的也是降低類和類之間的耦合度,白話“不要和陌生人說話”,或者也可以理解成“讓專業(yè)的人去做專業(yè)的事情”,出現(xiàn)在成員變量,方法輸入、輸出參數(shù)中的類都可以稱為成員朋友類,而出現(xiàn)在方法體內(nèi)部的類不屬于朋友類。

通過具體場景的例子來看一下。由于小貓接手了商城類的業(yè)務(wù),目前他對業(yè)務(wù)的實現(xiàn)細(xì)節(jié)應(yīng)該是最清楚的,所以領(lǐng)導(dǎo)在向老板匯報相關(guān)SKU銷售情況的時候總是會找到小貓去統(tǒng)計各個品類的sku的銷售額以及銷售量。于是就有了領(lǐng)導(dǎo)下命令,小貓去做統(tǒng)計的業(yè)務(wù)流程。

//sku商品
public class Sku {
    private BigDecimal price;
    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }
}

//小貓統(tǒng)計總sku數(shù)量以及總銷售金額
public class Kitty {
    public void doSkuCheck(List<Sku> skuList) {
        BigDecimal totalSaleAmount =
                skuList.stream().map(sku -> sku.getPrice()).reduce(BigDecimal::add).get();
        System.out.println("總sku數(shù)量:" + skuList.size() + "sku總銷售金額:" + totalSaleAmount);
    }
}

//領(lǐng)導(dǎo)讓小貓去統(tǒng)計各個品類的商品
public class Leader {
    public void checkSku(Kitty kitty) {
        //模擬領(lǐng)導(dǎo)指定的各個品類
        List<Sku> difCategorySkuList = new ArrayList<>();
        kitty.doSkuCheck(difCategorySkuList);
    }
}

//測試類
public class LodTest {
    public static void main(String[] args) {
        Leader leader = new Leader();
        Kitty kitty = new Kitty();
        leader.checkSku(kitty);
    }
}

從上面的例子來看,領(lǐng)導(dǎo)其實并沒有參與統(tǒng)計的任何事情,他只是指定了品類讓小貓去統(tǒng)計。從而降低了類和類之間的耦合。即“讓專門的人做專門的事”

我們看一下最終的類圖。

LOD

里氏替換原則

里氏替換原則(Liskov Substitution Principle,英文簡稱:LSP),它由芭芭拉·利斯科夫(Barbara Liskov)在1988年提出。里氏替換原則的含義是:如果一個程序中所有使用基類的地方都可以用其子類來替換,而程序的行為沒有發(fā)生變化,那么這個子類就遵守了里氏替換原則。換句話說,一個子類應(yīng)該可以完全替代它的父類,并且保持程序的正確性和一致性。

上述的定義還是比較抽象的,老貓試著重新理解一下:

  • 子類可以實現(xiàn)父類的抽象方法,但是不能覆蓋父類的抽象方法。
  • 子類可以增加自己特有的方法。
  • 當(dāng)子類的方法重載父類的方法的時,方法的前置條件(即方法的輸入/入?yún)ⅲ┮雀割惙椒ǖ妮斎雲(yún)?shù)更加寬松。
  • 當(dāng)子類的方法實現(xiàn)父類的方法時,方法的后置條件比父類更嚴(yán)格或者和父類一樣。

里氏替換原則準(zhǔn)確來說是上述提到的開閉原則的實現(xiàn)方式,但是它克服了繼承中重寫父類造成的可復(fù)用性變差的缺點。它是動作正確性的保證。即類的擴(kuò)展不會給已有的系統(tǒng)引入新的錯誤,降低了代碼出錯的可能性。

下面咱們用里式替換原則比較經(jīng)典的例子來說明“鴕鳥不是鳥”。我們看一下咱們印象中的鳥類:

class Bird {
    double flySpeed; 
 
    //設(shè)置飛行速度
    public void setSpeed(double speed) {
        flySpeed = speed;
    }
 
    //計算飛行所需要的時間
    public double getFlyTime(double distance) {
        return (distance / flySpeed);
    }
}
//燕子
public class Swallow extends Bird{
}
//由于鴕鳥不能飛,所以我們將鴕鳥的速度設(shè)置為0
public class Ostrich extends Bird {
    public void setSpeed(double speed) {
        flySpeed = 0;
    }
}

光看這個實現(xiàn)的時候好像沒有問題,但是我們調(diào)用其方法計算其指定距離飛行時間的時候,那么這個時候就有問題了,如下:

public class TestMain {
    public static void main(String[] args) {
        double distance = 120;
        Ostrich ostrich = new Ostrich();
        System.out.println(ostrich.getFlyTime(distance));

        Swallow swallow = new Swallow();
        swallow.setSpeed(30);
        System.out.println(swallow.getFlyTime(distance));
    }
}

結(jié)果輸出:

Infinity
4.0

顯然鴕鳥出問題了:

  • 鴕鳥重寫了鳥類的 setSpeed(double speed) 方法,這違背了里氏替換原則。
  • 燕子和鴕鳥都是鳥類,但是父類抽取的共性有問題,鴕鳥的飛行不是正常鳥類的功能,需要特殊處理,應(yīng)該抽取更加共性的功能。

于是我們進(jìn)行對其進(jìn)行優(yōu)化,咱們?nèi)∠r鳥原來的繼承關(guān)系,定義鳥和鴕鳥的更一般的父類,如動物類,它們都有奔跑的能力。鴕鳥的飛行速度雖然為 0,但奔跑速度不為 0,可以計算出其奔跑指定距離所要花費(fèi)的時間。優(yōu)化之后代碼如下:

//抽象出更高層次的動物類,定義內(nèi)部的奔跑行為
public class Animal {
    double runSpeed;

    //設(shè)置奔跑速度
    public void setSpeed(double speed) {
        runSpeed = speed;
    }
    //計算奔跑所需要的時間
    public double getRunTime(double distance) {
        return (distance / runSpeed);
    }
}
//定義飛行的鳥類
public class Bird extends Animal {
    double flySpeed;
    //設(shè)置飛行速度
    public void setSpeed(double speed) {
        flySpeed = speed;
    }
    //計算飛行所需要的時間
    public double getFlyTime(double distance) {
        return (distance / flySpeed);
    }
}
//此時鴕鳥直接繼承動物接口
public class Ostrich extends Animal {
}
//燕子繼承普通的鳥類接口
public class Swallow extends Bird {
}

簡單測試一下:

public class TestMain {
    public static void main(String[] args) {
        double distance = 120;
        Ostrich ostrich = new Ostrich();
        ostrich.setSpeed(40);
        System.out.println(ostrich.getRunTime(distance));

        Swallow swallow = new Swallow();
        swallow.setSpeed(30);
        System.out.println(swallow.getFlyTime(distance));
    }
}

結(jié)果輸出:

3.0
4.0

優(yōu)化之后,優(yōu)點:

  • 代碼共享,減少創(chuàng)建類的工作量,每個子類都擁有父類的方法和屬性;
  • 提高代碼的重用性;
  • 提高代碼的可擴(kuò)展性;
  • 提高產(chǎn)品或項目的開放性;

缺點:

  • 繼承是侵入性的。只要繼承,就必須擁有父類的所有屬性和方法;
  • 降低代碼的靈活性。子類必須擁有父類的屬性和方法,讓子類自由的世界中多了些約束;
  • 增強(qiáng)了耦合性。當(dāng)父類的常量、變量和方法被修改時,需要考慮子類的修改,而且在缺乏規(guī)范的環(huán)境下,這種修改可能帶來非常糟糕的結(jié)果————大段的代碼需要重構(gòu)。

最終我們看一下類圖:

老貓覺得里氏替換原則是最難把握好的,所以到后續(xù)咱們再進(jìn)行深入設(shè)計模式回歸的時候再做深入探究。

合成復(fù)用原則

合成復(fù)用原則(Composite/Aggregate Reuse Principle,英文簡稱CARP)是指咱們盡量要使用對象組合而不是繼承關(guān)系達(dá)到軟件復(fù)用的目的。這樣的話系統(tǒng)就可以變得更加靈活,同時也降低了類和類之間的耦合度。

看個例子,當(dāng)我們剛學(xué)java的時候都是從jdbc開始學(xué)起來的。所以對于DBConnection我們并不陌生。那當(dāng)我們實現(xiàn)基本產(chǎn)品Dao層的時候,我們就有了如下寫法:

public class DBConnection {
    public String getConnection(){
        return "獲取數(shù)據(jù)庫鏈接";
    }
}
//基礎(chǔ)產(chǎn)品dao層
public class ProductDao {
    private DBConnection dbConnection;

    public ProductDao(DBConnection dbConnection) {
        this.dbConnection = dbConnection;
    }

    public void saveProduct(){
        String conn = dbConnection.getConnection();
        System.out.println("使用"+conn+"新增商品");
    }
}

上述就是最簡單的合成服用原則應(yīng)用場景。但是這里有個問題,DBConnection目前只支持mysql一種連接DB的方式,顯然不合理,有很多企業(yè)其實還需要支持Oracle數(shù)據(jù)庫連接,所以為了符合之前說到的開閉原則,我們讓DBConnection交給子類去實現(xiàn)。于是我們可以將其定義成抽象方法。

public abstract class DBConnection {
    public abstract String getConnection();
}
//mysql鏈接
public class MySqlConnection extends DBConnection{
    @Override
    public String getConnection() {
        return "獲取mysql鏈接";
    }
}
//oracle鏈接
public class OracleConnection extends DBConnection{
    @Override
    public String getConnection() {
        return "獲取Oracle鏈接方式";
    }
}

最終的實現(xiàn)方式我們一起看一下類圖。

CARP

總結(jié)

之前看過一個故事,一棟樓的破敗往往從一扇破窗戶開始,慢慢腐朽。其實代碼的腐爛其實也是一樣,往往是一段拓展性極差的代碼開始。所以這要求我們研發(fā)人員還是得心中有桿“設(shè)計原則”的秤,咱們可能不會去做刻意的代碼設(shè)計,但是相信有這么一桿原則的秤,代碼也不至于會寫得太爛。

當(dāng)然我們也不要刻意去追求設(shè)計原則,要權(quán)衡具體的場景做出合理的取舍。設(shè)計原則是設(shè)計模式的基礎(chǔ),相信大家在了解完設(shè)計原則之后對后續(xù)的設(shè)計模式會有更加深刻的理解。

責(zé)任編輯:趙寧寧 來源: 程序員老貓
相關(guān)推薦

2010-07-16 11:12:40

云計算爭議

2022-12-26 18:53:00

MQ宕機(jī)倉儲服務(wù)

2020-11-10 07:08:08

API程序外接口

2016-11-28 09:06:45

前端系統(tǒng)開發(fā)

2021-10-17 22:24:57

芯片數(shù)據(jù)技術(shù)

2025-06-03 08:05:00

設(shè)計原則開發(fā)代碼

2024-08-16 14:01:00

2016-03-29 09:59:11

JavaScriptAPI設(shè)計

2013-04-17 10:46:54

面向?qū)ο?/a>

2012-05-08 10:14:45

設(shè)計原則

2011-11-09 13:59:27

代碼腐爛

2021-07-05 06:51:43

流程代碼結(jié)構(gòu)

2012-03-15 11:15:13

Java設(shè)計模式

2013-06-09 11:04:07

設(shè)計扁平化設(shè)計平面化設(shè)計

2010-10-11 11:25:26

MySQL主鍵

2012-06-07 10:11:01

面向?qū)ο?/a>設(shè)計原則Java

2017-06-19 14:21:01

JavaScriptAPI設(shè)計原則

2011-06-01 10:58:57

2012-03-05 13:58:34

設(shè)計模式里氏置換

2012-03-07 10:40:19

Java設(shè)計模式
點贊
收藏

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