Rust 中的設計模式:代理模式 -Proxy-

代理模式介紹

代理模式是一種非常有用的設計模式,其基本功能是確保調用者不能直接訪問對象的實例,而是通過具有該實例訪問權的另一個類來間接訪問。

我們在這裏看到了什麼?

1,一個 Drivable 接口,在 Rust 中就是 trait,這個 trait 只有一個方法:drive(int distance)。

2,兩個結構體:Car 和 Bicycle,它們都實現了 Drivable 特性。

3,一個具體的 VehicleProxy 結構體,它實現了 Drivable 特徵,但它也包含了一個實現 Drivable 特徵的具體對象。

4,一個具體的 VehicleManager 結構體,它保存了 VehicleProxy 的實例,它不知道將要驅動的車輛的確切類型,也不知道任何實現細節。

代理模式在某些情況下非常有用:

1,如果你想控制 / 監控對具體結構體的訪問。

2,如果你想有條件地訪問具體的結構體。在這個特殊的例子中,VehicleProxy 還可以獲取駕駛者的年齡作爲參數。例如,如果司機年齡小於 18 歲,他或她不允許開車。

如何在 Rust 中實現代理模式?

在你想要使用的目錄中打開一個終端,輸入:

cargo new proxy_pattern

我們將一步一步地進行實施。首先打開 main.rs,

定義 Drivable 特徵:

pub trait Drivable {
    fn drive(&self, distance:u32);
}

這個特徵定義了一個 drive 方法,有兩個參數:

定義和實現 Car 結構體:

pub struct Car {}

impl Drivable for Car {
    fn drive(&self, distance: u32) {
        println!("I drove {} kilometres in my car", distance);
    }
}

1,我們定義一個 Car 結構體,由於此結構體沒有其他屬性,因此該結構體爲空。

2,我們在 Car 結構體上實現了 Drivable 特徵的方法 drive,該方法只打印一條消息。

我們對 Bicycle 做同樣的事情:

pub struct Bicycle {}

impl Drivable for Bicycle {
    fn drive(&self, distance: u32) {
        println!("I drove {} kilometres on my bicycle", distance);
    }
}

定義 VehicleProxy:

pub struct VehicleProxy {
    pub real_subject: Box<dyn Drivable+'static>
}

impl Drivable for VehicleProxy {
    fn drive(&self, distance: u32) {
        self.real_subject.drive(distance);
    }
}

1,real_subject 字段是一個 Box,因爲在編譯時還不知道大小。

2,在 Box 泛型定義中,我們看到兩個東西:

3,在實現部分,我們看到在 real_subject 上調用了 drive 方法。

定義 VehicleManager:

pub struct VehicleManager {    
    pub vehicle_proxy: Box<VehicleProxy>
}

impl Drivable for VehicleManager {
    fn drive(&self, distance: u32) {
        self.vehicle_proxy.drive(distance);
    }
}

1,因爲我們不知道 VehicleProxy 將引用哪個類,所以在編譯時大小是未知的,所以我們再次使用 Box。

2,注意,在 vehicle_proxy 字段上調用 drive 方法。

現在來測試一下:

fn main() {
    let my_vehicle = Box::new(Bicycle {});

    let my_proxy = Box::new(VehicleProxy {
        real_subject: my_vehicle,
    });

    let my_vehicle_manager = Box::new(VehicleManager {
        vehicle_proxy: my_proxy,
    });

    my_vehicle_manager.drive(20);
}

執行 cargo run,結果如下:

I drove 20 kilometres on my bicycle
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/8ByF492VUbi_x5rRe679xQ