文章目錄
- 代理模式
- 介紹
- 實現
- java
- rust
- rust倉庫
代理模式
在代理模式(Proxy Pattern)中,一個類代表另一個類的功能。在代理模式中,我們創建具有現有對象的對象,以便向外界提供功能接口。
介紹
-
意圖:為其他對象提供一種代理以控制對這個對象的訪問。
-
代理模式的主要優點有:
- 代理模式在客戶端與目標對象之間起到一個中介作用和保護目標對象的作用;
- 代理對象可以擴展目標對象的功能;
- 代理模式能將客戶端與目標對象分離,在一定程度上降低了系統的耦合度;
-
其主要缺點是:
- 在客戶端和目標對象之間增加一個代理對象,會造成請求處理速度變慢;
- 增加了系統的復雜度;
-
應用實例: 1、買火車票不一定在火車站買,也可以去代售點。 2、一張支票或銀行存單是賬戶中資金的代理。支票在市場交易中用來代替現金,并提供對簽發人賬號上資金的控制。 3、spring aop。
-
使用場景:按職責來劃分,通常有以下使用場景: 1、遠程代理。 2、虛擬代理。 3、Copy-on-Write 代理。 4、保護(Protect or Access)代理。 5、Cache代理。 6、防火墻(Firewall)代理。 7、同步化(Synchronization)代理。 8、智能引用(Smart Reference)代理。
實現
我們將創建一個 Image 接口和實現了 Image 接口的實體類。ProxyImage 是一個代理類,減少 RealImage 對象加載的內存占用。
ProxyPatternDemo 類使用 ProxyImage 來獲取要加載的 Image 對象,并按照需求進行顯示。
代理模式的 UML 圖
java
步驟 1
創建一個接口。
Image.java
public interface Image {void display();
}
步驟 2
創建實現接口的實體類。
RealImage.java
public class RealImage implements Image {private String fileName;public RealImage(String fileName){this.fileName = fileName;loadFromDisk(fileName);}@Overridepublic void display() {System.out.println("Displaying " + fileName);}private void loadFromDisk(String fileName){System.out.println("Loading " + fileName);}
}
ProxyImage.java
public class ProxyImage implements Image{private RealImage realImage;private String fileName;public ProxyImage(String fileName){this.fileName = fileName;}@Overridepublic void display() {if(realImage == null){realImage = new RealImage(fileName);}realImage.display();}
}
步驟 3
當被請求時,使用 ProxyImage 來獲取 RealImage 類的對象。
ProxyPatternDemo.java
public class ProxyPatternDemo {public static void main(String[] args) {Image image = new ProxyImage("test_10mb.jpg");// 圖像將從磁盤加載image.display(); System.out.println("");// 圖像不需要從磁盤加載image.display(); }
}
步驟 4
執行程序,輸出結果:
Loading test_10mb.jpg
Displaying test_10mb.jpgDisplaying test_10mb.jpg
rust
rust和java的搭建過程類似,如就不再贅述rust搭建過程。
trait Image {fn dispaly(&self);
}
struct RealImage{file_name:String,
}
impl RealImage {fn load_from_disk(&self) {println!("Loading {}",self.file_name)}fn new(file_name:String)->RealImage {let i=RealImage { file_name:file_name.clone() };i.load_from_disk();i}
}impl Image for RealImage {fn dispaly(&self) {println!("Displaying {}",self.file_name.as_str())}
}
struct ProxyImage{real_image: RealImage,file_name:String}
impl ProxyImage {fn new(file_name:String)->ProxyImage {ProxyImage{real_image:RealImage::new(file_name.clone()),file_name:file_name}}
}
impl Image for ProxyImage {fn dispaly(&self) {self.real_image.dispaly();}
}
fn main() {let pi=ProxyImage::new("test_10mb.jpg".to_string());pi.dispaly();pi.dispaly();
}
rust倉庫
https://github.com/onenewcode/design.git
本教程項目在bin文件夾下的proxy.rs文件中