适配器是一种结构设计模式,它能让具有不兼容接口的对象进行协作。
这里案例中:有一个call函数只接受接口 (trait)为Target的参数:
fn call(target: impl Target);
|
如果有一个接口类型是SpecificTarget 作为需要作为参数传入怎么办?
将这个SpecificTarget 转换为Target。
就像将110伏插头转为220伏电压插头,这样只能使用220伏的电器通过适配插头就可以使用110伏电,这是去日本旅游需要携带转压器的原因、下面看看第一个接口trait:这是我们call函数可以接受的接口
target.rs
pub trait Target { fn request(&self) -> String; }
pub struct OrdinaryTarget;
impl Target for OrdinaryTarget { fn request(&self) -> String { "Ordinary request.".into() } }
|
但是,现在我们只有SpecificTarget这个接口,要传给call函数:
adaptee.rs:
pub struct SpecificTarget;
impl SpecificTarget { pub fn specific_request(&self) -> String { ".tseuqer cificepS".into() } }
|
那么,就需要一个适配转换器将SpecificTarget转换为Target:
adapter.rs:
use crate::{adaptee::SpecificTarget, Target};
///将adaptee的'SpecificTarget'转换为兼容的`Target`输出 pub struct TargetAdapter { adaptee: SpecificTarget, }
impl TargetAdapter { pub fn new(adaptee: SpecificTarget) -> Self { Self { adaptee } } }
impl Target for TargetAdapter { fn request(&self) -> String { // 这里是将原来的specific输出 "改编 "为兼容Target的输出。 self.adaptee.specific_request().chars().rev().collect() } }
|
上面三个代码已经完成适配器结构,下面是客户端调用:
main.rs
mod adaptee; mod adapter; mod target;
use adaptee::SpecificTarget; use adapter::TargetAdapter; use target::{OrdinaryTarget, Target};
/// 只能调用 "Target "接口的call函数 /// /// 为了更好地理解适配器模式,想象一下这是 /// 一个客户端代码,它只能在一个特定的接口上操作 /// (`Target` trait only)。这意味着一个不兼容的接口不能被 /// 在没有适配器的情况下传递到这里。 fn call(target: impl Target) { println!("'{}'", target.request()); }
fn main() { let target = OrdinaryTarget;
print!("兼容于target的任何参数都能直接被调用: "); call(target);
let adaptee = SpecificTarget;
println!( "Adaptee 与客户端不兼容: '{}'", adaptee.specific_request() );
let adapter = TargetAdapter::new(adaptee);
print!("但是使用 adapter 以后,客户端可以调用call函数了: "); call(adapter); }
|