Java中面向?qū)ο笏枷朐O(shè)計(jì)原則、設(shè)計(jì)模式、簡單工廠模式竭缝、工廠方法模式房维、單例設(shè)計(jì)模式之餓漢式和懶漢式、Runtime類

面向?qū)ο笏枷朐O(shè)計(jì)原則

在實(shí)際的開發(fā)中抬纸,我們要想更深入的了解面向?qū)ο笏枷肓捅仨毷煜で叭丝偨Y(jié)過的面向?qū)ο蟮乃枷氲脑O(shè)計(jì)原則,那么都有哪些原則呢湿故,我們就來了解一下

  • 單一職責(zé)原則
    • 其實(shí)就是開發(fā)人員經(jīng)常說的”高內(nèi)聚阿趁,低耦合”
  • 開閉原則
    • 核心思想是:一個對象對擴(kuò)展開放,對修改關(guān)閉坛猪。其實(shí)開閉原則的意思就是:對類的改動是通過增加代碼進(jìn)行的脖阵,而不是修改現(xiàn)有代碼。
  • 里氏替換原則
    • 核心思想:在任何父類出現(xiàn)的地方都可以用它的子類來替代墅茉。其實(shí)就是說:同一個繼承體系中的對象應(yīng)該有共同的行為特征命黔。
  • 依賴注入原則
    • 核心思想:要依賴于抽象,不要依賴于具體實(shí)現(xiàn)就斤。
  • 接口分離原則
    • 核心思想:不應(yīng)該強(qiáng)迫程序依賴它們不需要使用的方法纷铣。
  • 迪米特原則
    • 核心思想:一個對象應(yīng)當(dāng)對其他對象盡可能少的了解

設(shè)計(jì)模式

設(shè)計(jì)模式在我們開發(fā)中還是經(jīng)常用到的,那么战转,下面我們來學(xué)習(xí)一下

  • 設(shè)計(jì)模式概述

    • 設(shè)計(jì)模式(Design pattern)是一套被反復(fù)使用搜立、多數(shù)人知曉的、經(jīng)過分類編目的槐秧、代碼設(shè)計(jì)經(jīng)驗(yàn)的總結(jié)啄踊。使用設(shè)計(jì)模式是為了可重用代碼、讓代碼更容易被他人理解刁标、保證代碼可靠性颠通。
  • 設(shè)計(jì)模式不是一種方法和技術(shù),而是一種思想
    設(shè)計(jì)模式和具體的語言無關(guān)膀懈,學(xué)習(xí)設(shè)計(jì)模式就是要建立面向?qū)ο蟮乃枷攵倜蹋M可能的面向接口編程,低耦合启搂,高內(nèi)聚硼控,使設(shè)計(jì)的程序可復(fù)用

  • 學(xué)習(xí)設(shè)計(jì)模式能夠促進(jìn)對面向?qū)ο笏枷氲睦斫猓粗嗳桓於摹K鼈兿噍o相成

  • 設(shè)計(jì)模式的幾個要素:

  • 名字 必須有一個簡單牢撼,有意義的名字

  • 問題 描述在何時使用模式

  • 解決方案 描述設(shè)計(jì)的組成部分以及如何解決問題

  • 效果 描述模式的效果以及優(yōu)缺點(diǎn)

  • 設(shè)計(jì)模式的分類

  • 創(chuàng)建型模式 對象的創(chuàng)建

  • 結(jié)構(gòu)型模式 對象的組成(結(jié)構(gòu))

  • 行為型模式 對象的行為

創(chuàng)建型模式:簡單工廠模式,工廠方法模式疑苫,抽象工廠模式熏版,建造者模式纷责,原型模式,單例模式撼短。(6個)結(jié)構(gòu)型模式:外觀模式再膳、適配器模式、代理模式曲横、裝飾模式喂柒、橋接模式、組合模式胜榔、享元模式。(7個)行為型模式:模版方法模式湃番、觀察者模式夭织、狀態(tài)模式、職責(zé)鏈模式吠撮、命令模式尊惰、訪問者模式、策略模式泥兰、備忘錄模式弄屡、迭代器模式、解釋器模式鞋诗。(10個)

設(shè)計(jì)模式的分類雖然很多膀捷,但是我們平時能用到的也就下面幾種而已,所以不要被它這么多模式所嚇倒削彬。

  • 常見的設(shè)計(jì)模式 簡單工廠模式和工廠方法模式(接口)
    • 模版設(shè)計(jì)模式(抽象類)
    • 裝飾設(shè)計(jì)模式(IO流)
    • 單例設(shè)計(jì)模式(多線程)
    • 適配器模式(GUI)

下面我們就來學(xué)習(xí)我們常用的幾種設(shè)計(jì)模式全庸,讓大家掌握,熟悉融痛,并運(yùn)用到自己的項(xiàng)目中壶笼,學(xué)會學(xué)以致用。

簡單工廠模式

  • 簡單工廠模式概述
    • 又叫靜態(tài)工廠方法模式雁刷,它定義一個具體的工廠類負(fù)責(zé)創(chuàng)建一些類的實(shí)例

我們來寫一個簡單的例子來解釋簡單工廠模式

/* * 抽象的動物類覆劈,里面有抽象的方法 */
public abstract class Animal { 
  public abstract void eat();
}
/* * 具體的動物貓繼承抽象動物類,重寫抽象方法 */
public class Cat extends Animal { 
@Override 
public void eat() { 
System.out.println("貓吃魚"); 
}
}
/* * 具體的動物狗繼承抽象動物類沛励,重寫抽象方法 */
public class Dog extends Animal { 
@Override 
public void eat() { 
System.out.println("狗吃肉");
 }
}
/* * 動物工廠類责语,可以造貓和狗 */
public class AnimalFactory { 
private AnimalFactory() { } 
public static Animal createAnimal(String type) {
 if ("dog".equals(type)) { 
return new Dog();
 } else if ("cat".equals(type)) { 
return new Cat();
 } else { 
return null;
 } 
}
}
/* * 測試類 */
public class AnimalDemo { 
public static void main(String[] args) { 
// 工廠有了后,通過工廠給造
 Animal a = AnimalFactory.createAnimal("dog"); 
a.eat();
 a = AnimalFactory.createAnimal("cat");
 a.eat();
 // NullPointerException 
a = AnimalFactory.createAnimal("pig");
 if (a != null) { 
a.eat();
 } else { 
System.out.println("對不起目派,暫時不提供這種動物"); 
} 
}
}

以前我們在學(xué)代碼的時候鹦筹,不會去創(chuàng)建這個動物的工廠類,而是直接具體類的調(diào)用址貌,比如:

Dog d = new Dog();
 d.eat(); 
Cat c = new Cat(); 
c.eat();  

現(xiàn)在我們運(yùn)用了簡單工廠模式后铐拐,就不用每次用的時候去new對象徘键,而是直接去調(diào)用這個工廠類里面的具體方法,它會給我們返回一個已經(jīng)new好的對象遍蟋。那么這樣做有什么有缺點(diǎn)呢吹害,我們來總結(jié)一下。

  • 優(yōu)點(diǎn)
    • 客戶端不需要在負(fù)責(zé)對象的創(chuàng)建虚青,從而明確了各個類的職責(zé)
  • 缺點(diǎn)
    • 這個靜態(tài)工廠類負(fù)責(zé)所有對象的創(chuàng)建它呀,如果有新的對象增加,或者某些對象的創(chuàng)建方式不同棒厘,就需要不斷的修改工廠類纵穿,不利于后期的維護(hù)

當(dāng)我們要用一個模式時,當(dāng)這個模式的優(yōu)點(diǎn)大于缺點(diǎn)的時候奢人,我們就可以使用了谓媒,但是在簡單工廠模式中我們可以看到它的缺點(diǎn),當(dāng)我們有新的對象增加時何乎,就要不斷的修改工廠類句惯,所以不推薦大家用簡單工廠模式,那么我們要用什么呢支救,這就引出了我們要學(xué)的下一個知識點(diǎn)工廠方法模式

工廠方法模式

  • 工廠方法模式概述
    • 工廠方法模式中抽象工廠類負(fù)責(zé)定義創(chuàng)建對象的接口抢野,具體對象的創(chuàng)建工作由繼承抽象工廠的具體類實(shí)現(xiàn)。

我們就來用工廠方法模式對上面的那個例子進(jìn)行改進(jìn)

/* * 抽象的動物類各墨,里面有抽象的方法 */
public abstract class Animal { 
public abstract void eat();
}
/* * 工廠類接口指孤,里面有抽象的創(chuàng)造動物的方法 */
public interface Factory { 
public abstract Animal createAnimal();
}
/* * 具體的貓類繼承抽象動物類,重寫抽象方法 */
public class Cat extends Animal { 
@Override 
public void eat() { 
System.out.println("貓吃魚"); 
}
}
/* * 貓工廠類實(shí)現(xiàn)工廠類并實(shí)現(xiàn)它的抽象方法贬堵,返回一個貓對象 */
public class CatFactory implements Factory { 
@Override 
public Animal createAnimal() { 
return new Cat();
 }
}
/* * 具體的狗類繼承抽象動物類邓厕,重寫抽象方法 */
public class Dog extends Animal { 
@Override 
public void eat() { 
System.out.println("狗吃肉"); 
}
}
/* * 狗工廠類實(shí)現(xiàn)工廠類并實(shí)現(xiàn)它的抽象方法,返回一個狗對象 */
public class DogFactory implements Factory { 
@Override 
public Animal createAnimal() { 
return new Dog(); 
}
}
/* * 測試類 */
public class AnimalDemo { 
public static void main(String[] args) { 
// 需求:我要買只狗 
Factory f = new DogFactory(); 
Animal a = f.createAnimal();
 a.eat(); 
//需求:我要買只貓 
f = new CatFactory(); 
a = f.createAnimal(); 
a.eat();
 }
}

運(yùn)行程序扁瓢,控制臺會輸出详恼,狗吃肉 貓吃魚
我們仔細(xì)觀察用工廠方法模式比比簡單工廠模式多了幾個類,但是當(dāng)我們在需要一種動物豬時引几,我們就不用去修改工廠類里面的代碼了昧互,只需用創(chuàng)建一個豬類繼承抽象動物類,重寫抽象方法伟桅,再創(chuàng)建一個豬的工廠類實(shí)現(xiàn)工廠類并實(shí)現(xiàn)它的抽象方法敞掘,就可以了。代碼具有很強(qiáng)的維護(hù)性和擴(kuò)展性楣铁,那么我們來分析一下工廠方法模式的優(yōu)缺點(diǎn)玖雁。

  • 優(yōu)點(diǎn)
    • 客戶端不需要在負(fù)責(zé)對象的創(chuàng)建,從而明確了各個類的職責(zé)盖腕,如果有新的對象增加赫冬,只需要增加一個具體的類和具體的工廠類即可浓镜,不影響已有的代碼,后期維護(hù)容易劲厌,增強(qiáng)了系統(tǒng)的擴(kuò)展性
  • 缺點(diǎn)
    • 需要額外的編寫代碼膛薛,增加了工作量

我們可以看到工廠方法模式的優(yōu)點(diǎn)明顯大于缺點(diǎn),所以推薦大家使用补鼻。

單例設(shè)計(jì)模式

  • 單例設(shè)計(jì)模式概述
    • 單例模式就是要確保類在內(nèi)存中只有一個對象哄啄,該實(shí)例必須自動創(chuàng)建,并且對外提供风范。

如何實(shí)現(xiàn)類在內(nèi)存中只有一個對象呢?
- 構(gòu)造私有
- 本身提供一個對象
- 通過公共的方法讓外界訪問

那么我們就來學(xué)習(xí)單例模式中餓漢式懶漢式 這兩種模式咨跌,并做以比較

餓漢式

  • 餓漢式:類一加載就創(chuàng)建對象
public class Student { 
// 構(gòu)造私有 
private Student() { } 
// 自己造一個對象 
// 靜態(tài)方法只能訪問靜態(tài)成員變量,加靜態(tài) 
// 為了不讓外界直接訪問修改這個值硼婿,加private 
private static Student s = new Student(); 
// 提供公共的訪問方式
// 為了保證外界能夠直接使用該方法锌半,加靜態(tài) 
public static Student getStudent() { return s; }}
public class StudentDemo { 
public static void main(String[] args) { 
// 通過單例得到對象
 Student s1 = Student.getStudent(); 
Student s2 = Student.getStudent(); 
System.out.println(s1 == s2); //true 
}
}

運(yùn)行程序,控制臺會輸出true加酵,說明我們用單例模式的餓漢式確保類在內(nèi)存中只有一個對象拳喻,他的特點(diǎn)就是類一加載就創(chuàng)建對象,可以在代碼中Student類中體現(xiàn)到哭当。那么我們怎樣才能在用這個對象的時候才去創(chuàng)建它呢猪腕,我們就要來看下懶漢式了。

懶漢式

  • 懶漢式:用對象的時候钦勘,才去創(chuàng)建對象
public class Teacher {
 private Teacher() { } 
private static Teacher t = null;
 public static Teacher getTeacher() {
 if (t == null) { 
t = new Teacher();//當(dāng)我們?nèi)ビ眠@個對象的時候才去創(chuàng)建它 
} 
return t; 
}
}
public class TeacherDemo { 
public static void main(String[] args) { 
Teacher t1 = Teacher.getTeacher();
 Teacher t2 = Teacher.getTeacher(); 
System.out.println(t1 == t2); //true 
}
}

單例模式的餓漢式和懶漢式是不是很容易理解呢陋葡,那么我們什么時候用餓漢式什么時候用懶漢式呢?
我們就來總結(jié)一下

餓漢式懶漢式比較

餓漢式我們經(jīng)常在開發(fā)中使用彻采,因?yàn)轲I漢式是不會出問題的單例模式
懶漢式我們在面試中回答用腐缤,因?yàn)閼袧h式可能會出問題的單例模式。面試主要面兩個思想肛响,分別是:

  • 懶加載思想(延遲加載)
  • 線程安全問題(就要考慮下面3個方面)
    • 是否多線程環(huán)境
    • b:是否有共享數(shù)據(jù)
    • c:是否有多條語句操作共享數(shù)據(jù)
      如果都是岭粤,就會存在線程的安全問題,我們上面的懶漢式代碼是不完整的特笋,應(yīng)該給對象中的方法加上synchronized關(guān)鍵字剃浇,這樣才算完整
public synchronized static Teacher getTeacher() { 
    if (t == null) { 
        t = new Teacher(); 
    } 
    return t;
}

Runtime類

我們在這里為什么要說Runtime類,因?yàn)樗趈ava中的設(shè)計(jì)就是按照單例模式之餓漢式設(shè)計(jì)的猎物,我們來看一段源碼

class Runtime { 
private Runtime() {} 
private static Runtime currentRuntime = new Runtime(); 
public static Runtime getRuntime() { 
return currentRuntime; 
}
}
  • 每個 Java 應(yīng)用程序都有一個 Runtime 類實(shí)例虎囚,使應(yīng)用程序能夠與其運(yùn)行的環(huán)境相連接∧枘ィ可以通過 getRuntime 方法獲取當(dāng)前運(yùn)行時淘讥。
  • 應(yīng)用程序不能創(chuàng)建自己的 Runtime 類實(shí)例。
  • Runtime類使用
    • public Process exec(String command)

這個類是用來干什么的呢堤如,它可以幫助我們運(yùn)行DOS命令蒲列,比如打開記事本窒朋、計(jì)算器之類的電腦工具,當(dāng)然也有更多的功能嫉嘀,我們來體驗(yàn)一下

public class RuntimeDemo { 
public static void main(String[] args) throws IOException { 
Runtime r = Runtime.getRuntime(); 
r.exec("notepad"); 
}
}

運(yùn)行程序會幫我們打開記事本

r.exec("calc"); //換成calc炼邀,會幫我們打開計(jì)算機(jī)
r.exec("shutdown -s -t 1000");  // 這個命令會幫我們把電腦定時關(guān)機(jī),上面的意思就是1000秒以后關(guān)機(jī)剪侮,我們來看運(yùn)行后的效果圖 

模版設(shè)計(jì)模式

  • 模版設(shè)計(jì)模式概述
    • 模版方法模式就是定義一個算法的骨架拭宁,而將具體的算法延遲到子類中來實(shí)現(xiàn)
  • 優(yōu)點(diǎn)
    • 使用模版方法模式,在定義算法骨架的同時瓣俯,可以很靈活的實(shí)現(xiàn)具體的算法杰标,滿足用戶靈活多變的需求
  • 缺點(diǎn)
    • 如果算法骨架有修改的話,則需要修改抽象類

我們可以在計(jì)算程序的運(yùn)行時間中應(yīng)用模版設(shè)計(jì)模式彩匕,在代碼中我們只需用改變要計(jì)算的代碼就可以了腔剂,把計(jì)算的時間設(shè)計(jì)成一個模版。

裝飾設(shè)計(jì)模式

  • 裝飾設(shè)計(jì)模式概述

    • 裝飾模式就是使用被裝飾類的一個子類的實(shí)例驼仪,在客戶端將這個子類的實(shí)例交給裝飾類掸犬。是繼承的替代方案
  • 優(yōu)點(diǎn)

    • 使用裝飾模式,可以提供比繼承更靈活的擴(kuò)展對象的功能绪爸,它可以動態(tài)的添加對象的功能湾碎,并且可以隨意的組合這些功能
  • 缺點(diǎn)

    • 正因?yàn)榭梢噪S意組合,所以就可能出現(xiàn)一些不合理的邏輯
  • 在IO流中的裝飾模式應(yīng)用

BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
BufferedWriter bw = new BufferedWriter((new OutputStreamWriter(System.out)));
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末奠货,一起剝皮案震驚了整個濱河市介褥,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌递惋,老刑警劉巖柔滔,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異萍虽,居然都是意外死亡睛廊,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門杉编,熙熙樓的掌柜王于貴愁眉苦臉地迎上來超全,“玉大人,你說我怎么就攤上這事王财÷延兀” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵绒净,是天一觀的道長见咒。 經(jīng)常有香客問我,道長挂疆,這世上最難降的妖魔是什么改览? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任下翎,我火速辦了婚禮,結(jié)果婚禮上宝当,老公的妹妹穿的比我還像新娘视事。我一直安慰自己,他們只是感情好庆揩,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布俐东。 她就那樣靜靜地躺著,像睡著了一般订晌。 火紅的嫁衣襯著肌膚如雪虏辫。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天锈拨,我揣著相機(jī)與錄音砌庄,去河邊找鬼。 笑死奕枢,一個胖子當(dāng)著我的面吹牛娄昆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播缝彬,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼萌焰,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了跌造?” 一聲冷哼從身側(cè)響起杆怕,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤族购,失蹤者是張志新(化名)和其女友劉穎壳贪,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體寝杖,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡违施,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了瑟幕。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片磕蒲。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖只盹,靈堂內(nèi)的尸體忽然破棺而出辣往,到底是詐尸還是另有隱情,我是刑警寧澤殖卑,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布站削,位于F島的核電站,受9級特大地震影響孵稽,放射性物質(zhì)發(fā)生泄漏许起。R本人自食惡果不足惜十偶,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望园细。 院中可真熱鬧惦积,春花似錦、人聲如沸猛频。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鹿寻。三九已至厉亏,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間烈和,已是汗流浹背爱只。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留招刹,地道東北人恬试。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像疯暑,于是被迫代替她去往敵國和親训柴。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345

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

  • 設(shè)計(jì)模式匯總 一妇拯、基礎(chǔ)知識 1. 設(shè)計(jì)模式概述 定義:設(shè)計(jì)模式(Design Pattern)是一套被反復(fù)使用幻馁、多...
    MinoyJet閱讀 3,903評論 1 15
  • 1 單例模式的動機(jī) 對于一個軟件系統(tǒng)的某些類而言,我們無須創(chuàng)建多個實(shí)例越锈。舉個大家都熟知的例子——Windows任務(wù)...
    justCode_閱讀 1,431評論 2 9
  • 一仗嗦、設(shè)計(jì)模式的分類 總體來說設(shè)計(jì)模式分為三大類: 創(chuàng)建型模式,共五種:工廠方法模式甘凭、抽象工廠模式稀拐、單例模式、建造者...
    RamboLI閱讀 744評論 0 1
  • CAReplicatorLayer是一個Layer容器丹弱,添加到容器上的子Layer可以復(fù)制若干份德撬;可以設(shè)定子Lay...
    怪小喵閱讀 5,172評論 1 17
  • 下午的心理學(xué)課程臨時改成了一場沙龍蜓洪。由師從德國海靈格大師的崔老師來為我們主持。 這場沙龍的主題叫做“愛的序位”坯苹,主...
    銳博Reborn閱讀 303評論 0 0