最近2018中文字幕在日韩欧美国产成人片_国产日韩精品一区二区在线_在线观看成年美女黄网色视频_国产精品一区三区五区_国产精彩刺激乱对白_看黄色黄大色黄片免费_人人超碰自拍cao_国产高清av在线_亚洲精品电影av_日韩美女尤物视频网站

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
如何使用結(jié)構(gòu)型模式

這篇文章主要講解了“如何使用結(jié)構(gòu)型模式”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“如何使用結(jié)構(gòu)型模式”吧!

在成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站過(guò)程中,需要針對(duì)客戶(hù)的行業(yè)特點(diǎn)、產(chǎn)品特性、目標(biāo)受眾和市場(chǎng)情況進(jìn)行定位分析,以確定網(wǎng)站的風(fēng)格、色彩、版式、交互等方面的設(shè)計(jì)方向。創(chuàng)新互聯(lián)公司還需要根據(jù)客戶(hù)的需求進(jìn)行功能模塊的開(kāi)發(fā)和設(shè)計(jì),包括內(nèi)容管理、前臺(tái)展示、用戶(hù)權(quán)限管理、數(shù)據(jù)統(tǒng)計(jì)和安全保護(hù)等功能。

適配器模式

所謂適配器模式,就是把一個(gè)類(lèi)的結(jié)構(gòu)轉(zhuǎn)換成另外一個(gè)類(lèi)的接口。使得原本由于接口不兼容而不能工作的類(lèi)都能夠一起工作。

在生活中比較常見(jiàn)的就是當(dāng)我們想連接顯示器的時(shí)候,vga需要轉(zhuǎn)成hdmi,還有電源適配,比如可能需要220v的充電頭,但是只有110v的充電頭,那么就需要將220v的充電頭適配成110v的充電頭。

Adaptee: 需要適配的就代碼,舊接口

Adapter: 將調(diào)用轉(zhuǎn)發(fā)給Adaptee 的適配器類(lèi)

Target: 支持的新接口

適配器模式UML

如何使用結(jié)構(gòu)型模式

類(lèi)適配器模式

Target

public interface Target {
    void output110v();
}

Adaptee

public class Adaptee {
    public void output220v() {
        System.out.println("輸出電壓");
    }
}

Adapter

public class Adapter extends Adaptee implements Target {
    @Override
    public void output110v() {
        this.output220v();
    }
}

這里需要注意的是Adapter繼承了源類(lèi)而實(shí)現(xiàn)了目標(biāo)類(lèi)

Client

public class Client {
    public static void main(String[] args) {
        Target target = new Adapter();
        target.output110v();
    }
}

雖然我們是使用了output110v的充電頭,但是經(jīng)過(guò)Adapter后,最終通過(guò)this.output220v() 會(huì)調(diào)用output220v的充電頭,這就是把output220v適配成了output110v。

如何使用結(jié)構(gòu)型模式

對(duì)象適配器模式

其實(shí)說(shuō)得這么高大上,其實(shí)就是Adaptor 的實(shí)現(xiàn)方式不同,類(lèi)適配器模式采用繼承了源類(lèi)(也就是需要適配的類(lèi))實(shí)現(xiàn)了目標(biāo)類(lèi)。

這樣就存在一個(gè)問(wèn)題,當(dāng)我們需要適配多個(gè)類(lèi)的時(shí)候就會(huì)出現(xiàn)問(wèn)題,因?yàn)閖ava中是允許實(shí)現(xiàn)多個(gè)接口,但是只能繼承一個(gè)類(lèi)。

為了解決這個(gè)問(wèn)題,我們可以把需要適配的類(lèi)作為Adapter 的成員變量,然后通過(guò)構(gòu)造函數(shù)進(jìn)行適配

public class NewAdapter implements Target{
    Adaptee adaptee;

    public NewAdapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    @Override
    public void output110v() {
        adaptee.output220v();
    }
}

代理模式


代理模式也算是比較常用的設(shè)計(jì)模式之一,大家接觸最多的spring aop,就是采用動(dòng)態(tài)代理模式來(lái)完成的。代理模式可以分為普通代理模式,強(qiáng)制代理模式,動(dòng)態(tài)代理模式,也是本文著重講解的,當(dāng)然還有其代理模式。

先來(lái)用一段代碼來(lái)體會(huì)代理模式,場(chǎng)景是玩家打游戲。

Subject: 共同接口,客戶(hù)端使用的現(xiàn)有接口

RealSubject: 真實(shí)對(duì)象的類(lèi)

ProxySubject: 代理對(duì)象類(lèi)

代理模式UML

如何使用結(jié)構(gòu)型模式

普通代理模式


通過(guò)上面的例子,相信對(duì)大家都對(duì)代理模式有點(diǎn)感覺(jué)了,但是好像又不那么恰當(dāng),上面的測(cè)試類(lèi)種,還是需要新建一個(gè)player,這就相當(dāng)于什么,相當(dāng)于我們是在手機(jī)上登錄了游戲,然后再把手機(jī)給代練者代練。而事實(shí)上,經(jīng)常是把賬號(hào)密碼給代練即可。

這就引出了普通代理模式,客戶(hù)端不能訪問(wèn)真實(shí)角色,只能訪問(wèn)代理角色,我們能夠知道代理的存在。

如何使用結(jié)構(gòu)型模式

Subject

public interface SubjectNormalGamePlayer {
    public void login();
    public void upgrade();
    public void matches();
}

RealSubject

public class RealSubjectNormalPlayerImpl implements SubjectNormalGamePlayer {
    private String name;
    private String password;

    public RealSubjectNormalPlayerImpl(String name, String password) {
        this.name = name;
        this.password = password;
    }

    @Override
    public void login() {
        if(name.equals("cutey") && password.equals("123456")) {
            System.out.println(name + "登錄成功");
        }
    }

    @Override
    public void upgrade() {  
        System.out.println(name + "升級(jí)");
    }

    @Override
    public void matches() {
        System.out.println(name + "打排位賽");
    }
}

ProxySubject

public class ProxySubjectNormalPlayerImpl implements SubjectNormalGamePlayer {
    SubjectNormalGamePlayer gamePlayer;

    //注意這里的區(qū)別,我們是拿賬號(hào)和密碼去登錄真實(shí)角色
    //并不是直接拿真實(shí)角色的手機(jī)來(lái)打
    public ProxySubjectNormalPlayerImpl(String name, String password) {
        gamePlayer = new RealSubjectNormalPlayerImpl(name, password);
    }

    @Override
    public void login() {
        System.out.print("代練:");
        gamePlayer.login();
    }

    @Override
    public void upgrade() {
        System.out.print("代練:");
        gamePlayer.upgrade();
    }

    @Override
    public void matches() {
        System.out.print("代練:");
        gamePlayer.matches();
    }
}

Client

public class Client {
    public static void main(String[] args) {
        //通過(guò)測(cè)試類(lèi)也很明顯區(qū)別,不必要顯示構(gòu)造真實(shí)角色類(lèi)
        SubjectNormalGamePlayer proxy = new ProxySubjectNormalPlayerImpl("cutey", "123456");
        proxy.login();
        proxy.upgrade();
        proxy.matches();
    }
}

強(qiáng)制代理


普通代理呢是去找到一個(gè)代理對(duì)象幫打,但是強(qiáng)制代理呢,主要是體現(xiàn)在“強(qiáng)制”,角色類(lèi)會(huì)指定一個(gè)代理,其它方式找來(lái)的代理不能幫我打,一定要用我指定的代理才行。

Subject

和普通代理模式大部分代碼一樣,不同的是加了一個(gè)強(qiáng)制指定代理對(duì)象。

public interface SubjectForceGamePlayer {
   	//省略登錄、升級(jí)和打排位等方法
    
    //強(qiáng)制指定代理對(duì)象
    public SubjectForceGamePlayer getForceProxy();
}

RealSubject

public class ForceGamePlayerImpl implements IForceGamePlayer {
    private String name;
    private String password;

    private IForceGamePlayer proxy = null;      //指定需要誰(shuí)來(lái)代理


    public ForceGamePlayerImpl(String name, String password) {
        this.name = name;
        this.password = password;
    }
    
    @Override
    public IForceGamePlayer getForceProxy() {
        //強(qiáng)制指定代理類(lèi),并且只有這樣才能給proxy賦值
        proxy =  new ForceProxyGamePlayerImpl(this);
        return proxy;
    }

    @Override
    public void login() {
        //只要不是自己指定的proxy,其它方式proxy肯定是null
        if(proxy != null) {
            if(name.equals("imperfect") && password.equals("123456")) {
                System.out.println(name + "登錄成功");
            }
        } else {
            System.out.println("需要代理");
        }

    }

    @Override
    public void upgrade() {
        if(proxy != null) {
            System.out.println(name + "升級(jí)");
        } else {
            System.out.println("需要代理");
        }

    }

    @Override
    public void matches() {
        if(proxy != null) {
            System.out.println(name + "打排位賽");
        } else {
            System.out.println("需要代理");
        }

    }
}

ProxySubject

public class ProxySubjectForcePlayerImpl implements SubjectForceGamePlayer {

    private SubjectForceGamePlayer gamePlayer;

	//接收被代理對(duì)象的指定
    public ProxySubjectForcePlayerImpl(SubjectForceGamePlayer gamePlayer) {
        this.gamePlayer = gamePlayer;
    }


    //省略登錄、升級(jí)和打比賽的方法

    //沒(méi)有代理對(duì)象,暫時(shí)返回自己
    @Override
    public SubjectForceGamePlayer getForceProxy() {
        return this;
    }

}

Client

public class Client {
    public static void main(String[] args) {
        wrongProxy1();
        wrongProxy2();
        correctProxy();
    }

    public static void correctProxy() {
        SubjectForceGamePlayer player = new RealSubjectForcePlayerImpl("cutey", "123456");

        //你這個(gè)代理必須是我指定的,并且強(qiáng)制要有
        SubjectForceGamePlayer proxy = player.getForceProxy();
        proxy.login();
        proxy.upgrade();
        proxy.matches();
    }

    public static void wrongProxy1() {
        SubjectForceGamePlayer player = new RealSubjectForcePlayerImpl("cutey", "123456");
        SubjectForceGamePlayer proxy = new ProxySubjectForcePlayerImpl(player);
        proxy.login();
        proxy.upgrade();
        proxy.matches();
    }

    public static void wrongProxy2() {
        SubjectForceGamePlayer player = new RealSubjectForcePlayerImpl("cutey", "123456");
        player.login();
        player.upgrade();
        player.matches();
    }
}

動(dòng)態(tài)代理


這個(gè)應(yīng)該是代理模式中用的比較多的,也是我覺(jué)得最需要各位小伙伴理解并且掌握的。所謂動(dòng)態(tài)代理是指,不用在編譯器指定為誰(shuí)代理,而是在運(yùn)行期再獲得被代理的對(duì)象并且執(zhí)行代理的方法。

下面將要講的例子是利用jdk中提供的InvocationHandler和Proxy類(lèi)

Subject 、RealSubject 都和普通代理模式一樣

ProxySubject

我們不知道要給誰(shuí)代理,所以要用到的是繼承InvocationHandler類(lèi)

public class ProxySubjectDynamicPlayerImpl implements InvocationHandler {
    Class cls = null;	//要代理的類(lèi)
    Object obj = null;	//需要代理的對(duì)象

    //指定需要代理的對(duì)象
    public ProxySubjectDynamicPlayerImpl(Object obj) {
        this.obj = obj;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //調(diào)用代理對(duì)象的方法
        Object result = method.invoke(this.obj, args);
        if(method.getName().equalsIgnoreCase("login")) {
            System.out.println("異地登陸提醒:有人登錄我的賬戶(hù)");
        }
        return result;
    }
}

Client

public class Client {
    public static void main(String[] args) {
        SubjectDynamicPlayer player = new RealSubjectDynamicPlayerImpl("imperfect", "123456");

        //把需要代理的信息交給handler,還記得invoke方法嗎
        //在invoke方法中已經(jīng)實(shí)現(xiàn)了被代理對(duì)象的方法
        InvocationHandler handler = new ProxySubjectDynamicPlayerImpl(player);

        //獲取被代理類(lèi)的類(lèi)加載屬性
        ClassLoader cl = player.getClass().getClassLoader();

        //獲取被代理類(lèi)的接口
        Class[] interfaces = player.getClass().getInterfaces();

        //把上述的三個(gè)信息交給Proxy創(chuàng)建出一個(gè)代理類(lèi)
        SubjectDynamicPlayer proxy = (SubjectDynamicPlayer) Proxy.newProxyInstance(cl, interfaces, handler);

        proxy.login();
        proxy.upgrade();
        proxy.matches();
    }
}

在編譯時(shí)我們是完全不知道給誰(shuí)代理,一切都是在運(yùn)行時(shí)才知道,這就是“動(dòng)態(tài)”

裝飾模式

裝飾模式就是動(dòng)態(tài)地給一個(gè)對(duì)象添加一些恩愛(ài)的職責(zé),就增加功能來(lái)說(shuō),裝飾模式比生成子類(lèi)更為靈活。

無(wú)論干什么,最重要的都是揚(yáng)長(zhǎng)避短,對(duì)于賣(mài)手機(jī)也是如此,肯定是把賣(mài)點(diǎn)詳細(xì)地介紹,而對(duì)于缺點(diǎn)能不提就不提。

Component: 定義一個(gè)對(duì)象的接口,可以給這些對(duì)象動(dòng)態(tài)地添加職責(zé)

ConcreteComponent: 具體的對(duì)象

Decorator: 裝飾抽象類(lèi),繼承了Component,從外類(lèi)來(lái)擴(kuò)展Component

ConcentrateDecorator: 具體的裝飾類(lèi)

裝飾模式UML

如何使用結(jié)構(gòu)型模式

裝飾模式

Component

public abstract class ComponentMobile {
    //產(chǎn)品名字
    private String name;

    //省略get,set,tostring方法

    public abstract void showDetails();

    public abstract void onSale(String userName);

}

Concentrate Component

public class ConcreteComponentOnePlus extends ComponentMobile {

    public ConcreteComponentOnePlus(String name) {
        super(name);
    }

    @Override
    public void showDetails() {
        System.out.println("處理器:驍龍888 \r\n拍照:哈蘇專(zhuān)業(yè)模式 \r\n屏幕:2k+120hz 柔性屏 \r\n充電:65w快充");
    }

    @Override
    public void onSale(String userName) {
        System.out.println(userName + "購(gòu)買(mǎi)了" + getName());
    }
}

Decorator

public abstract class Decorator extends ComponentMobile {

    //把要裝飾的手機(jī)拿給我
    private ComponentMobile mobile;

    public Decorator(String name, ComponentMobile mobile) {
        super(name);
        this.mobile = mobile;
    }

	//細(xì)節(jié)還是要展示的
    //只不過(guò)怎么展示呢,子類(lèi)可以加以修飾
    public void showDetails() {
        mobile.showDetails();
    }

    //手機(jī)也是要出售的
    public void onSale(String name) {
        mobile.onSale(name);
    }

}

注意,我們手機(jī)的細(xì)節(jié)還是要展示的,不能說(shuō)做的不好就不說(shuō)出來(lái),欺騙消費(fèi)者。能把你認(rèn)出來(lái)叫化妝,不能把你認(rèn)出來(lái)叫整容,我們講的是裝飾模式,不是整容模式。

如何使用結(jié)構(gòu)型模式

Concrete Decorator

public class ConcreteDecoratorSystem extends Decorator {

    public ConcreteDecoratorSystem(String name, ComponentMobile mobile) {
        super(name, mobile);
    }

    //裝飾系統(tǒng)
    public void decorateScreen() {
        System.out.println("出廠配備了ColorOS,其它型號(hào)的手機(jī)也會(huì)逐步適配");

    }

    @Override
    public void showDetails() {
        //想先介紹了系統(tǒng),再說(shuō)其他參數(shù)
        decorateScreen();
        super.showDetails();
    }
}
public class ConcreteDecoratorPrice extends Decorator {


    public ConcreteDecoratorPrice(String name, ComponentMobile mobile) {
        super(name, mobile);
    }

    //公布價(jià)格
    public void decoratePrice() {
        System.out.println("8 + 128:4999");
        System.out.println("8 + 256: 5499");
    }

    @Override
    public void showDetails() {
        super.showDetails();
        //介紹完其它的后,公布性?xún)r(jià)比較高的價(jià)格
        decoratePrice();
    }
}

Client

public class Client {
    public static void main(String[] args) {
        //手機(jī)發(fā)布會(huì),原產(chǎn)品
        ComponentMobile mobile = new ConcreteComponentOnePlus("OnePlus 9 Pro");
        //裝飾下系統(tǒng)
        mobile = new ConcreteDecoratorSystem(mobile.getName(), mobile);
        //裝飾下價(jià)格
        mobile = new ConcreteDecoratorPrice(mobile.getName(), mobile);
        mobile.showDetails();

        //用戶(hù)一看,誒,不錯(cuò)不錯(cuò),買(mǎi)了
        mobile.onSale("cutey");
    }
}

感謝各位的閱讀,以上就是“如何使用結(jié)構(gòu)型模式”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)如何使用結(jié)構(gòu)型模式這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!


新聞標(biāo)題:如何使用結(jié)構(gòu)型模式
本文路徑:http://fisionsoft.com.cn/article/jocjph.html