Java設(shè)計(jì)模式之代理模式與裝飾模式實(shí)例詳解
本文實(shí)例講述了Java設(shè)計(jì)模式之代理模式與裝飾模式。分享給大家供大家參考,具體如下:
之所以把這兩種模式放在一起說(shuō),是因?yàn)槲野l(fā)現(xiàn)這了兩種模式幾乎一模一樣!
從網(wǎng)上也搜了一些資料,發(fā)現(xiàn)兩者還是有一些區(qū)別的。我們?cè)趯W(xué)習(xí)的同時(shí)也把這種困惑搞清楚。
定義:
代理模式,為其他對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪問(wèn)。
裝飾模式,動(dòng)態(tài)地給一個(gè)對(duì)象添加一些額外的職責(zé)。
代理模式,很好理解,就是把一個(gè)對(duì)象再次封裝,以后就對(duì)封裝的對(duì)象訪問(wèn)就可以了。
因?yàn)榇韺?duì)象已經(jīng)取代了被代理對(duì)象。
裝飾模式,給一個(gè)對(duì)象增加功能,形象一點(diǎn)就是做為一個(gè)服務(wù)生站在一邊提供服務(wù)。
所以根本的區(qū)別是,裝飾模式對(duì)象還在場(chǎng),不是取代原對(duì)象,而是在一邊提供服務(wù)。
本文所闡述觀點(diǎn)均為個(gè)人理解,只對(duì)本人負(fù)責(zé)。
下面給出例子:
package test.design.proxydecorator;
/**
* 接口定義行為:吃飯
* @author lushuaiyin
*
*/
public interface Eatable {
void eatFood();
}
package test.design.proxydecorator;
/**
* 實(shí)現(xiàn)類
* @author lushuaiyin
*
*/
public class Man implements Eatable{
@Override
public void eatFood() {
System.out.println("I am eating food! Happy!");
}
}
以上是普通的接口與實(shí)現(xiàn),下面是模式實(shí)例
代理模式
package test.design.proxydecorator;
/**
* 代理模式
* 代理對(duì)象把被代理對(duì)象封裝,像一個(gè)包裝盒把被代理對(duì)象包裹起來(lái)。
* 它不改變被代理對(duì)象的原有邏輯,只是增加來(lái)了一些自己的服務(wù),像一個(gè)代理一樣。
* 代理從使用上給調(diào)用者的感覺(jué)就是你已經(jīng)取代了原來(lái)的對(duì)象。
* 就像皇太后取代小皇帝實(shí)行垂簾聽(tīng)政。
* @author Administrator
*
*/
public class ProxyMan implements Eatable{
private Eatable eatable;
public ProxyMan(){
System.out.println("proxy: I am proxy object. I will help you create a object of Man that wnt to be proxyed");
this.eatable=new Man();
//注意代理對(duì)象把被代理對(duì)象封裝,在內(nèi)部有實(shí)際的被代理對(duì)象,這個(gè)調(diào)用者是不知道的。
}
@Override
public void eatFood() {
//代理對(duì)象把被代理對(duì)象的功能封裝,蛋不改變其內(nèi)部邏輯,只是增加一些服務(wù)。
System.out.println("proxy: I know you are hungry,so I cook for you some food.");
this.eatable.eatFood();
System.out.println("proxy: Now you eat up food. Let me help you clean the dishes.");
}
}
裝飾模式
package test.design.proxydecorator;
/**
* 裝飾的抽象.
* 也可以不用抽象類,簡(jiǎn)單的父類也可以,只要實(shí)現(xiàn)裝飾功能.
* 抽象只是為了增加一層封裝,規(guī)定裝飾者必有的裝飾功能而已。
* @author lushuaiyin
*
*/
public abstract class DecoratorMan {
protected Eatable eatable;
//使用構(gòu)造函數(shù)或者set方法(或其他方法)把接口對(duì)象傳入。
//注意,必須保證這個(gè)對(duì)象的傳入,最好還是用構(gòu)造函數(shù)。
public DecoratorMan(Eatable eatable){
this.eatable=eatable;
}
public void eatFood(){
this.eatable.eatFood();
};
}
package test.design.proxydecorator;
/**
* 裝飾模式
* 裝飾對(duì)象時(shí)獨(dú)立于原來(lái)的對(duì)象的。它和被裝飾的對(duì)象有關(guān)系,但是是獨(dú)立的對(duì)象。
* 裝飾對(duì)象更像一個(gè)酒店服務(wù)生,為別人提供服務(wù),所以他還是他自己,他有自己的實(shí)際存在。
* @author lushuaiyin
*
*/
public class Decorator extends DecoratorMan{
public Decorator(Eatable eatable) {
super(eatable);
}
//重寫(xiě)父類方法
public void eatFood(){
decoratorServiceCookFood();//裝飾的具體行為
super.eatable.eatFood();
decoratorServiceCleanDishes();//裝飾的具體行為
};
public void decoratorServiceCookFood(){
System.out.println("Decorator: I know you are hungry,so I cook for you some food.");
}
public void decoratorServiceCleanDishes(){
System.out.println("Decorator: Now you eat up food. Let me help you clean the dishes.");
}
}
最關(guān)鍵的是調(diào)用,這也是這兩種模式的主要區(qū)別所在!
package test.design.proxydecorator;
public class TestMain {
/**
* @param args
*/
public static void main(String[] args) {
//代理模式
System.out.println("代理模式:");
Man m1=new Man();//通常情況下
m1.eatFood();
System.out.println("---------------------------");
//代理模式者直接取代某對(duì)象,你連你想要見(jiàn)的人的面都見(jiàn)不到。
//它說(shuō)你要見(jiàn)的人已經(jīng)把所有事委托于我,他會(huì)的我會(huì);他不會(huì)的,我也會(huì)。我就是他的替代增強(qiáng)版。
Eatable e1=new ProxyMan();
e1.eatFood();
System.out.println("------------分割---------------");
System.out.println("裝飾模式:");
Man m2=new Man();//通常情況下
m2.eatFood();
System.out.println("---------------------------");
//裝飾模式者站在一邊提供各種服務(wù).
//裝飾者和被裝飾者都在場(chǎng),裝飾者提供服務(wù),賺取小費(fèi)。
Decorator d1=new Decorator(m2);
d1.eatFood();
}
}
打印:
代理模式: I am eating food! Happy! --------------------------- proxy: I am proxy object. I will help you create a object of Man that wnt to be proxyed proxy: I know you are hungry,so I cook for you some food. I am eating food! Happy! proxy: Now you eat up food. Let me help you clean the dishes. ------------分割--------------- 裝飾模式: I am eating food! Happy! --------------------------- Decorator: I know you are hungry,so I cook for you some food. I am eating food! Happy! Decorator: Now you eat up food. Let me help you clean the dishes.
更多java相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點(diǎn)技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總》
希望本文所述對(duì)大家java程序設(shè)計(jì)有所幫助。
相關(guān)文章
Spring中的@ConditionalOnProperty作用和用法詳解
這篇文章主要介紹了Spring中的@ConditionalOnProperty作用和用法詳解,在spring boot中有時(shí)候需要控制配置類是否生效,可以使用@ConditionalOnProperty注解來(lái)控制@Configuration是否生效,需要的朋友可以參考下2023-11-11
Java 同步鎖(synchronized)詳解及實(shí)例
這篇文章主要介紹了Java 同步鎖(synchronized)詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-03-03
Java實(shí)現(xiàn)對(duì)象排序的兩種方式詳解
這篇文章主要介紹了Java實(shí)現(xiàn)對(duì)象排序的兩種方式詳解,在Java中經(jīng)常會(huì)涉及到對(duì)象數(shù)組的排序問(wèn)題,則就提到對(duì)象之間的比較問(wèn)題,今天我們就來(lái)看一下兩種不同排序方式之間的區(qū)別,需要的朋友可以參考下2023-09-09
Java的方法和this關(guān)鍵字如何理解與應(yīng)用
Java語(yǔ)言中的“方法”(Method)在其他語(yǔ)言當(dāng)中也可能被稱為“函數(shù)”(Function)。對(duì)于一些復(fù)雜的代碼邏輯,如果希望重復(fù)使用這些代碼,并且做到“隨時(shí)任意使用”,那么就可以將這些代碼放在一個(gè)大括號(hào){}當(dāng)中,并且起一個(gè)名字。使用代碼的時(shí)候,直接找到名字調(diào)用即可2021-10-10
RocketMQ的push消費(fèi)方式實(shí)現(xiàn)示例
這篇文章主要為大家介紹了RocketMQ的push消費(fèi)方式實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪<BR>2022-08-08
MybatisPlus實(shí)現(xiàn)真正批量插入的詳細(xì)步驟
在數(shù)據(jù)庫(kù)操作中,批量插入是提升效率的重要手段,MyBatis-Plus提供了多種批量插入方法,但默認(rèn)的saveBatch方法效率并不高,文章介紹了通過(guò)手動(dòng)拼接SQL、使用IService接口以及自定義insertBatchSomeColumn方法進(jìn)行優(yōu)化,以實(shí)現(xiàn)更高效的批量插入,并給出了性能優(yōu)化建議2024-10-10
Java中sleep()與wait()的區(qū)別總結(jié)
因?yàn)樽罱鼘W(xué)習(xí)時(shí)正好碰到這兩個(gè)方法,就查閱相關(guān)資料,并通過(guò)程序?qū)崿F(xiàn),進(jìn)行區(qū)別總結(jié)一下,所以下面這篇文章主要給大家總結(jié)介紹了關(guān)于Java中sleep()與wait()區(qū)別的相關(guān)資料,需要的朋友可以參考,下面來(lái)一起看看吧。2017-05-05
java switch語(yǔ)句使用注意的四大細(xì)節(jié)
很多朋友在使用java switch語(yǔ)句時(shí),可能沒(méi)有注意到一些細(xì)節(jié),本文將詳細(xì)介紹使用java switch語(yǔ)句四大要點(diǎn),需要的朋友可以參考下2012-12-12

