GOF23(java設(shè)計(jì)模式)--創(chuàng)建型模式

單例模式闸天、簡單工廠模式、工廠方法模式斜做、抽象工廠模式苞氮、建造者模式、原型模式

一瓤逼、單例模式
作用:保證一個(gè)類只有一個(gè)實(shí)例笼吟,并且提供一個(gè)訪問該實(shí)例的全局訪問點(diǎn)。
五種寫法:餓漢模式抛姑、懶漢模式赞厕、雙重檢測鎖、靜態(tài)內(nèi)部類實(shí)現(xiàn)延遲加載定硝、枚舉類實(shí)現(xiàn)單例(不細(xì)講了,具體參考我的另一篇文章http://www.reibang.com/p/e86833bee429
二毫目、簡單工廠模式
2.1蔬啡、作用:用來生產(chǎn)同一等級(jí)結(jié)構(gòu)中的任意產(chǎn)品诲侮。(對于增加新的產(chǎn)品,需要修改已有代碼)
2.2箱蟆、缺點(diǎn):對于增加新產(chǎn)品無能為力沟绪!不修改代碼的話,是無法擴(kuò)展的空猜,不完全滿足開閉原則(如下面的例子绽慈,如果再增加華為電腦,則必須修改工廠類的代碼)
2.3辈毯、UML圖:

簡單工廠模式.png

2.4坝疼、示例:

//電腦接口
public interface Computer {
    public void play();
}
//聯(lián)想電腦類
class LenovoComputer implements Computer{
    public void play() {
        System.out.println("我是聯(lián)想電腦");
    }
}
//蘋果電腦類
class MacComputer implements Computer{
    public void play() {
        System.out.println("我是蘋果電腦");
    }
}
--------------------------------------------------------------------------------
//簡單工廠類,類方法一般為靜態(tài)的谆沃,所以也稱為靜態(tài)工廠
public class SimpleFactory {
    public static Computer createComputer(String type){
        if(type.equalsIgnoreCase("mac")){
            return new MacComputer();
        }else{
            return new LenovoComputer();
        }
    }
    
    public static Computer createLenovoComputer(){
        return new LenovoComputer();
    }
    
    public static Computer createMacComputer(){
        return new MacComputer();
    }
}
--------------------------------------------------------------------------------
//客戶端
public class Client {
    public static void main(String[] args) {
        SimpleFactory simpleFactory = new SimpleFactory();
        Computer c1 = simpleFactory.createComputer("mac");
        Computer c2 = simpleFactory.createLenovoComputer();
        c1.play();
        c2.play();
    }
}

三钝凶、工廠方法模式
3.1、作用:為了避免簡單工廠模式的缺點(diǎn)唁影,不完全滿足開閉原則耕陷,而設(shè)計(jì)的。工廠方法模式和簡單工廠模式最大的不同在于据沈,簡單工廠模式只有一個(gè)(對于一個(gè)項(xiàng)目或者一個(gè)獨(dú)立模塊而言)工廠類哟沫,而工廠方法模式有一組實(shí)現(xiàn)了相同接口的工廠類
3.2、缺點(diǎn):除了是滿足開閉原則外锌介,從結(jié)構(gòu)復(fù)雜度南用、代碼復(fù)雜的、客戶端編程難度掏湾、管理上的難度上看裹虫,工廠方法相比簡單工廠都要復(fù)雜,所以實(shí)際上融击,我們一般只會(huì)用簡單工廠筑公,很少會(huì)用到工廠方法模式
3.3、UML圖:


工廠方法模式.png

3.4尊浪、示例:

//電腦接口
public interface Computer {
    public void play();
}
//聯(lián)想電腦類
class LenovoComputer implements Computer{
    public void play() {
        System.out.println("我是聯(lián)想電腦");
    }
}
//蘋果電腦類
class MacComputer implements Computer{
    public void play() {
        System.out.println("我是蘋果電腦");
    }
}
--------------------------------------------------------------------------------
//工廠接口
public interface FactoryMethod {
    public Computer createComputer();
}
//聯(lián)想工廠
class LenovoComputerFactory implements FactoryMethod{
    public Computer createComputer() {
        return new LenovoComputer();
    }
}
//蘋果工廠
class MacComputerFactory implements FactoryMethod{
    public Computer createComputer() {
        return new MacComputer();
    }
}
--------------------------------------------------------------------------------
//客戶端
public class Client {
    public static void main(String[] args) {
        FactoryMethod factory1  = new LenovoComputerFactory();
        FactoryMethod factory2  = new MacComputerFactory();
        LenovoComputer c1 = (LenovoComputer) factory1.createComputer();
        MacComputer c2 = (MacComputer) factory2.createComputer();
        c1.play();
        c2.play();
    }
}

結(jié)論:由此看出匣屡,如果再加入一個(gè)華為的電腦,只需加入一個(gè)華為電腦的類和一個(gè)華為電腦工廠就可以了拇涤,不需要修改之前的任何代碼捣作,因此滿足了開閉原則

四、抽象工廠模式
4.1鹅士、作用:用來生產(chǎn)不同產(chǎn)品族的全部產(chǎn)品券躁,在有多個(gè)業(yè)務(wù)品種、業(yè)務(wù)分類時(shí),通過抽象工廠模式產(chǎn)生需要的對象是一種非常好的解決方式也拜。
4.2以舒、缺點(diǎn):對于增加新的產(chǎn)品,無能為力慢哈;支持增加產(chǎn)品族(如在下面例子中蔓钟,若再加入華為電腦,則需要新增華為電腦工廠類卵贱,并要修改每一個(gè)配件類滥沫,去新增產(chǎn)品配件,因此就不能滿足開閉原則了)
4.3键俱、UML圖:


抽象工廠模式.png

4.4兰绣、示例:

//電腦類
public class Computer {
    private Engine engine;
    private Keyboard keyboard;
    private Mouse mouse;
    public Engine getEngine() {
        return engine;
    }
    public void setEngine(Engine engine) {
        this.engine = engine;
    }
    public Keyboard getKeyboard() {
        return keyboard;
    }
    public void setKeyboard(Keyboard keyboard) {
        this.keyboard = keyboard;
    }
    public Mouse getMouse() {
        return mouse;
    }
    public void setMouse(Mouse mouse) {
        this.mouse = mouse;
    }
    public void play(){
        System.out.println(engine.getName()+keyboard.getName()+mouse.getName());
    };
}
//引擎類(為了簡潔,此處沒有用到接口方妖,直接用名字代表不同的對象)
class Engine{
    private String name;
    public Engine(String name){this.name=name;}
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
//鍵盤類(為了簡潔狭魂,此處沒有用到接口,直接用名字代表不同的對象)
class Keyboard{
    private String name;
    public Keyboard(String name){this.name=name;}
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
//鼠標(biāo)類(為了簡潔党觅,此處沒有用到接口雌澄,直接用名字代表不同的對象)
class Mouse{
    private String name;
    public Mouse(String name){this.name=name;}
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
--------------------------------------------------------------------------------
//抽象工廠接口
public interface AbstractFactory {
    public Computer createComputer();
}
//聯(lián)想電腦工廠
class LenovoComputerFactory implements AbstractFactory{
    public Computer createComputer() {
        Computer c = new Computer();
        c.setEngine(new Engine("聯(lián)想CPU"));
        c.setKeyboard(new Keyboard("聯(lián)想鍵盤"));
        c.setMouse(new Mouse("聯(lián)想鼠標(biāo)"));
        return c;
    }
}
//蘋果電腦工廠
class MacComputerFactory implements AbstractFactory{
    public Computer createComputer() {
        Computer c = new Computer();
        c.setEngine(new Engine("蘋果CPU"));
        c.setKeyboard(new Keyboard("蘋果鍵盤"));
        c.setMouse(new Mouse("蘋果鼠標(biāo)"));
        return c;
    }
}
--------------------------------------------------------------------------------
//客戶端
public class Client {
    public static void main(String[] args) {
        AbstractFactory Lenovofactory = new LenovoComputerFactory();
        AbstractFactory Macfactory = new MacComputerFactory();
        Computer LenovoComputer = Lenovofactory.createComputer();
        Computer MacComputer = Macfactory.createComputer();
        LenovoComputer.play();
        MacComputer.play();
    }
}

五、建造者模式
5.1杯瞻、作用:分離了對象子組件的單獨(dú)構(gòu)造(由Builder來負(fù)責(zé))和裝配(由Director負(fù)責(zé))镐牺。 從而可以構(gòu)造出復(fù)雜的對象。這個(gè)模式適用于:某個(gè)對象的構(gòu)建過程復(fù)雜的情況下使用魁莉。由于實(shí)現(xiàn)了構(gòu)建和裝配的解耦睬涧。不同的構(gòu)建器,相同的裝配旗唁,也可以做出不同的對象畦浓;相同的構(gòu)建器,不同的裝配順序也可以做出不同的對象检疫。也就是實(shí)現(xiàn)了構(gòu)建算法讶请、裝配算法的解耦,實(shí)現(xiàn)了更好的復(fù)用屎媳。
5.2夺溢、UML圖:


建造者模式.png

5.3、示例:

//電腦類
public class Computer {
    private Engine engine;
    private Keyboard keyboard;
    private Mouse mouse;
    public Engine getEngine() {
        return engine;
    }
    public void setEngine(Engine engine) {
        this.engine = engine;
    }
    public Keyboard getKeyboard() {
        return keyboard;
    }
    public void setKeyboard(Keyboard keyboard) {
        this.keyboard = keyboard;
    }
    public Mouse getMouse() {
        return mouse;
    }
    public void setMouse(Mouse mouse) {
        this.mouse = mouse;
    }
    public void play(){
        System.out.println(engine.getName()+keyboard.getName()+mouse.getName());
    };
}
//引擎類
class Engine{
    private String name;
    public Engine(String name){this.name=name;}
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
//鍵盤類
class Keyboard{
    private String name;
    public Keyboard(String name){this.name=name;}
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
//鼠標(biāo)類
class Mouse{
    private String name;
    public Mouse(String name){this.name=name;}
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
--------------------------------------------------------------------------------
//電腦構(gòu)建接口
public interface ComputerBuilder {
    public Engine createEngine();
    public Keyboard createKeyBoard();
    public Mouse createMouse();
}
class realComputerBuilder implements ComputerBuilder{
    public Engine createEngine() {
        return new Engine("聯(lián)想CPU");
    }
    public Keyboard createKeyBoard() {
        return new Keyboard("蘋果鍵盤");
    }
    public Mouse createMouse() {
        return new Mouse("華為鼠標(biāo)");
    }
}
--------------------------------------------------------------------------------
//電腦組裝接口
public interface ComputerDirector {
    public Computer computerDirector(ComputerBuilder computerBuilder);
}
class realComputerDirector implements ComputerDirector{
    public Computer computerDirector(ComputerBuilder computerBuilder) {
        Computer c = new Computer();
        c.setEngine(computerBuilder.createEngine());
        c.setKeyboard(computerBuilder.createKeyBoard());
        c.setMouse(computerBuilder.createMouse());
        return c;
    }
}
--------------------------------------------------------------------------------
//客戶端
public class Client {
    public static void main(String[] args) {
        ComputerBuilder computerBuilder = new realComputerBuilder();
        ComputerDirector computerDirector = new realComputerDirector(); 
        Computer c =computerDirector.computerDirector(computerBuilder);
        System.out.println(c.getEngine().getName()+""+c.getKeyboard().getName()+""+c.getMouse().getName()+"");
    }
}
--------------------------------------------------------------------------------
總結(jié):如上代碼烛谊,如果要生產(chǎn)不同型號(hào)的配件风响,只需要?jiǎng)?chuàng)建一個(gè)新的構(gòu)造器類,需要組裝成不同型號(hào)的電腦也只需要?jiǎng)?chuàng)建一個(gè)新的組黃器類丹禀,不需要修改之前的代碼

六状勤、原型模式(prototype)
6.1鞋怀、作用:通過new產(chǎn)生一個(gè)對象需要非常繁瑣的數(shù)據(jù)準(zhǔn)備或訪問權(quán)限,則可以使用原型模式荧降。它本身就是java中的克隆技術(shù)接箫,以某個(gè)對象為原型攒读,復(fù)制出新的對象朵诫。顯然,新的對象具備原型對象的特點(diǎn)薄扁。優(yōu)勢有:效率高(直接克隆剪返,避免了重新執(zhí)行構(gòu)造過程步驟) 〉嗣罚克隆類似于new脱盲,但是不同于new。new創(chuàng)建新的對象屬性采用的是默認(rèn)值日缨∏矗克隆出的對象的屬性值完全和原型對象相同。并且克隆出的新對象改變不會(huì)影響原型對象匣距。然后面哥,再修改克隆對象的值。
6.2毅待、重要知識(shí)點(diǎn):克隆問題(淺克隆和深克隆尚卫,此處不詳說,請另行查看我的文章:http://www.reibang.com/p/d2783a7cf031
6.3尸红、UML圖:

原型模式.png

6.4吱涉、示例:

//電腦類
public class Computer implements Serializable{
    private Engine engine;
    private Keyboard keyboard;
    private Mouse mouse;
    public Engine getEngine() {
        return engine;
    }
    public void setEngine(Engine engine) {
        this.engine = engine;
    }
    public Keyboard getKeyboard() {
        return keyboard;
    }
    public void setKeyboard(Keyboard keyboard) {
        this.keyboard = keyboard;
    }
    public Mouse getMouse() {
        return mouse;
    }
    public void setMouse(Mouse mouse) {
        this.mouse = mouse;
    }
    public void play(){
        System.out.println(engine.getName()+keyboard.getName()+mouse.getName());
    };
}
//引擎類
class Engine implements Serializable{
    private String name;
    public Engine(String name){this.name=name;}
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
//鍵盤類
class Keyboard implements Serializable{
    private String name;
    public Keyboard(String name){this.name=name;}
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
//鼠標(biāo)類
class Mouse implements Serializable{
    private String name;
    public Mouse(String name){this.name=name;}
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
--------------------------------------------------------------------------------
public class ComputerClone {
    public Computer clone(Computer c){
        Computer c2 =null;
        try {
            ByteArrayOutputStream bas =new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bas);
            oos.writeObject(c);
            ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bas.toByteArray()));
            c2 =(Computer) ois.readObject();
            bas.flush();oos.flush();
            bas.close();oos.close();
            ois.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return c2;
    }
}
--------------------------------------------------------------------------------
public class Client {
    public static void main(String[] args) {
        ComputerClone computerClone = new ComputerClone();
        Computer c = new Computer();
        c.setEngine(new Engine("華為CPU"));
        c.setKeyboard(new Keyboard("聯(lián)想鍵盤"));
        c.setMouse(new Mouse("蘋果鼠標(biāo)"));
        Computer c2 = computerClone.clone(c);
        System.out.println(c);
        System.out.println(c2);
        System.out.println(c2.getEngine().getName()+""+c2.getKeyboard().getName()+""+c2.getMouse().getName()+"");
    }
}
--------------------------------------------------------------------------------
結(jié)果:
com.primeton.GOF23.prototype.Computer@6727734f
com.primeton.GOF23.prototype.Computer@7176c74b
華為CPU聯(lián)想鍵盤蘋果鼠標(biāo)
--------------------------------------------------------------------------------
總結(jié):通過結(jié)果可以看到克隆出來的對象是一個(gè)新對象,但其中屬性與原型對象一致外里,整個(gè)新對象產(chǎn)生的過程很簡單怎爵,效率高(直接克隆,避免了重新執(zhí)行構(gòu)造過程步驟) 
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末盅蝗,一起剝皮案震驚了整個(gè)濱河市鳖链,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌风科,老刑警劉巖撒轮,帶你破解...
    沈念sama閱讀 211,561評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異贼穆,居然都是意外死亡题山,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評論 3 385
  • 文/潘曉璐 我一進(jìn)店門故痊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來顶瞳,“玉大人,你說我怎么就攤上這事】猓” “怎么了焰络?”我有些...
    開封第一講書人閱讀 157,162評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長符喝。 經(jīng)常有香客問我闪彼,道長,這世上最難降的妖魔是什么协饲? 我笑而不...
    開封第一講書人閱讀 56,470評論 1 283
  • 正文 為了忘掉前任畏腕,我火速辦了婚禮,結(jié)果婚禮上茉稠,老公的妹妹穿的比我還像新娘描馅。我一直安慰自己,他們只是感情好而线,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,550評論 6 385
  • 文/花漫 我一把揭開白布铭污。 她就那樣靜靜地躺著,像睡著了一般膀篮。 火紅的嫁衣襯著肌膚如雪嘹狞。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,806評論 1 290
  • 那天各拷,我揣著相機(jī)與錄音刁绒,去河邊找鬼。 笑死烤黍,一個(gè)胖子當(dāng)著我的面吹牛知市,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播速蕊,決...
    沈念sama閱讀 38,951評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼嫂丙,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了规哲?” 一聲冷哼從身側(cè)響起跟啤,我...
    開封第一講書人閱讀 37,712評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎唉锌,沒想到半個(gè)月后隅肥,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,166評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡袄简,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,510評論 2 327
  • 正文 我和宋清朗相戀三年腥放,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片绿语。...
    茶點(diǎn)故事閱讀 38,643評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡秃症,死狀恐怖候址,靈堂內(nèi)的尸體忽然破棺而出诞吱,到底是詐尸還是另有隱情蕴坪,我是刑警寧澤件舵,帶...
    沈念sama閱讀 34,306評論 4 330
  • 正文 年R本政府宣布酵熙,位于F島的核電站,受9級(jí)特大地震影響伞广,放射性物質(zhì)發(fā)生泄漏轩拨。R本人自食惡果不足惜厘肮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,930評論 3 313
  • 文/蒙蒙 一良漱、第九天 我趴在偏房一處隱蔽的房頂上張望舞虱。 院中可真熱鬧欢际,春花似錦母市、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至浑槽,卻和暖如春蒋失,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背桐玻。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評論 1 266
  • 我被黑心中介騙來泰國打工篙挽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人镊靴。 一個(gè)月前我還...
    沈念sama閱讀 46,351評論 2 360
  • 正文 我出身青樓铣卡,卻偏偏與公主長得像,于是被迫代替她去往敵國和親偏竟。 傳聞我的和親對象是個(gè)殘疾皇子煮落,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,509評論 2 348

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

  • 設(shè)計(jì)模式概述 在學(xué)習(xí)面向?qū)ο笃叽笤O(shè)計(jì)原則時(shí)需要注意以下幾點(diǎn):a) 高內(nèi)聚、低耦合和單一職能的“沖突”實(shí)際上踊谋,這兩者...
    彥幀閱讀 3,736評論 0 14
  • UML概述 UML簡介 UML (Unified Modeling Language)為面向?qū)ο筌浖O(shè)計(jì)提供統(tǒng)一的...
    aron1992閱讀 512評論 0 0
  • 字節(jié)跳動(dòng)飛書內(nèi)推蝉仇!北京、杭州殖蚕、武漢轿衔、廣州、深圳睦疫、上海害驹,六大城市等你來投。感興趣的朋友可以私我咨詢&內(nèi)推笼痛,也可以通過...
    盧卡斯嗶嗶嗶閱讀 607評論 0 3
  • 伸手黨一般都愛到處問人要健身計(jì)劃裙秋,基本被問得人心里都是拒絕的琅拌。原因是沒見過不了解你的體型和身體狀況。在這種情況下貿(mào)...
    九月藝文閱讀 963評論 0 0
  • 從前我有遠(yuǎn)大理想摘刑,想做一個(gè)偉大的人进宝,造福人類,萬中挑一枷恕。 可真是個(gè)單純天真的年紀(jì)啊党晋,那時(shí)的我眼見小,目光所及不過生...
    林星海閱讀 1,026評論 2 4