Java日記之設(shè)計(jì)模式初探

前言

設(shè)計(jì)模式是在開發(fā)中必須要掌握的一種技能搂擦,包括各個(gè)項(xiàng)目的結(jié)構(gòu)設(shè)計(jì)以及一些框架源碼的解讀庇配,里面都包含有設(shè)計(jì)模式歌逢,設(shè)計(jì)模式也是面試中經(jīng)常問(wèn)到签杈,從這篇文章開始記錄全部23種設(shè)計(jì)模式的解析,23種設(shè)計(jì)模式根據(jù)準(zhǔn)則來(lái)分類總共分為三大類沽一,創(chuàng)建型盖溺、結(jié)構(gòu)形以及行為型。此篇文章的大部分源代碼出自于Java設(shè)計(jì)模式精講 Debug方式+內(nèi)存分析铣缠,并結(jié)合我自己的理解烘嘱,已獲得課程老師同意昆禽。


感謝geely老師


設(shè)計(jì)模式的七大原則

在講設(shè)計(jì)模式之前,首先就要講設(shè)計(jì)模式的七大原則:

  1. 開閉原則(open closed principle)
  2. 依賴倒置原則(dependence inversion principle)
  3. 單一職責(zé)原則(Single Responsibility Principle)
  4. 接口隔離原則(interface segregation principle)
  5. 迪米特原則(law of demeter LOD)
  6. 里氏替換原則(LSP liskov substitution principle)
  7. 合成復(fù)用原則(Composite Reuse Principle)

1. 開閉原則(open closed principle)

  • 定義:一個(gè)軟件的實(shí)體比如類笙以、模塊和函數(shù)應(yīng)該對(duì)擴(kuò)展開放淌实,修改和關(guān)閉,所謂的開閉也正是對(duì)擴(kuò)展和修改這兩個(gè)行為的原則猖腕,強(qiáng)調(diào)的是用抽象構(gòu)建框架拆祈,用實(shí)現(xiàn)來(lái)擴(kuò)展細(xì)節(jié),它是面向設(shè)計(jì)模式中最基礎(chǔ)的原則倘感,它知道我們?nèi)绾谓⒎€(wěn)定靈活的系統(tǒng)放坏,例如版本更新,盡量不修改源代碼老玛,但是可以增加新功能淤年,實(shí)現(xiàn)開閉原則的思想就是面向抽象編程钧敞。

  • 優(yōu)點(diǎn): 提高軟件的可復(fù)用性及可維護(hù)性。

代碼舉例:

public interface ICourse {
    Integer getId();
    String getName();
    Double getPrice();
}

//實(shí)現(xiàn)類
public class JavaCourse implements ICourse{
    private Integer Id;
    private String name;
    private Double price;

    public JavaCourse(Integer id, String name, Double price) {
        this.Id = id;
        this.name = name;
        this.price = price;
    }

    public Integer getId() {
        return this.Id;
    }

    public String getName() {
        return this.name;
    }

    public Double getPrice() {
        return this.price;
    }

}

首先創(chuàng)建一個(gè)接口和它的實(shí)現(xiàn)類麸粮,這時(shí)候假如說(shuō)要對(duì)JavaCourse這個(gè)類進(jìn)行拓展溉苛,但是不修改原來(lái)的代碼,該怎么做呢弄诲?很簡(jiǎn)單愚战,繼承這個(gè)類,并進(jìn)行拓展就行齐遵,以下的例子:

//拓展類
public class JavaDiscountCourse extends JavaCourse {

    public JavaDiscountCourse(Integer id, String name, Double price) {
        super(id, name, price);
    }

    public Double getDiscountPrice(){
        return super.getPrice()*0.8;
    }

}

//測(cè)試類
public class Test {
    public static void main(String[] args) {
        ICourse iCourse = new JavaDiscountCourse(96, "Java從零到企業(yè)級(jí)電商開發(fā)", 348d);
        JavaDiscountCourse javaCourse = (JavaDiscountCourse) iCourse;
        System.out.println("課程ID:" + javaCourse.getId() + " 課程名稱:" + javaCourse.getName() 
        + " 課程原價(jià):" + javaCourse.getPrice() + " 課程折后價(jià)格:" + javaCourse.getDiscountPrice() + "元");

    }
}
開閉原則代碼運(yùn)行結(jié)果

從代碼就可以看出來(lái)了寂玲,這就很符合開閉原則,我們只對(duì)類進(jìn)行拓展和修改洛搀,如果是修改方法的話敢茁,通過(guò)接口去進(jìn)行抽象出來(lái),然后去實(shí)現(xiàn)就可以留美,這就是面向接口編程彰檬。

2.依賴倒置原則(dependence inversion principle)

  • 定義:高層模塊不應(yīng)該依賴底層模塊,兩者都應(yīng)該依賴其抽象谎砾。意思就是抽象不應(yīng)該依賴細(xì)節(jié)逢倍,細(xì)節(jié)應(yīng)該依賴抽象,還是最主要的景图,就是針對(duì)接口來(lái)進(jìn)行編程较雕,不要針對(duì)實(shí)現(xiàn)來(lái)進(jìn)行編程。 通過(guò)抽象可以使各個(gè)類或者模塊的實(shí)現(xiàn)彼此獨(dú)立互不影響挚币,從而實(shí)現(xiàn)模塊之間的松耦合亮蒋,降低模塊的耦合性。使用這個(gè)原則也有一些注意的點(diǎn)妆毕,就是每個(gè)類都盡量繼承接口或者抽象類慎玖。

  • 優(yōu)點(diǎn):可以減少類間的耦合,提高系統(tǒng)的而穩(wěn)定性笛粘,提高代碼的可讀性和可維護(hù)性趁怔,也降低了修改程序所造成的的風(fēng)險(xiǎn)。

代碼舉例:

定義接口
public interface ICourse {
    void studyCourse();
}

實(shí)現(xiàn)類
public class JavaCourse implements ICourse {

    @Override
    public void studyCourse() {
        System.out.println("學(xué)習(xí)Java課程");
    }
}

public class PythonCourse implements ICourse {

    @Override
    public void studyCourse() {
        System.out.println("學(xué)習(xí)Python課程");
    }
}

首先定義接口和它的實(shí)現(xiàn)類薪前,接著我們面向接口編程呢润努,我只需要要?jiǎng)?chuàng)建一個(gè)傳遞接口實(shí)現(xiàn)的類就好了。

public class Ju {

    public void setiCourse(ICourse iCourse) {
        this.iCourse = iCourse;
    }

    private ICourse iCourse;



    public void studyImoocCourse(){
        iCourse.studyCourse();
    }

    
}

//測(cè)試類實(shí)現(xiàn)
public class Test {

    public static void main(String[] args) {
        Ju ju = new Ju();
        ju.setiCourse(new JavaCourse());
        ju.studyImoocCourse();

        ju.setiCourse(new FECourse());
        ju.studyImoocCourse();

    }
}

依賴倒置原則代碼運(yùn)行結(jié)果

從代碼就可以看出來(lái)示括,這就是面向接口編程铺浇,你需要實(shí)現(xiàn)接口什么樣的方法,就只要把實(shí)現(xiàn)這個(gè)接口的類實(shí)例化就可以輕松的進(jìn)行調(diào)用垛膝,這樣就降低了耦合度随抠,也就不用如果需要替換類裁着,就需要從核心邏輯上替換實(shí)現(xiàn)的類了,也提高了代碼的可維護(hù)性拱她。

3.單一職責(zé)原則(Single Responsibility Principle)

  • 定義:不要存在多于一個(gè)導(dǎo)致類變更的原因二驰。假設(shè)我們有一個(gè)類負(fù)責(zé)兩個(gè)職責(zé), 但是一旦有其中一個(gè)需求變更秉沼,就要修改里面的代碼桶雀,但是修改的話有可能就導(dǎo)致原版運(yùn)行正常的另一個(gè)職責(zé)發(fā)生問(wèn)題。也就是說(shuō)這個(gè)類有兩個(gè)職責(zé)唬复,對(duì)于這樣子的類的話矗积,我們就需要分別建立兩個(gè)類,分別負(fù)責(zé)職責(zé)敞咧,這樣就不會(huì)發(fā)生故障或者變更棘捣。一個(gè)類/接口/方法只負(fù)責(zé)一項(xiàng)原則。

  • 優(yōu)點(diǎn):降低類的復(fù)雜度休建,提高類的可讀性乍恐,提高系統(tǒng)的可維護(hù)性和降低變更引起的風(fēng)險(xiǎn)。

  • 缺點(diǎn):有可能類會(huì)非常的多测砂,可讀性就差茵烈。
    代碼舉例:

private void updateUserInfo(String userName,String address,boolean bool){
    if(bool){
        //todo something1
    }else{
        //todo something2
    }
}

比如說(shuō)一個(gè)有新的業(yè)務(wù)需求(如上代碼),你可能就需要在代碼上面直接更改砌些,這樣子如此長(zhǎng)期改下去可能會(huì)發(fā)生問(wèn)題呜投。我們就推薦各創(chuàng)建一個(gè)類并負(fù)責(zé)各自的職責(zé)。

//各自類的實(shí)現(xiàn)
public class FlyBird {
    public void mainMoveMode(String birdName){
        System.out.println(birdName+"用翅膀飛");
    }
}

public class WalkBird {
    public void mainMoveMode(String birdName){
        System.out.println(birdName+"用腳走");
    }
}

//測(cè)試類
public class Test {
    public static void main(String[] args) {
        FlyBird flyBird = new FlyBird();
        flyBird.mainMoveMode("大雁");

        WalkBird walkBird = new WalkBird();
        walkBird.mainMoveMode("鴕鳥");

    }
}

一些公共的方法可以使用抽象類來(lái)進(jìn)行實(shí)現(xiàn)存璃,不同的業(yè)務(wù)仑荐,就創(chuàng)建各自的類來(lái)進(jìn)行負(fù)責(zé)其職責(zé)就好。

4.接口隔離原則(interface segregation principle)

  • 定義:用多個(gè)專門的接口纵东,而不使用單一的接口粘招,客戶端不應(yīng)該依賴它不需要的接口。一個(gè)類對(duì)一個(gè)類的依賴應(yīng)該建立在最小的接口上篮迎。建立單一接口男图,不要建立龐大臃腫的接口示姿,盡量細(xì)化接口甜橱,接口的方法,盡量少栈戳,太少也不行岂傲,就是一定要適度。

  • 優(yōu)點(diǎn):符合我們常說(shuō)的高內(nèi)聚低耦合的設(shè)計(jì)思想子檀,從而使得類具有很好的可讀性镊掖,可擴(kuò)展性和可維護(hù)性乃戈。

代碼舉例:

//接口定義
public interface IAnimalAction {
    void eat();
    void fly();
    void swim();

}

public interface IEatAnimalAction {
    void eat();
}

public interface IFlyAnimalAction {
    void fly();
}

public interface ISwimAnimalAction {
    void swim();
}

//實(shí)現(xiàn)類
public class Bird implements IAnimalAction {
    @Override
    public void eat() {

    }

    @Override
    public void fly() {

    }

    @Override
    public void swim() {

    }
}

public class Dog implements ISwimAnimalAction,IEatAnimalAction {

    @Override
    public void eat() {

    }

    @Override
    public void swim() {

    }
}

這就是一個(gè)接口隔離原則的設(shè)計(jì)了,因?yàn)楸容^簡(jiǎn)單所有沒(méi)什么好說(shuō)的亩进,就是通過(guò)一個(gè)接口來(lái)對(duì)應(yīng)一個(gè)類以及使用多繼承症虑。

5.迪米特原則(law of demeter LOD)

  • 定義:一個(gè)對(duì)象應(yīng)該對(duì)其他對(duì)象保持最少的了解,又叫最少知道原則归薛,盡量降低類的耦合谍憔,就是盡量不要對(duì)外公開過(guò)多的方法和變量,多使用private權(quán)限來(lái)約束主籍。

  • 優(yōu)點(diǎn):降低類之間的耦合习贫。

代碼舉例:
比如Boss說(shuō)有一個(gè)需求就是查詢現(xiàn)在有多少門線上課程,這就關(guān)系了三個(gè)類千元,TeamLeader苫昌、Course和Boss。

public class Boss {

    public void commandCheckNumber(TeamLeader teamLeader){
        teamLeader.checkNumberOfCourses();
    }

}

public class Course {
}

public class TeamLeader {
    public void checkNumberOfCourses(){
        List<Course> courseList = new ArrayList<Course>();
        //模擬查詢課程邏輯
        for(int i = 0 ;i < 20;i++){
            courseList.add(new Course());
        }
        System.out.println("在線課程的數(shù)量是:"+courseList.size());
    }

}

//測(cè)試類
public class Test {
    public static void main(String[] args) {
        Boss boss = new Boss();
        TeamLeader teamLeader = new TeamLeader();
        boss.commandCheckNumber(teamLeader);

    }
}
迪米特原則代碼運(yùn)行結(jié)果

從這段代碼我們看到Course是有TeamLeader來(lái)生成的幸海,Course是不和Boss發(fā)生接觸的祟身,Boss也不需要知道Course,這就是迪米特原則涕烧,Boss不需要關(guān)心那么多細(xì)節(jié)月而,只要知道結(jié)果就行。

6. 里氏替換原則(LSP liskov substitution principle)

  • 定義:如果對(duì)每個(gè)類型為T1的對(duì)象o1议纯,都有類型為T2的對(duì)象o2父款,使得T1定義的所有程序P在所有的對(duì)象o1都替換成o2時(shí),程序P的行為沒(méi)有發(fā)生變化瞻凤,那么類型T2是類型T1的子類型憨攒。這個(gè)原則相比其他幾個(gè)是比較難理解的,簡(jiǎn)單來(lái)說(shuō)就是T1這個(gè)類生成了o1對(duì)象阀参,T2生成了o2對(duì)象肝集,我們現(xiàn)在寫一個(gè)程序,里面使用T1的類型蛛壳,同時(shí)創(chuàng)建了o1杏瞻,當(dāng)我們把所有程序中的o1都替換成T2生成的o2時(shí),這時(shí)程序的行為沒(méi)有發(fā)生變化衙荐,那么就可以認(rèn)為T2是T1的子類型捞挥。有沒(méi)有發(fā)現(xiàn)跟開閉原則有點(diǎn)類似,它其實(shí)就是開閉原則的補(bǔ)充忧吟。

  • 定義擴(kuò)展:一個(gè)軟件實(shí)體如果適用一個(gè)父類的話砌函,那一定適用于其子類,所有引用父類的地方必須能透明的適用其子類的對(duì)象,子類對(duì)象能夠替換父類對(duì)象讹俊,而程序邏輯不變垦沉。子類可以擴(kuò)展父類的功能,但不能改變父類原有的功能仍劈。子類可以實(shí)現(xiàn)父類的抽象方法厕倍,但不能覆蓋父類的非抽象方法。子類可以增加自己特有的方法贩疙。當(dāng)子類的方法重載父類的方法绑青,方法的前置條件要比父類的輸入?yún)?shù)更寬松。當(dāng)子類的方法實(shí)現(xiàn)父類的方法時(shí)屋群,方法的后置條件要比父類更加嚴(yán)格或者相等闸婴。

  • 優(yōu)點(diǎn):約束繼承泛濫,開閉原則的一種體現(xiàn)芍躏。也加強(qiáng)了程序的健壯性邪乍,同時(shí)變更時(shí)也可以做到非常好的兼容性,提高程序的維護(hù)性对竣,擴(kuò)展性庇楞,降低需求變更時(shí)引入的風(fēng)險(xiǎn)。

代碼舉例:
舉個(gè)例子說(shuō)明下繼承的風(fēng)險(xiǎn)(以下例子來(lái)源其他博客否纬,侵刪)

public class Father {
    public int subtraction(int a, int b) {
        return a - b;
    }

}

public class Test {

    public static void main(String[] args) {
        Father father = new Father();
        System.out.println("100-50=" + father.subtraction(100, 50));
        System.out.println("100-80=" + father.subtraction(100, 80));
    }
}
里氏替換原則代碼運(yùn)行結(jié)果1

上面就是一個(gè)很簡(jiǎn)單減法運(yùn)算吕晌,現(xiàn)在我們需要增加一個(gè)新的功能,完成兩數(shù)相加临燃,然后再與100求和睛驳,由類Sun來(lái)負(fù)責(zé)。

public class Sun extends Father {

    @Override
    public int subtraction(int a, int b) {
        return a + b;
    }

    public int addition(int a, int b) {
        //重寫后subtraction(a,b)改為a+b
        return subtraction(a, b) + 100;
    }

}

public class Test {

    public static void main(String[] args) {
        Sun sun = new Sun();
        System.out.println("100-50="+sun.subtraction(100, 50));
        System.out.println("100-80="+sun.subtraction(100, 80));
        System.out.println("100+20+100="+sun.addition(100, 20));
    }
}
里氏替換原則代碼運(yùn)行結(jié)果2

我們發(fā)現(xiàn)原本運(yùn)行正常的相減功能發(fā)生了錯(cuò)誤膜廊。原因就是類Sun在給方法起名時(shí)無(wú)意中重寫了父類的方法乏沸,造成所有運(yùn)行相減功能的代碼全部調(diào)用了類Sun重寫后的方法,造成原本運(yùn)行正常的功能出現(xiàn)了錯(cuò)誤爪瓜。在本例中蹬跃,引用基類Father完成的功能,換成子類Sun之后铆铆,發(fā)生了異常蝶缀。在實(shí)際編程中,我們常常會(huì)通過(guò)重寫父類的方法來(lái)完成新的功能薄货,這樣寫起來(lái)雖然簡(jiǎn)單翁都,但是整個(gè)繼承體系的可復(fù)用性會(huì)比較差,特別是運(yùn)用多態(tài)比較頻繁時(shí)菲驴,程序運(yùn)行出錯(cuò)的幾率非常大荐吵。如果非要重寫父類的方法骑冗,比較通用的做法是:原來(lái)的父類和子類都繼承一個(gè)更通俗的基類赊瞬,原有的繼承關(guān)系去掉先煎,采用依賴、聚合巧涧,組合等關(guān)系代替薯蝎。

7. 合成復(fù)用原則(Composite Reuse Principle)

  • 定義:盡量使用對(duì)象組合/聚合,而不是使用繼承關(guān)系來(lái)達(dá)到軟件復(fù)用的目的谤绳。

  • 優(yōu)點(diǎn):可以使系統(tǒng)更加的靈活占锯,降低類與類之間的耦合度,一個(gè)類的變化對(duì)其他類造成的影響相對(duì)較少缩筛。

代碼舉例:

//定義接口
public abstract class DBConnection {

    public abstract String getConnection();
}

//實(shí)現(xiàn)接口類
public class MySQLConnection extends DBConnection {
    @Override
    public String getConnection() {
        return "MySQL數(shù)據(jù)庫(kù)連接";
    }
}

public class PostgreSQLConnection extends DBConnection {
    @Override
    public String getConnection() {
        return "PostgreSQL數(shù)據(jù)庫(kù)連接";
    }
}
public class ProductDao{

    private DBConnection dbConnection;

    public void setDbConnection(DBConnection dbConnection) {
        this.dbConnection = dbConnection;
    }

    public void addProduct(){
        String conn = dbConnection.getConnection();
        System.out.println("使用"+conn+"增加產(chǎn)品");
    }
}

public class Test {
    public static void main(String[] args) {
        ProductDao productDao = new ProductDao();
        productDao.setDbConnection(new PostgreSQLConnection());
        productDao.addProduct();
    }
}

從代碼就可以看出消略,通過(guò)ProductDao類注入你需要的對(duì)象,就能實(shí)現(xiàn)不同的業(yè)務(wù)邏輯瞎抛,通過(guò)setDbConnection()就可以實(shí)現(xiàn)對(duì)象的組合和復(fù)用艺演,當(dāng)然也可以通過(guò)構(gòu)造方法來(lái)進(jìn)行,而以后我們?nèi)绻黾赢a(chǎn)品的話桐臊,只需要寫一個(gè)和MySQLConnection類一樣平級(jí)的類胎撤,繼承DBConnection接口,具體的選擇就可以額交給客戶端就好了断凶。

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末伤提,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子认烁,更是在濱河造成了極大的恐慌肿男,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件却嗡,死亡現(xiàn)場(chǎng)離奇詭異次伶,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)稽穆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門冠王,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人舌镶,你說(shuō)我怎么就攤上這事柱彻。” “怎么了餐胀?”我有些...
    開封第一講書人閱讀 157,435評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵哟楷,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我否灾,道長(zhǎng)卖擅,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,509評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮惩阶,結(jié)果婚禮上挎狸,老公的妹妹穿的比我還像新娘。我一直安慰自己断楷,他們只是感情好锨匆,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,611評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著冬筒,像睡著了一般恐锣。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上舞痰,一...
    開封第一講書人閱讀 49,837評(píng)論 1 290
  • 那天土榴,我揣著相機(jī)與錄音,去河邊找鬼响牛。 笑死鞭衩,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的娃善。 我是一名探鬼主播论衍,決...
    沈念sama閱讀 38,987評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼聚磺!你這毒婦竟也來(lái)了坯台?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,730評(píng)論 0 267
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤瘫寝,失蹤者是張志新(化名)和其女友劉穎蜒蕾,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體焕阿,經(jīng)...
    沈念sama閱讀 44,194評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡咪啡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,525評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了暮屡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片撤摸。...
    茶點(diǎn)故事閱讀 38,664評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖褒纲,靈堂內(nèi)的尸體忽然破棺而出准夷,到底是詐尸還是另有隱情,我是刑警寧澤莺掠,帶...
    沈念sama閱讀 34,334評(píng)論 4 330
  • 正文 年R本政府宣布衫嵌,位于F島的核電站,受9級(jí)特大地震影響彻秆,放射性物質(zhì)發(fā)生泄漏楔绞。R本人自食惡果不足惜结闸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,944評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望酒朵。 院中可真熱鬧桦锄,春花似錦、人聲如沸耻讽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,764評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)针肥。三九已至,卻和暖如春香伴,著一層夾襖步出監(jiān)牢的瞬間慰枕,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,997評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工即纲, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留具帮,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,389評(píng)論 2 360
  • 正文 我出身青樓低斋,卻偏偏與公主長(zhǎng)得像蜂厅,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子膊畴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,554評(píng)論 2 349

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

  • 本文集網(wǎng)絡(luò)上文章及自己coding和理解的結(jié)果而來(lái)掘猿,是設(shè)計(jì)模式學(xué)習(xí)的開篇。 本文介紹設(shè)計(jì)模式的一些概念唇跨,分類稠通,和設(shè)...
    月落蝶殤閱讀 497評(píng)論 0 0
  • 1、單一職能原則(Single Responsibility Principle, SRP) 定義 There s...
    tianranll閱讀 704評(píng)論 0 1
  • 軟件開發(fā)是始于面向過(guò)程的 軟件開發(fā)是始于面向過(guò)程的买猖,因?yàn)槊嫦蜻^(guò)程地解決問(wèn)題更直接改橘,軟件本身就是一個(gè)解決問(wèn)題的過(guò)程;...
    侏羅紀(jì)猿閱讀 755評(píng)論 0 2
  • 設(shè)計(jì)模式6大原則 轉(zhuǎn)自:http://www.cnblogs.com/devinzhang/archive/201...
    犀利的小眼神閱讀 430評(píng)論 0 1
  • 每天早上梳洗打扮這段時(shí)間玉控,總會(huì)聽點(diǎn)羅胖的“邏輯思維”飞主,這樣才覺得不虛度光陰吧。 有一句沒(méi)一句的聽著高诺,總會(huì)有那么兩個(gè)...
    每日一智閱讀 774評(píng)論 0 2