![Адаптер](/images/patterns/cards/adapter-mini.png?id=b2ee4f681fb589be5a0685b94692aebb)
Адаптер на Rust
Адаптер — это структурный паттерн, который позволяет подружить несовместимые объекты.
Адаптер выступает прослойкой между двумя объектами, превращая вызовы одного в вызовы понятные другому.
Adapter in Rust
In this example, the trait SpecificTarget
is incompatible with a call
function which accepts trait Target
only.
fn call(target: impl Target);
The adapter helps to pass the incompatible interface to the call
function.
let target = TargetAdapter::new(specific_target);
call(target);
adapter.rs
use crate::{adaptee::SpecificTarget, Target};
/// Converts adaptee's specific interface to a compatible `Target` output.
pub struct TargetAdapter {
adaptee: SpecificTarget,
}
impl TargetAdapter {
pub fn new(adaptee: SpecificTarget) -> Self {
Self { adaptee }
}
}
impl Target for TargetAdapter {
fn request(&self) -> String {
// Here's the "adaptation" of a specific output to a compatible output.
self.adaptee.specific_request().chars().rev().collect()
}
}
adaptee.rs
pub struct SpecificTarget;
impl SpecificTarget {
pub fn specific_request(&self) -> String {
".tseuqer cificepS".into()
}
}
target.rs
pub trait Target {
fn request(&self) -> String;
}
pub struct OrdinaryTarget;
impl Target for OrdinaryTarget {
fn request(&self) -> String {
"Ordinary request.".into()
}
}
main.rs
mod adaptee;
mod adapter;
mod target;
use adaptee::SpecificTarget;
use adapter::TargetAdapter;
use target::{OrdinaryTarget, Target};
/// Calls any object of a `Target` trait.
///
/// To understand the Adapter pattern better, imagine that this is
/// a client code, which can operate over a specific interface only
/// (`Target` trait only). It means that an incompatible interface cannot be
/// passed here without an adapter.
fn call(target: impl Target) {
println!("'{}'", target.request());
}
fn main() {
let target = OrdinaryTarget;
print!("A compatible target can be directly called: ");
call(target);
let adaptee = SpecificTarget;
println!(
"Adaptee is incompatible with client: '{}'",
adaptee.specific_request()
);
let adapter = TargetAdapter::new(adaptee);
print!("But with adapter client can call its method: ");
call(adapter);
}
Output
A compatible target can be directly called: 'Ordinary request.' Adaptee is incompatible with client: '.tseuqer cificepS' But with adapter client can call its method: 'Specific request.'