国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

七種常用的設(shè)計(jì)模式

這篇具有很好參考價(jià)值的文章主要介紹了七種常用的設(shè)計(jì)模式。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

常用的七種設(shè)計(jì)模式:?jiǎn)卫J健⒐S方法模式、抽象工廠模式、代理模式、裝飾器模式、觀察者模式和責(zé)任鏈模式。

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

設(shè)計(jì)模式根據(jù)工作的目的,分為創(chuàng)建型模式、結(jié)構(gòu)型模式和行為型模式三類。

創(chuàng)建型模式:單例模式、工廠方法模式抽象工廠模式、創(chuàng)建者模式、原型模式。

結(jié)構(gòu)型模式:適配器模式、代理模式裝飾器模式、外觀模式、橋接模式、組合模式、享元模式。

行為型模式:策略模式、模板方法模式、觀察者模式、迭代子模式、責(zé)任鏈模式、命令模式、備忘錄模式、狀態(tài)模式、訪問者模式、中介者模式、解釋器模式。

軟件設(shè)計(jì)七大原則(OOP原則)

開閉原則:對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉。
里氏替換原則:不要破壞繼承體系,子類重寫方法功能發(fā)生改變,不應(yīng)該影響父類方法的含義。
依賴倒置原則:要面向接口編程,不要面向?qū)崿F(xiàn)編程。
單一職責(zé)原則:控制類的粒度大小、將對(duì)象解耦、提高其內(nèi)聚性。
接口隔離原則:要為各個(gè)類建立它們需要的專用接口。
迪米特法則:一個(gè)類應(yīng)該保持對(duì)其它對(duì)象最少的了解,降低耦合度。
合成復(fù)用原則:盡量先使用組合或者聚合等關(guān)聯(lián)關(guān)系來實(shí)現(xiàn),其次才考慮使用繼承關(guān)系來實(shí)現(xiàn)。

實(shí)際上,七大原則的目的只有一個(gè):降低對(duì)象之間的耦合,增加程序的可復(fù)用性、可擴(kuò)展性和可維護(hù)性。

1、單例模式:一個(gè)類只有一個(gè)實(shí)例,且該類能自行創(chuàng)建這個(gè)實(shí)例的一種模式
? ? ? ? ①單例類只有一個(gè)實(shí)例對(duì)象

? ? ? ? ②該單例對(duì)象必須由單例類自行創(chuàng)建

? ? ? ? ③單例類對(duì)外提供一個(gè)訪問該單例的全局訪問點(diǎn)

? ? ? ?④、優(yōu)點(diǎn)
????????????????單例模式可以保證內(nèi)存里只有一個(gè)實(shí)例,減少了內(nèi)存的開銷。
????????????????可以避免對(duì)資源的多重占用。
????????????????單例模式設(shè)置全局訪問點(diǎn),可以優(yōu)化和共享資源的訪問。
????????⑤、缺點(diǎn)
????????????????單例模式一般沒有接口,擴(kuò)展困難。
????????????????單例模式的功能代碼通常寫在一個(gè)類中,如果功能設(shè)計(jì)不合理,則很容易違背單一職責(zé)原則

? ? ? ? 餓漢式單例:類一旦加載就創(chuàng)建一個(gè)單例,保證在調(diào)用getInstance方法之前單例已經(jīng)存在,這種餓漢式單例會(huì)造成空間浪費(fèi)。

public class Hungry {
    private Hungry(){}
    private final static Hungry HUNGRY = new Hungry();
    public static Hungry getInstance(){
        return HUNGRY;
    }
}

????????懶漢式單例:為了避免內(nèi)存空間浪費(fèi),采用懶漢式單例,即用到該單例對(duì)象的時(shí)候再創(chuàng)建。

public class LazyMan {
    private LazyMan(){};

    public static LazyMan lazyMan;

    public static LazyMan getInstance(){
        if (lazyMan==null){
            lazyMan = new LazyMan();
        }
        return lazyMan;
    }
}

這是最簡(jiǎn)單的懶漢式,但是,存在很大問題,單線程下這段代碼沒有問題,但是在多線程下有很大問題。

public class LazyMan {
    private LazyMan(){
        System.out.println(Thread.currentThread().getName()+"");
    }

    public static LazyMan lazyMan;

    public static LazyMan getInstance(){
        if (lazyMan==null){
            lazyMan = new LazyMan();
        }
        return lazyMan;
    }

    public static void main(String[] args) {
        for(int i=0;i<10;i++){
            new Thread(()->{
                lazyMan.getInstance();
            }).start();
        }
    }
}

設(shè)計(jì)模式,后端開發(fā),設(shè)計(jì)模式,java,單例模式?會(huì)發(fā)現(xiàn)結(jié)果都不一樣,因此,并發(fā)情況下,這段代碼是有問題的。我們需要進(jìn)行兩端檢測(cè),進(jìn)行“加鎖”:synchronized (Singleton.class)。

public class LazyMan {
    private LazyMan(){
        System.out.println(Thread.currentThread().getName()+"");
    }

    public static LazyMan lazyMan;

    public static LazyMan getInstance(){
        if (lazyMan==null){        //第一層檢查,檢查是否有引用指向?qū)ο螅卟l(fā)情況下會(huì)有多個(gè)線程同時(shí)進(jìn)入
            synchronized (LazyMan.class){    //第一層鎖,保證只有一個(gè)線程進(jìn)入
                //雙重檢查,防止多個(gè)線程同時(shí)進(jìn)入第一層檢查(因單例模式只允許存在一個(gè)對(duì)象,故在創(chuàng)建對(duì)象之前無引用指向?qū)ο螅芯€程均可進(jìn)入第一層檢查)
                //當(dāng)某一線程獲得鎖創(chuàng)建一個(gè)LazyMan對(duì)象時(shí),即已有引用指向?qū)ο?,lazyMan不為空,從而保證只會(huì)創(chuàng)建一個(gè)對(duì)象
                //假設(shè)沒有第二層檢查,那么第一個(gè)線程創(chuàng)建完對(duì)象釋放鎖后,后面進(jìn)入對(duì)象也會(huì)創(chuàng)建對(duì)象,會(huì)產(chǎn)生多個(gè)對(duì)象
                if(lazyMan==null){    //第二層檢查
                    //synchronized關(guān)鍵字作用為禁止指令重排,保證返回Singleton對(duì)象一定在創(chuàng)建對(duì)象后
                    lazyMan = new LazyMan();        //這行代碼存在的問題,不能保證原子性
實(shí)際上會(huì)執(zhí)行以下內(nèi)容:
                    //(1)在堆上開辟空間;(2)屬性初始化;(3)引用指向?qū)ο?                    //假設(shè)以上三個(gè)內(nèi)容為三條單獨(dú)指令,因指令重排可能會(huì)導(dǎo)致執(zhí)行順序?yàn)?->3->2(正常為1->2->3),當(dāng)單例模式中存在普通變量需要在構(gòu)造方法中進(jìn)行初始化操作時(shí),單線程情況下,順序重排沒有影響;但在多線程情況下,假如線程1執(zhí)行l(wèi)azyMan = new LazyMan()語(yǔ)句時(shí)先1再3,由于系統(tǒng)調(diào)度線程2的原因沒來得及執(zhí)行步驟2,但此時(shí)已有引用指向?qū)ο笠簿褪莑azyMan!=null,故線程2在第一次檢查時(shí)不滿足條件直接返回lazyMan,此時(shí)lazyMan為null
                    //synchronized關(guān)鍵字可保證lazyMan = new LazyMan()語(yǔ)句執(zhí)行順序?yàn)?23,因其為非原子性依舊可能存在系統(tǒng)調(diào)度問題(即執(zhí)行步驟時(shí)被打斷),但能確保的是只要lazyMan!=0,就表明一定執(zhí)行了屬性初始化操作;而若在步驟3之前被打斷,此時(shí)lazyMan依舊為null,其他線程可進(jìn)入第一層檢查向下執(zhí)行創(chuàng)建對(duì)象
                }
            }
        }
        return lazyMan;
    }

    public static void main(String[] args) {
        for(int i=0;i<10;i++){
            new Thread(()->{
                lazyMan.getInstance();
            }).start();
        }
    }
}

設(shè)計(jì)模式,后端開發(fā),設(shè)計(jì)模式,java,單例模式?可以看到結(jié)果都是只有一個(gè),按理來說是沒有問題,實(shí)際上不是,上述標(biāo)注行代碼存在問題的,不是一個(gè)原子性操作。

? ? ? ? 靜態(tài)內(nèi)部類單例:是不安全,存在問題的,是不安全,存在問題的(修改過的懶漢式單例也是如此)。

public class Inner {
    private Inner(){}
    public static Inner getInstance(){
        return InnerClass.INNER;
    }
    public static class InnerClass{
        private static final Inner INNER = new Inner();
    }
}

2、工廠方法模式:實(shí)例化對(duì)象不是用new,用工廠方法替代。將選擇實(shí)現(xiàn)類,創(chuàng)建對(duì)象統(tǒng)一管理和控制。從而將調(diào)用者跟我們的實(shí)現(xiàn)類解耦。

? ? ? ? 簡(jiǎn)單工廠模式:用來生產(chǎn)同一等級(jí)架構(gòu)中的任意產(chǎn)品(對(duì)于增加新的產(chǎn)品,需要修改已有代碼)
在簡(jiǎn)單工廠模式中,可以根據(jù)參數(shù)的不同返回不同類的實(shí)例。簡(jiǎn)單工廠模式專門定義一個(gè)類來負(fù)責(zé)創(chuàng)建其他類的實(shí)例。

接下來創(chuàng)建一個(gè)接口,兩個(gè)實(shí)現(xiàn)類,一個(gè)工廠,一個(gè)測(cè)試類

//創(chuàng)建手機(jī)接口
public interface Phone {
    void name();
}
//創(chuàng)建華為實(shí)現(xiàn)類
public class HuaWei implements Phone{
    @Override
    public void name() {
        System.out.println("華為手機(jī)");
    }
}
//創(chuàng)建小米實(shí)現(xiàn)類
public class XiaoMi implements Phone{
    @Override
    public void name() {
        System.out.println("小米手機(jī)");
    }
}
//創(chuàng)建工廠
public class PhoneFactory {
    public static Phone getPhone(String phone){
        if(phone.equals("華為")){
            return new HuaWei();
        }else if(phone.equals("小米")){
            return  new XiaoMi();
        }else {
            return null;
        }
    }
}
//測(cè)試類
public class Consumer {
    public static void main(String[] args) {
        Phone p1= PhoneFactory.getPhone("華為");
        Phone p2= PhoneFactory.getPhone("小米");
        p1.name();
        p2.name();
    }
}

得到測(cè)試結(jié)果

????????華為手機(jī)
????????小米手機(jī)

我們通過創(chuàng)建一個(gè)PhoneFactory類,成功的完成工廠的創(chuàng)建。我們?cè)趧?chuàng)建對(duì)象時(shí),也就不需要直接創(chuàng)建對(duì)象,而是可以通過創(chuàng)建工廠,這樣大大的降低了代碼的耦合性。但是,靜態(tài)工廠模式是不能添加數(shù)據(jù)的。比如說,我們想添加一個(gè)“Oppo”手機(jī)類,你不直接修改PhoneFactory工廠代碼,是不能實(shí)現(xiàn)的。所以,就有了第二種的工廠方法模式。

? ? ? ? 工廠方法模式:用來生產(chǎn)同一等級(jí)架構(gòu)中的固定產(chǎn)品,一個(gè)工廠等級(jí)結(jié)構(gòu)可以負(fù)責(zé)多個(gè)不同產(chǎn)品等級(jí)結(jié)構(gòu)中的產(chǎn)品對(duì)象的創(chuàng)建 。(支持增加任意產(chǎn)品)

//創(chuàng)建手機(jī)接口
public interface Phone {
    void name();
}
//創(chuàng)建華為實(shí)現(xiàn)類
public class HuaWei implements Phone{
    @Override
    public void name() {
        System.out.println("華為手機(jī)");
    }
}
//創(chuàng)建手機(jī)工廠接口
public interface PhoneFactory {
    Phone getPhone();
}
//創(chuàng)建華為工廠
public class HuaWeiFactory implements PhoneFactory{
    @Override
    public Phone getPhone() {
        return new HuaWei();
    }
}
//測(cè)試類
public class Consumer {
    public static void main(String[] args) {
        Phone phone = new HuaWeiFactory().getPhone();
        phone.name();
    }
}

得到測(cè)試結(jié)果

? ? ? ? 華為手機(jī)

我們創(chuàng)建了手機(jī)工廠接口PhoneFactory,再創(chuàng)建華為工廠HuaWeiFactory實(shí)現(xiàn)工廠,這樣就可以通過HuaWeiFactory創(chuàng)建對(duì)象。增加新的具體工廠和產(chǎn)品族很方便,比如說,我們想要增加小米,只需要?jiǎng)?chuàng)建一個(gè)小米工廠XiaoMiFactory實(shí)現(xiàn)手機(jī)工廠接口PhoneFactory,合理的解決的簡(jiǎn)單工廠模式不能修改代碼的缺點(diǎn)。但是,在現(xiàn)實(shí)使用中,簡(jiǎn)單工廠模式占絕大多數(shù)。

簡(jiǎn)單工廠模式與工廠方法模式比較:

結(jié)構(gòu)的復(fù)雜度:簡(jiǎn)單工廠模式占優(yōu)。
代碼的復(fù)雜度:簡(jiǎn)單工廠模式占優(yōu)。
編程的復(fù)雜度:簡(jiǎn)單工廠模式占優(yōu)。
管理的復(fù)雜的:簡(jiǎn)單工廠模式占優(yōu)。
因此,雖然簡(jiǎn)單工廠模式不符合設(shè)計(jì)模式,但是實(shí)際使用遠(yuǎn)大于工廠方法模式

3、抽象工廠模式:抽象工廠模式提供了一個(gè)創(chuàng)建一系列相關(guān)或者相互依賴對(duì)象的接口,無需指定它們具體的類(圍繞一個(gè)超級(jí)工廠創(chuàng)建其他工廠,該超級(jí)工廠稱為工廠的工廠)

抽象工廠模式得主要角色:

????????1、抽象工廠(Abstract Factory)提供了創(chuàng)建產(chǎn)品的接口,它包含多個(gè)創(chuàng)建產(chǎn)品的方法 newProduct(),可以創(chuàng)建多個(gè)不同等級(jí)的產(chǎn)品。
2具體工廠(Concrete Factory)主要是實(shí)現(xiàn)抽象工廠中的多個(gè)抽象方法,完成具體產(chǎn)品的創(chuàng)建。
3抽象產(chǎn)品(Product)定義了產(chǎn)品的規(guī)范,描述了產(chǎn)品的主要特性和功能,抽象工廠模式有多個(gè)抽象產(chǎn)品。
4具體產(chǎn)品(ConcreteProduct)實(shí)現(xiàn)了抽象產(chǎn)品角色所定義的接口,由具體工廠來創(chuàng)建,它同具體工廠之間是多對(duì)一的關(guān)系。

//電腦接口
public interface Computer {
    void play();
    void watch();
}
//創(chuàng)建華為電腦對(duì)象
public class HuaWeiComputer implements Computer{
    @Override
    public void play() {
        System.out.println("HuaWei's play!");
    }

    @Override
    public void watch() {
        System.out.println("HuaWei's watch!");
    }
}
//手機(jī)接口
public interface Phone {
    void send();
    void call();
}
//創(chuàng)建華為手機(jī)對(duì)象
public class HuaWeiPhone implements Phone{
    @Override
    public void send() {
        System.out.println("HuaWei's send");
    }

    @Override
    public void call() {
        System.out.println("HuaWei's call");
    }
}
//抽象工廠
public interface IProductFactory {
    //生產(chǎn)手機(jī)
    Phone phone();
    //生產(chǎn)電腦
    Computer computer();
}
//創(chuàng)建華為工廠
public class HuaWeiFactory implements IProductFactory{
    @Override
    public Phone phone() {
        return new HuaWeiPhone();
    }

    @Override
    public Computer computer() {
        return new HuaWeiComputer();
    }
}
//測(cè)試類
public class Consumer {
    public static void main(String[] args) {
        HuaWeiFactory huaWeiFactory = new HuaWeiFactory();
        Phone phone = huaWeiFactory.phone();
        phone.call();
        phone.send();
        Computer computer = huaWeiFactory.computer();
        computer.play();
        computer.watch();
    }
}

得到測(cè)試結(jié)果

????????HuaWei's call
????????HuaWei's send
????????HuaWei's play!
????????HuaWei's watch!

我們通過創(chuàng)建一個(gè)抽象工廠完成了對(duì)具體工廠的創(chuàng)建,只需要傳入?yún)?shù)就可以實(shí)例化對(duì)象。具體產(chǎn)品在應(yīng)用層的代碼隔離,無需關(guān)心創(chuàng)建的細(xì)節(jié)將一個(gè)系列的產(chǎn)品統(tǒng)一到一起創(chuàng)建。將一系列產(chǎn)品規(guī)劃到一起創(chuàng)建。但是,抽象工廠模式也存在著缺點(diǎn)。規(guī)定了所有可能被創(chuàng)建的產(chǎn)品集合,產(chǎn)品簇中擴(kuò)展新的產(chǎn)品困難,不可以增加產(chǎn)品,只能增加品牌。

4、代理模式:由于某些原因需要給某對(duì)象提供一個(gè)代理以控制對(duì)該對(duì)象的訪問。這時(shí),訪問對(duì)象不適合或者不能直接引用目標(biāo)對(duì)象,代理對(duì)象作為訪問對(duì)象和目標(biāo)對(duì)象之間的中介。

? ? ? ? 靜態(tài)代理模式:

? ? ? ? 角色分析:? ? ? ? ???

????????1、抽象角色:一般會(huì)使用接口或抽象類來解決

????????2、真實(shí)角色:被代理的角色

????????3、代理角色:代理真實(shí)角色,代理真實(shí)角色后我們會(huì)進(jìn)行一些附屬操作

????????4、訪問角色:訪問代理對(duì)象的人

//租房
public interface Rent {
    void rent();
}
//房東
public class Master implements Rent{
    @Override
    public void rent() {
        System.out.println("Master rent");
    }
}
//中介
public class Proxy implements Rent{
    private Master master;

    public Proxy() {
    }

    public Proxy(Master master) {
        this.master = master;
    }

    @Override
    public void rent() {
        see();
        master.rent();
        fare();
    }
    //看房
    public void see(){
        System.out.println("see");
    }
    //收費(fèi)
    public void fare(){
        System.out.println("fare");
    }
}
//測(cè)試類
public class Consumer {
    public static void main(String[] args) {
        Master master = new Master();
        //進(jìn)行代理
        Proxy proxy = new Proxy(master);
        //不需要通過對(duì)象,直接通過代理完成響應(yīng)業(yè)務(wù)
        proxy.rent();
    }
}

得到測(cè)試結(jié)果

????????see
????????Master rent
????????fare

可以從上述代碼看出,我們通過創(chuàng)建中介這一代理完成了租房,并且還有看房、收費(fèi)的附屬操作。我們不需要使用房東對(duì)象,通過使用代理中介就可以完成操作。?

代理模式優(yōu)點(diǎn):可以使真實(shí)角色的操作更加純粹!不用去關(guān)注一些公共的業(yè)務(wù),公共也就可以交給代理角色,實(shí)現(xiàn)了業(yè)務(wù)的分工,公共業(yè)務(wù)發(fā)生擴(kuò)展的時(shí)候,方便集中管理!
代理模式缺點(diǎn):一個(gè)真實(shí)角色就會(huì)產(chǎn)生一個(gè)代理角色;代碼量會(huì)翻倍開發(fā)效率會(huì)變低,也許,這樣無法理解到代理模式的好處。舉個(gè)例子也許能更好理解,比如說我們想要在原有固定功能上新增業(yè)務(wù),按照開閉原則我們是不能對(duì)原有代碼進(jìn)行修改的。但是我們可以通過代理模式,增加代理,在實(shí)現(xiàn)原有功能的情況下寫入新的功能,創(chuàng)建對(duì)象時(shí)也就可以使用代理,完成操作。

?動(dòng)態(tài)代理模式:雖然靜態(tài)代理模式可以很好的解決開閉原則,但是每有一個(gè)真實(shí)角色就會(huì)產(chǎn)生一個(gè)代理,代碼量翻倍過于臃腫,開發(fā)效率較低。因此,我們就使用動(dòng)態(tài)代理模式進(jìn)行設(shè)計(jì)。

//接口
public interface IUserService {
    void add();
    void delete();
    void update();
    void query();

}
//實(shí)現(xiàn)類
public class UserServiceImpl implements IUserService {
    @Override
    public void add() {
        System.out.println("add");
    }

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

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

    @Override
    public void query() {
        System.out.println("query");
    }
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//自動(dòng)生成動(dòng)態(tài)代理類模板
public class ProxyInvocationHandler implements InvocationHandler {
    //被代理接口
    private Object target;
   
    public void setTarget(Object target) {
        this.target = target;
    }
     //得到代理類
    public Object getProxy() {
        return Proxy.newProxyInstance(getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }
    public void log(String s) {
        System.out.println("[debug]:" + s);
    }
    //得到代理類
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        log(method.getName());
        Object result = method.invoke(target, args);
        return result;
    }
}
//測(cè)試類
public class Consumer {
    public static void main(String[] args) {
        UserServiceImpl userService = new UserServiceImpl();
        ProxyInvocationHandler handler = new ProxyInvocationHandler();
        //設(shè)置代理對(duì)象
        handler.setTarget(userService);
        //生成代理類
        IUserService proxy = (IUserService)handler.getProxy();
        proxy.add();
        proxy.query();
    }
}

得到測(cè)試結(jié)果

????????[debug]:add
????????add
????????[debug]:query
????????query

通過測(cè)試我們可以順利的使用動(dòng)態(tài)代理模式完成一系列操作,當(dāng)我們想要添加附屬操作時(shí),我們只需要在模板中進(jìn)行添加。優(yōu)點(diǎn):①可以使真實(shí)角色的操作更加純粹!不用去關(guān)注一些公共的業(yè)務(wù)。②公共也就可以交給代理角色!實(shí)現(xiàn)了業(yè)務(wù)的分工。③公共業(yè)務(wù)發(fā)生擴(kuò)展的時(shí)候,方便集中管理。④一個(gè)動(dòng)態(tài)代理類代理的是一個(gè)接口,一般就是對(duì)應(yīng)的一類業(yè)務(wù)。⑤一個(gè)動(dòng)態(tài)代理類可以代理多個(gè)類,只要是實(shí)現(xiàn)了同一個(gè)接口即可!

5、裝飾者模式:動(dòng)態(tài)的將新功能附加到對(duì)象上。在對(duì)象功能的拓展方面,比繼承更有彈性。同時(shí)裝飾者模式也體現(xiàn)了開閉原則。

? ? ? ? 角色分析:

? ? ? ? 1、抽象構(gòu)件(Component)角色:定義一個(gè)抽象接口以規(guī)范準(zhǔn)備接收附加責(zé)任的對(duì)象。
? ? ? ? 2、具體構(gòu)件(ConcreteComponent)角色:實(shí)現(xiàn)抽象構(gòu)件,通過裝飾角色為其添加一些職責(zé)。
????????3、抽象裝飾(Decorator)角色:繼承抽象構(gòu)件,并包含具體構(gòu)件的實(shí)例,可以通過其子類擴(kuò)展具體構(gòu)件的功能。
????????4、具體裝飾(ConcreteDecorator)角色:實(shí)現(xiàn)抽象裝飾的相關(guān)方法,并給具體構(gòu)件對(duì)象添加附加的責(zé)任。

//定義抽象類
public abstract class Drink {
    public abstract double cost();
}
//定義兩個(gè)抽象類的實(shí)現(xiàn)類
public class Juice extends Drink{
    @Override
    public double cost() {
        System.out.println("juice: "+16);
        return 16;
    }
}
public class Milk extends Drink{
    @Override
    public double cost() {
        System.out.println("milk: "+12);
        return 12;
    }
}
//定義裝飾抽象類
public abstract class Decorator extends Drink {
    public abstract double cost();
}
//定義兩個(gè)裝飾具體實(shí)現(xiàn)類
public class Chocolate extends Decorator{
    private final static double COST = 4;
    private Drink drink;

    public Chocolate(Drink drink) {
        this.drink = drink;
    }

    @Override
    public double cost() {
        System.out.println("chocolate:"+4);
        return COST+drink.cost();
    }
}
public class Pudding extends Decorator{
    private final static double COST = 5;
    private Drink drink;

    public Pudding(Drink drink) {
        this.drink = drink;
    }

    @Override
    public double cost() {
        System.out.println("pudding:"+5);
        return COST+drink.cost();
    }
}
//測(cè)試類
public class Test {
    public static void main(String[] args) {
        Drink milk = new Milk();
        milk = new Pudding(milk);
        milk = new Chocolate(milk);
        System.out.println(milk.cost());
    }
}

得到測(cè)試結(jié)果

????????chocolate:4
????????pudding:5
????????milk: 12
????????21.0

設(shè)計(jì)模式,后端開發(fā),設(shè)計(jì)模式,java,單例模式

?

可以看到非常簡(jiǎn)單的就能夠完成具體構(gòu)件和具體裝飾的組合。也可以看到結(jié)構(gòu)也非常簡(jiǎn)潔明,具體構(gòu)件在自己的package中,具體裝飾也在自己的package中。我們不管是想要增加具體構(gòu)件還是具體配飾,都可以在各自的package中添加。對(duì)已有的代碼不需要進(jìn)行任何操作,就算新加的有bug也不會(huì)影響原有代碼的操作。

6、觀察者模式:對(duì)象間的一種一對(duì)多依賴關(guān)系,使得每當(dāng)一個(gè)對(duì)象狀態(tài)發(fā)生改變時(shí),其相關(guān)依賴對(duì)象皆得到通知并被自動(dòng)更新。這種模式有時(shí)又稱作發(fā)布-訂閱模式、模型-視圖模式,它是對(duì)象行為型模式。

? ? ? ? 觀察者模式有點(diǎn):

? ? ? ? 1、降低了目標(biāo)與觀察者之間的耦合關(guān)系,兩者之間是抽象耦合關(guān)系。符合依賴倒置原則。

? ? ? ? 2、目標(biāo)與觀察者之間建立了一套觸發(fā)機(jī)制。

//定義觀察者接口
public interface Observer {
    void response();
}
//具體化觀察者1
public class Observer1 implements Observer{
    @Override
    public void response() {
        System.out.println("Observer1 action");
    }
}
//具體化觀察者2
public class Observer2 implements Observer{
    @Override
    public void response() {
        System.out.println("Observer2 action");
    }
}
//抽象目標(biāo)
public abstract class Subject {
    //創(chuàng)建觀察者集合
    protected ArrayList<Observer> array = new ArrayList<Observer>();
    //增加觀察者
    public void add(Observer observer){
        array.add(observer);
    }
    //刪除觀察者
    public void remove(Observer observer){
        array.remove(observer);
    }
    //通知觀察者方法
    public abstract void notifyObserver();
}
//具體化目標(biāo)
public class Subject1 extends Subject{
    @Override
    public void notifyObserver() {
        for (Observer observer :array){
            observer.response();
        }
    }
}
//測(cè)試類
public class Test {
    public static void main(String[] args) {
        Subject subject = new Subject1();
        Observer obs1 = new Observer1();
        Observer obs2 = new Observer2();
        subject.add(obs1);
        subject.add(obs2);
        subject.notifyObserver();
    }
}

得到測(cè)試結(jié)果:

????????Observer1 action
????????Observer2 action

通過測(cè)試我們可以看到,我們不需要建立太多觀察者和具體目標(biāo)之間的聯(lián)系,大大降低了目標(biāo)與觀察者之間的耦合關(guān)系。并且結(jié)構(gòu)也十分簡(jiǎn)單明了,觀察者和目標(biāo)分別在各自的package包下。當(dāng)我們想要添加觀察者時(shí),只需要在觀察者包下進(jìn)行添加,實(shí)現(xiàn)Observer接口就可以了。

7、責(zé)任鏈模式:一種處理請(qǐng)求的模式,它讓多個(gè)處理器都有機(jī)會(huì)處理該詰求,直到其中某個(gè)處理成功為止。責(zé)任鏈模式把多個(gè)處理器串成鏈,然后讓請(qǐng)求在鏈上傳遞。
????????責(zé)任鏈模式的主要角色
????????抽象處理者(Handler)角色:定義一個(gè)處理請(qǐng)求的接口,包含抽象處理方法和一個(gè)后繼連接。
????????具體處理者(Concrete Handler)角色:實(shí)現(xiàn)抽象處理者的處理方法,判斷能否處理本次請(qǐng)求,如果可以處理請(qǐng)求則處理,否則將該請(qǐng)求轉(zhuǎn)給它的后繼者。
????????客戶類(Client)角色:創(chuàng)建處理鏈,并向鏈頭的具體處理者對(duì)象提交請(qǐng)求,它不關(guān)心處理細(xì)節(jié)和請(qǐng)求的傳遞過程。
????????責(zé)任鏈模式優(yōu)點(diǎn)
????????????????降低了對(duì)象之間的耦合度。處理者不需要知道客戶的任何信息,客戶也不要知道處理者是如何實(shí)現(xiàn)方法的。
????????????????提高了系統(tǒng)的靈活性。當(dāng)我們想要新增處理器到整個(gè)鏈條中時(shí),所付出的代價(jià)是非常小的
????????責(zé)任鏈模式缺點(diǎn)
????????????????降低了系統(tǒng)的性能。對(duì)比較長(zhǎng)的職責(zé)鏈,請(qǐng)求的處理可能涉及多個(gè)處理對(duì)象
????????????????不能保證每個(gè)請(qǐng)求一定被處理。由于一個(gè)請(qǐng)求沒有明確的接收者,所以不能保證它一定會(huì)被處理,該請(qǐng)求可能一直傳到鏈的末端都得不到處理。

//抽象處理者
public abstract class Handler {
    private Handler next;
    public void setNext(Handler next) { this.next = next; }
    public Handler getNext() { return next; }

    //處理請(qǐng)求
    public abstract void handleRequest(int info);
}
//具體處理者1
public class Handler1 extends Handler{
    @Override
    public void handleRequest(int info) {
        if (info <10){
            System.out.println("Handler1完成處理");
        }else {
            if (getNext()!=null){
                getNext().handleRequest(info);
            }else {
                System.out.println("沒有處理者進(jìn)行處理");
            }
        }
    }
}
//具體處理者2
public class Handler2 extends Handler{
    @Override
    public void handleRequest(int info) {
        if (info <20&&info>10){
            System.out.println("Handler2完成處理");
        }else {
            if (getNext()!=null){
                getNext().handleRequest(info);
            }else {
                System.out.println("沒有處理者進(jìn)行處理");
            }
        }
    }
}
測(cè)試類
public class Test {
    public static void main(String[] args) {
        Handler handler1 = new Handler1();
        Handler handler2 = new Handler2();
        handler1.setNext(handler2);
        handler1.handleRequest(5);
        handler1.handleRequest(15);
        handler1.handleRequest(25);
    }
}

得到測(cè)試結(jié)果:

Handler1完成處理
Handler2完成處理
沒有處理者進(jìn)行處理

通過測(cè)試結(jié)果我們看到,5交給了Handler1處理,15交給了Handler2處理,而25則沒有處理者處理。請(qǐng)求者根本不需要參與處理,只需要提交數(shù)據(jù)就可以完成功能的處理,完全不需要管是哪個(gè)處理者進(jìn)行處理的。當(dāng)我們想要繼續(xù)添加處理者時(shí),這只需要再次添加就可以了,也不會(huì)對(duì)之前的代碼造成影響。文章來源地址http://www.zghlxwxcb.cn/news/detail-789305.html

到了這里,關(guān)于七種常用的設(shè)計(jì)模式的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【Java】常用設(shè)計(jì)模式的理解

    有一些重要的設(shè)計(jì)原則在開篇和大家分享下,這些原則將貫通全文: 面向接口編程,而不是面向?qū)崿F(xiàn)。這個(gè)很重要,也是優(yōu)雅的、可擴(kuò)展的代碼的第一步,這就不需要多說了吧。 職責(zé)單一原則。每個(gè)類都應(yīng)該只有一個(gè)單一的功能,并且該功能應(yīng)該由這個(gè)類完全封裝起來。 對(duì)

    2024年02月13日
    瀏覽(17)
  • Java程序中常用的設(shè)計(jì)模式有哪些和該種設(shè)計(jì)模式解決的痛點(diǎn)

    設(shè)計(jì)模式是大量程序員智慧的結(jié)晶,是優(yōu)秀的代碼范式,是以前那些大佬程序員的編程經(jīng)驗(yàn)總結(jié),非常值得學(xué)習(xí)。 在軟件開發(fā)中,有許多常用的設(shè)計(jì)模式,每種模式都解決了特定類型的問題。以下是一些常見的設(shè)計(jì)模式及其簡(jiǎn)要介紹: 單例模式 (Singleton): 定義:確保類只有一

    2024年02月09日
    瀏覽(18)
  • 一文講完Java常用設(shè)計(jì)模式(23種)

    一文講完Java常用設(shè)計(jì)模式(23種)

    設(shè)計(jì)模式的起源可以追溯到20世紀(jì)80年代,當(dāng)時(shí)面向?qū)ο缶幊涕_始流行。在這個(gè)時(shí)期,一些軟件開發(fā)者開始注意到他們?cè)诓煌捻?xiàng)目中遇到了相同的問題,并且他們開始尋找可重用的解決方案。這些解決方案被稱為設(shè)計(jì)模式。最早提出設(shè)計(jì)模式的人是Erich Gamma、Richard Helm、Ral

    2024年02月08日
    瀏覽(19)
  • Java中JDK類庫(kù)常用的6種設(shè)計(jì)模式

    Java中JDK類庫(kù)常用的6種設(shè)計(jì)模式: 1、抽象工廠。2、建造者模式。3、工廠模式。4、原型模式。5、單例模式。6、適配器模式。 javax.xml.parsers. DocumentBuilderFactory 抽象類。 public static DocumentBuilderFactory newInstance ()方法。 類功能:使得應(yīng)用程序可以 通過XML文件,獲得一個(gè)能生成DO

    2024年02月04日
    瀏覽(21)
  • 4.設(shè)計(jì)模式之后七種模式后11種模式命令訪問者迭代器發(fā)布訂閱中介者忘備錄解釋器狀態(tài)策略職責(zé)鏈和空模式

    4.設(shè)計(jì)模式之后七種模式后11種模式命令訪問者迭代器發(fā)布訂閱中介者忘備錄解釋器狀態(tài)策略職責(zé)鏈和空模式

    1.命令(command)模式 不知道命令接收者(對(duì)象)是誰(shuí),支持撤銷 (接受者 間接調(diào)用執(zhí)行 的具體行為) 命令調(diào)用者和接收者解耦 //只要實(shí)現(xiàn)命令接口即可 (就是客戶端給個(gè)命令,然后命令類傳給接收類執(zhí)行) 優(yōu)點(diǎn)和缺點(diǎn) 容易撤銷操作 命令隊(duì)列可以多線程操作 增加過多的命令類 空命令也

    2024年02月12日
    瀏覽(96)
  • 實(shí)際開發(fā)中常用的設(shè)計(jì)模式--------策略模式(知識(shí)跟業(yè)務(wù)場(chǎng)景結(jié)合)-----小白也能看懂(通俗易懂版本)

    1.策略模式定義: 策略模式是一種行為型設(shè)計(jì)模式,它允許在運(yùn)行時(shí)動(dòng)態(tài)地改變對(duì)象的行為。策略模式將將每一個(gè)算法封裝到具有共同接口的獨(dú)立的類中,從而使得它們可以相互替換從而使得算法的變化不會(huì)影響到客戶端 2.簡(jiǎn)單的策略模式示例代碼: 在上述代碼中,SortStra

    2024年02月13日
    瀏覽(29)
  • 實(shí)際開發(fā)中常用的設(shè)計(jì)模式--------單例模式(知識(shí)跟業(yè)務(wù)場(chǎng)景結(jié)合)-----小白也能看懂(通俗易懂版本)

    1.定義 單例模式是一種創(chuàng)建型設(shè)計(jì)模式,它通過使用私有構(gòu)造函數(shù)和靜態(tài)方法來確保一個(gè)類只有一個(gè)實(shí)例,并且提供全局訪問點(diǎn)來獲取該實(shí)例。 通過使用單例模式,我們可以方便地管理全局唯一的對(duì)象實(shí)例,并且避免了多次創(chuàng)建相同類型的對(duì)象所帶來的資源浪費(fèi)問題 2.業(yè)務(wù)場(chǎng)

    2024年02月12日
    瀏覽(29)
  • 【Java開發(fā)】設(shè)計(jì)模式 17:中介者模式

    中介者模式是一種行為設(shè)計(jì)模式,指用一個(gè)中介對(duì)象來封裝一系列的對(duì)象交互。 中介者使各對(duì)象不需要顯示地相互引用,從而使其耦合松散,而且可以獨(dú)立地改變它們之間的交互。在這個(gè)模式中,中介者負(fù)責(zé)協(xié)調(diào)各個(gè)對(duì)象間的通信,使其流程更加清晰簡(jiǎn)單。 ??? 場(chǎng)景 中介者

    2023年04月22日
    瀏覽(24)
  • 【設(shè)計(jì)模式與范式:行為型】71 | 命令模式:如何利用命令模式實(shí)現(xiàn)一個(gè)手游后端架構(gòu)?

    設(shè)計(jì)模式模塊已經(jīng)接近尾聲了,現(xiàn)在我們只剩下 3 個(gè)模式還沒有學(xué)習(xí),它們分別是:命令模式、解釋器模式、中介模式。這 3 個(gè)模式使用頻率低、理解難度大,只在非常特定的應(yīng)用場(chǎng)景下才會(huì)用到,所以,不是我們學(xué)習(xí)的重點(diǎn),你只需要稍微了解,見了能認(rèn)識(shí)就可以了。 今天

    2024年02月09日
    瀏覽(20)
  • 【設(shè)計(jì)模式】單例模式|最常用的設(shè)計(jì)模式

    【設(shè)計(jì)模式】單例模式|最常用的設(shè)計(jì)模式

    單例模式是最常用的設(shè)計(jì)模式之一,雖然簡(jiǎn)單,但是還是有一些小坑點(diǎn)需要注意。本文介紹單例模式并使用go語(yǔ)言實(shí)現(xiàn)一遍單例模式。 單例模式保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)訪問它的全局訪問點(diǎn)。 使用場(chǎng)景: 當(dāng)類只能有一個(gè)實(shí)例而且可以從一個(gè)公開的眾所周知的訪

    2024年04月29日
    瀏覽(31)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包