設計模式

創建型模式

Factory--工廠模式

簡單工廠模式

創建工廠對象,然后通過條件獲取相應的對象,這種方式健壯性差,如果輸入的條件字符串不符合要求則不能獲取到相應的對象。

interface Pet {
    public void eat();
}

class Dog implements Pet {

    @Override
    public void eat() {
        System.out.print("Dog is eat");
    }
}

class Cat implements Pet {

    @Override
    public void eat() {
        System.out.print("Cat is eat");
    }
}

class PetFactory {
    public Pet getPet(String name) {
        if(name.equals("Dog")) {
            return new Dog();
        }else if (name.equals("Cat")) {
            return new Cat();
        }else {
            // 條件都不符合,創建默認對象
            return new Dog();
        }
    }
}

public class FactoryModel {
    public static void main(String[] args) {
        PetFactory petFactory = new PetFactory();
        Pet dog = petFactory.getPet("Dog");
        dog.eat();
    }
}

對普通工廠方法模式的改進,在普通工廠方法模式中,如果傳遞的字符串出錯,則不能正確創建對象,提供多個工廠方法,分別創建對象。

interface Pet {
    public void eat();
}

class Dog implements Pet {

    @Override
    public void eat() {
        System.out.print("Dog is eat");
    }
}

class Cat implements Pet {

    @Override
    public void eat() {
        System.out.print("Cat is eat");
    }
}

class PetFactory {
    public Pet getDog() {
        return new Dog();
    }

    public Pet getCat() {
        return new Cat();
    }
}

public class FactoryModel {
    public static void main(String[] args) {
        PetFactory petFactory = new PetFactory();
        Pet dog = petFactory.getDog();
        dog.eat();
    }
}
多個工廠方法模式

有時需要新增一個或多個種類,例如新加一個Bird動物,可實現動物接口,以及實現工廠類,這樣就不需要去修改其他的接口了。

interface Pet {
    public void eat();
}

class Dog implements Pet {

    @Override
    public void eat() {
        System.out.print("Dog is eat");
    }
}

class Cat implements Pet {

    @Override
    public void eat() {
        System.out.print("Cat is eat");
    }
}

interface Factory {
    public Pet produce();
}

class DogFactory implements Factory {

    @Override
    public Pet produce() {
        return new Dog();
    }
}

class CatFactory implements Factory {

    @Override
    public Pet produce() {
        return new Cat();
    }
}

public class AbstractFactoryModel {
    public static void main(String[] args) {
        Factory factory = new DogFactory();
        Pet dog = factory.produce();
        dog.eat();
    }
}

AbstractFactory--抽象工廠模式

抽象工廠模式中彌補了工廠模式的不足(一個工廠只能生產一種產品)。工廠模式中一個工廠只能生產一種產品,而抽象工廠可以生產多個。

package AbstractFactoryModel;

interface Pet {
    public void eat();
}

interface Dog extends Pet {
}

interface Cat extends Pet{
}

class ChinaDog implements Dog {

    @Override
    public void eat() {
        System.out.println("China dog is eat...");
    }
}

class ForeignDog implements Cat {

    @Override
    public void eat() {
        System.out.println("Foreign dog is eat...");
    }
}

class ChinaCat implements Cat {

    @Override
    public void eat() {
        System.out.println("China cat is eat...");
    }
}

class ForeignCat implements Cat {

    @Override
    public void eat() {
        System.out.println("Foreign cat is eat...");
    }
}

interface PetFactory {
    public Pet produceDog();
    public Pet produceCat();
}

class ChinaFactory implements PetFactory {

    @Override
    public Pet produceDog() {
        return new ChinaDog();
    }

    @Override
    public Pet produceCat() {
        return new ChinaCat();
    }
}

class ForeignFactory implements PetFactory {

    @Override
    public Pet produceDog() {
        return new ForeignDog();
    }

    @Override
    public Pet produceCat() {
        return new ForeignCat();
    }
}

public class AbstractFactoryModel {
    public static void main(String[] args) {
        PetFactory chinaFactory = new ChinaFactory();
        Pet dog = chinaFactory.produceDog();
        dog.eat();
    }
}

Singleton--單例模式

單例對象能保證在一個JVM中,該對象只有一個實例存在。

餓漢模式

直接創建該對象,不是懶加載。

class SingletonModel {
    private static SingletonModel singleton = new SingletonModel();

    private SingletonModel() {

    }

    public static SingletonModel getInstance() {
        return singleton;
    }
}


public class HungarySingletonModel {
    public static void main(String[] args) {
        SingletonModel instance = SingletonModel.getInstance();
    }
}
懶漢模式

只有需要用到該對象才創建。使用雙重檢查鎖機制。在還沒有該對象的時候,第一次判斷為空,此時可能會有多個線程進入到這,也就是說多個線程都判斷為空成立,此時某個線程獲得鎖資源,待該線程釋放鎖,會有下一個線程獲得鎖資源,如果不再次判斷是否為空,則之后的線程會再次創建對象,此時第一個獲得鎖資源的線程已經創建了對象,則再次判斷可以避免再次創建對象。

class SingletonModel {
    private static SingletonModel singleton = null;

    private SingletonModel() {

    }

    public static SingletonModel getInstance() {
        if (singleton == null) {
            synchronized (singleton) {
                if (singleton == null) {
                    singleton = new SingletonModel();
                }
            }
        }
        return singleton;
    }
}

public class LazySingletonModel {
    public static void main(String[] args) {
        SingletonModel instance = SingletonModel.getInstance();
    }
}

Builder--建造者模式

將一個復雜對象的構建與它的屬性分離,使得同樣的構建過程可以創建不同的屬性。
目的是將構建復雜對象的過程和它的屬性解耦。
類比房子,房子是個對象,而屋頂和地基都是房子的屬性,而建造屋頂和地基都有單獨的方法實現。
工廠模式關注的是創建單個產品,而建造者模式則關注創建復雜的對象,包含多個部分。

class House {
    private String roof;
    private String foundation;

    public String getRoof() {
        return roof;
    }

    public void setRoof(String roof) {
        this.roof = roof;
    }

    public String getFoundation() {
        return foundation;
    }

    public void setFoundation(String foundation) {
        this.foundation = foundation;
    }
}

interface Builder {
    void buildRoof();
    void buildFoundation();
    House createHouse();
}

class HouseBuilder implements Builder {
    private House house;

    public HouseBuilder(House house) {
        this.house = house;
    }

    @Override
    public void buildRoof() {
        this.house.setRoof("roof");
    }

    @Override
    public void buildFoundation() {
        this.house.setFoundation("foundation");
    }

    @Override
    public House createHouse() {
        return this.house;
    }


}
class Director {
    private Builder builder;

    public Director(Builder builder) {
        this.builder = builder;
    }

    public House construct() {
        builder.buildRoof();
        builder.buildFoundation();
        return builder.createHouse();
    }

}

public class BuilderModel {
    public static void main(String[] args) {
        House house = new House();
        Builder builder = new HouseBuilder(house);
        Director director = new Director(builder);
        house = director.construct();
        System.out.println(house);
    }
}

Prototype--原型模式

定義:用原型實例通過拷貝創建新的對象。Prototype模式允許一個對象再創建另外一個可定制的對象,根部無需知道任何創建的細節,工作原理:通過將一個原型對象傳給創建方法,從而通過對原型對象的拷貝來創建新的對象。

淺復制
class Pet implements Cloneable{
    private String name;
    private int age;

    public Pet(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

public class PrototypeModel {
    public static void main(String[] args) {
        Pet pet = new Pet("Tom", 1);
        System.out.println("Pet'address is " + pet.toString());

        try {
            Pet clone_pet = (Pet) pet.clone();
            System.out.println("Clone pet'address is " + clone_pet.toString());

        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}
深復制
package PrototypeModel;

import java.io.*;

class Dog implements Serializable{
    private String name;
    private int age;

    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void introduce() {
        System.out.println(this.name + "'age is " + this.age);
    }

    public Dog clone() {
        try {
            // 創建一個字節數組輸出流用來保存序列化后對象的字節
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            // 創建一個對象輸出流
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
            // 將對象寫出到之前創建的字節輸出流中
            objectOutputStream.writeObject(this);
            // 將字節數組輸出流轉化為字節數組
            byte[] bytes = byteArrayOutputStream.toByteArray();

            // 創建一個字節輸入流,將上面的對象字節寫入到流中
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
            // 創建一個對象輸入流,將字節輸入流包裝
            ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
            // 從流中將對象寫出來,強轉為該對象類型
            Dog dog = (Dog) objectInputStream.readObject();
            return dog;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

public class DeepPrototypeModel {
    public static void main(String[] args) {
        Dog dog = new Dog("Tom", 2);
        dog.introduce();
        System.out.println(dog.toString());
        Dog cloneDog = dog.clone();
        cloneDog.introduce();
        System.out.println(cloneDog.toString());
    }
}

結構型模式

Adapter--適配器模式

類適配器

通過繼承來實現適配器功能

interface Usb {
    void isUsb();
}

interface Ps2 {
    void isPs2();
}

class Usber implements Usb {

    @Override
    public void isUsb() {
        System.out.println("Usb接口");
    }
}

class Adapter extends Usber implements Ps2 {

    @Override
    public void isPs2() {
        System.out.println("Ps2接口");
    }
}

public class ClassAdapter {
    public static void main(String[] args) {
        Adapter p = new Adapter();
        p.isPs2();
        p.isUsb();
    }
}

對象適配器

通過對象實例來實現適配器功能

interface Usb {
    void isUsb();
}

interface Ps2 {
    void isPs2();
}

class Usber implements Usb {

    @Override
    public void isUsb() {
        System.out.println("Usb接口");
    }
}

class Adapter implements Ps2 {
    private Usber usb;

    public Adapter(Usber usb) {
        this.usb = usb;
    }

    @Override
    public void isPs2() {
        System.out.println("Ps2接口");
    }

    public void isUsb() {
        this.usb.isUsb();
    }
}

public class ObjectAdapter {
    public static void main(String[] args) {
        Adapter adapter = new Adapter(new Usber());
        adapter.isPs2();
        adapter.isUsb();
    }
}

接口適配器

如果需要定義一個類,且只需要接口中部分方法,可以使用抽象類去實現接口,然后使用該類去繼承抽象類,就可以去重寫部分方法了。

interface People {
    void eat();
    void run();
}

abstract class Adapter implements People {
    @Override
    public void eat() {

    }

    @Override
    public void run() {

    }
}

class Baby extends Adapter {
    @Override
    public void eat() {
        System.out.println("I can eat!");
    }
}

class InterfaceAdapterModel {
    public static void main(String[] args) {
        Baby baby = new Baby();
        baby.eat();
    }
}

Bridge--橋接模式

橋接模式就是把事物和其具體實現分開,使他們可以各自獨立的變化。像常用的JDBC橋DriverManager一樣,JDBC進行連接數據庫的時候,在各個數據庫之間進行切換。

interface JDBC {
    void connect();
}

class mysql implements JDBC {

    @Override
    public void connect() {
        System.out.println("connect mysql...");
    }
}

class oracle implements JDBC {

    @Override
    public void connect() {
        System.out.println("connect oracle...");
    }
}

abstract class Bridge {
    private JDBC jdbc;

    public void connect() {
        jdbc.connect();
    }

    public JDBC getJdbc() {
        return jdbc;
    }

    public void setJdbc(JDBC jdbc) {
        this.jdbc = jdbc;
    }
}

class MyBridge extends Bridge {
    @Override
    public void connect() {
        super.connect();
    }
}

public class BridgeModel {
    public static void main(String[] args) {
        Bridge bridge = new MyBridge();

        JDBC jdbc = new mysql();
        bridge.setJdbc(jdbc);
        bridge.connect();

        JDBC oracle = new oracle();
        bridge.setJdbc(oracle);
        bridge.connect();
    }
}

Composite--組合模式

將對象以樹形組織起來,以達成“部分-整體”的層次結構,使得客戶端對單個對象 和組合對象的使用具有一致性。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,837評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,196評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,688評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,654評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,456評論 6 406
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,955評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,044評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,195評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,725評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,608評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,802評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,318評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,048評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,422評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,673評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,424評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,762評論 2 372

推薦閱讀更多精彩內容

  • 清晨,拉開窗簾想看看預報中的重度霧霾,卻被眼前的景色驚呆了~屋頂、地面被一層白雪覆蓋了,更難以想象的是樓前的樹枝變...
    槑頭槑腦兒閱讀 336評論 0 2
  • Hello, everyone. Long time no see. Today, weshare some En...
    Game0ver閱讀 433評論 1 3
  • 好久未聯系的同學今天聊了起來 聊了很多 大家都非常想念彼此,我有時候做夢都會夢到以前高中時,真的很美好,現在想起來...
    Rose啊閱讀 114評論 0 1