代理模式的定義:為其他對象提供一種代理以控制對這個對象的訪問。在某些情況下,一個對象不適合或者不能直接引用另一個對象,而代理對象可以在客戶端和目標對象之間起到中介的作用, 其特征是代理類與委托類有同樣的接口,。代理模式是常用的java設(shè)計模式。
下面寫一個demo來使用一下代理模式,通過使用interface和不使用interface兩種情況的處理,看看使用interface的優(yōu)點在哪里。
一.不使用接口(interface)情況下實現(xiàn)代理
1.首先定義一個類Read作為閱讀界面,展示顯示的文本,在定義一個類Chat。
設(shè)置三個屬性text,color,size,目的是通過代理過程在外部設(shè)置它的color和size屬性。
Read類:
public class Read {
private String text;
private String color;//默認的字體顏色
private int size;//默認的字體大小
public Read(String text){
this.text = text;
}
}
Chat類:
public class Chat {
private String text;
private String backgroundColor;
private int size;
public Chat(String text){
this.text = text;
}
然后在這兩個類里面都提供一個方法goToSeting(),模擬進入設(shè)置頁面。該方法內(nèi)需要做的事有:1.創(chuàng)建設(shè)置頁面的對象 2.推送到設(shè)置頁面
同時還要定義一個方法用于改變屬性后將數(shù)據(jù)傳遞回來。
Read類里面:
//提供給外部一個方法 可以通過這個方法給我傳值
public void change(String color, int size){
System.out.println("改變前顏色:"+this.color+" "+"大小:"+this.size);
this.color = color;
this.size = size;
System.out.println("改變后顏色:"+this.color+" "+"大小:"+this.size);
}
Chat類里面:
public void doChange(String backgroundColor,int size){
System.out.println("設(shè)置前背景顏色:"+this.backgroundColor+" "+"字體:"+this.size);
this.backgroundColor = backgroundColor;
this.size = size;
System.out.println("設(shè)置后背景顏色:"+this.backgroundColor+" "+"字體:"+this.size);
}
2.然后,在定義一個類Setting作為設(shè)置頁面,可以設(shè)置字體大小和顏色。
Setting類里面需要定義了兩個屬性記錄為誰設(shè)置顏色和大小,記錄做完事情之后將數(shù)據(jù)返回給誰。定義如下:
Read read;
Chat chat;
然后寫一個方法startSetting()用于開始做事情,就是設(shè)置屬性。做完事通過調(diào)用他們的change()方法返回數(shù)據(jù)。Setting類里面實現(xiàn):
public class Setting {
//記錄為誰設(shè)置顏色和大小 記錄做完事情之后將數(shù)據(jù)返回給誰
Read read;
Chat chat;
public Setting(Read read){
this.read = read;
}
public Setting(Chat chat) {
this.chat = chat;
}
//開始設(shè)置
public void startSetting(){
System.out.println("開始設(shè)置....");
System.out.println("設(shè)置完畢 將返回!!!");
if (read != null){
read.change("褐色",30);
}
if (chat != null) {
chat.doChange("藍色", 20);
}
}
}
需要注意的是,這里必須判斷記錄是誰做事情的read和chat對象是否為null,然后才能調(diào)用change()方法返回數(shù)據(jù),不能直接返回數(shù)據(jù)。
因為在外部創(chuàng)建Read和Chat對象,調(diào)用goToSetting()方法設(shè)置他們的屬性時,只有同時有一個對象調(diào)用該方法來改變屬性,當多個同時調(diào)用時,就會報錯。報錯如下:
開始設(shè)置....
設(shè)置完畢 將返回!!!
改變前顏色:null 大小:0
改變后顏色:褐色 大小:30
Exception in thread "main" java.lang.NullPointerException
at day7.Setting.startSetting(Setting.java:40)
at day7.Read.goToSeting(Read.java:20)
at day7.MyClass.main(MyClass.java:13)
Process finished with exit code 1
接著需要實現(xiàn)兩個類里面模擬進入頁面的goToSetting()方法
Read類里面:
//模擬進入設(shè)置頁面
public void goToSeting(){
//1.創(chuàng)建設(shè)置頁面的對象
Setting setting = new Setting(this);
//2.推送到設(shè)置頁面
setting.startSetting();
}
Chat類里面:
public void goToSetting(){
Setting setting = new Setting(this);
setting.startSetting();
}
最后,到main方法里面創(chuàng)建對象,調(diào)用方法:
public class MyClass {
public static void main(String[] args){
// Read r1 = new Read("Hello World!");
// r1.goToSeting();
Read r2 = new Read("test");
r2.goToSeting();
Chat c1 = new Chat("Hello");
c1.goToSetting();
}
}
二.使用接口(interface)實現(xiàn)代理
1.定義一個Setting方法用于設(shè)置屬性。
因為設(shè)置完屬性后要回掉數(shù)據(jù),而可能有多個類的屬性需要被設(shè)置,每個類都有自己的返回數(shù)據(jù)的方法,導致方法不統(tǒng)一,而且每添加一個對象使用Setting類,都必須要添加一個這個類的對象和構(gòu)造方法。
因此需要使用多態(tài),定義一個內(nèi)部接口,統(tǒng)一管理傳遞數(shù)據(jù)的方法,并且保證每個使用Setting的類都必須實現(xiàn)這個方法。
Setting類里面實現(xiàn) 定義一個內(nèi)部接口:
public interface FontSettingInterface{
//定義同一個傳遞數(shù)據(jù)的方法
public void change(String color,int size);
}
創(chuàng)建對象
FontSettingInterface obj;
public Setting(FontSettingInterface obj){
this.obj = obj;
}
傳遞數(shù)據(jù)
public void startSetting(){
System.out.println("開始設(shè)置....");
System.out.println("設(shè)置完畢 將返回!!!");
obj.change("黑色",25);
}
2.使用Setting的類必須要實現(xiàn)這個接口,設(shè)置傳遞的對象,實現(xiàn)接口方法。
Read類:
public class Read implements Setting.FontSettingInterface{
private String text;
private String color;//默認的字體顏色
private int size;//默認的字體大小
public Read(String text){
this.text = text;
}
//模擬進入設(shè)置頁面
public void goToSeting(){
//1.創(chuàng)建設(shè)置頁面的對象
Setting setting = new Setting(this);
//2.推送到設(shè)置頁面
setting.startSetting();
}
@Override
public void change(String color, int size) {
System.out.println("改變前顏色:"+this.color+" "+"大小:"+this.size);
this.color = color;
this.size = size;
System.out.println("改變后顏色:"+this.color+" "+"大小:"+this.size);
}
}
Chat類:
public class Chat implements Setting.FontSettingInterface {
private String text;
private String backgroundColor;
private int size;
public Chat(String text){
this.text = text;
}
public void goToSetting(){
Setting setting = new Setting(this);
setting.startSetting();
}
@Override
public void change(String color, int size) {
System.out.println("設(shè)置前背景顏色:"+this.backgroundColor+" "+"字體:"+this.size);
this.backgroundColor = color;
this.size = size;
System.out.println("設(shè)置后背景顏色:"+this.backgroundColor+" "+"字體:"+this.size);
}
}
3.最后,在main方法里面創(chuàng)建對象然后調(diào)用。
總結(jié)
要寫好這個demo,需要理解接口的使用方法,通過這樣簡單的使用接口,也更有利于我們理解接口的使用和實現(xiàn)過程。