Skip to content

Commit

Permalink
proxy
Browse files Browse the repository at this point in the history
  • Loading branch information
lpxxn committed Mar 2, 2020
1 parent 1cd8be2 commit 0c52512
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,5 @@
|:-------:|:----------- |:------:|
| [Adapter](/structural/adapter.rs) | allows objects with incompatible interfaces to collaborate. ||
| [Decorator](/structural/decorator.rs) | Adds behavior to an object, statically or dynamically ||
| [Proxy](/structural/proxy.rs) | Provides a surrogate for an object to control it's actions ||

74 changes: 74 additions & 0 deletions structural/proxy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//! Proxy is a structural design pattern that lets you provide a substitute or placeholder for another object.
//! A proxy controls access to the original object, allowing you to perform something either before or after the request gets through to the original object.

// The Subject trait declares common operations for both RealSubject and
// the Proxy. As long as the client works with RealSubject using this
// interface, you'll be able to pass it a proxy instead of a real subject.
trait Subject {
fn request(&self);
}

// The RealSubject contains some core business logic. Usually, RealSubjects
// are capable of doing some useful work which may also be very slow or
// sensitive - e.g. correcting input data. A Proxy can solve these issues
// without any changes to the RealSubject's code.
struct RealSubject {}
impl Subject for RealSubject {
fn request(&self) {
println!("RealSubject: handling request.");
}
}

struct Proxy<'a> {
real_subject: &'a RealSubject,
}
impl<'a> Proxy<'a> {
fn new(real_subject: &'a RealSubject) -> Proxy {
Proxy { real_subject }
}
fn check_access(&self) -> bool {
// Some real checks should go here.
println!("Proxy: checking access prior to firing a real request.");
true
}
fn log_access(&self) {
println!("Proxy: logging the request.");
}
}

impl<'a> Subject for Proxy<'a> {
// The most common applications of the Proxy pattern are lazy loading,
// caching, controlling the access, logging, etc. A Proxy can perform one of
// these things and then, depending on the result, pass the execution to the
// same method in a linked RealSubject object.
fn request(&self) {
if self.check_access() {
self.real_subject.request();
self.log_access();
}
}
}

struct Client;
impl Client {
// The client code is supposed to work with all objects (both subjects
// and proxies) via the Subject interface in order to support both real
// subjects and proxies. In real life, however, clients mostly work with
// their real subjects directly. In this case, to implement the pattern
// more easily, you can extend your proxy from the real subject's class.
fn client_code<T: Subject>(subject: &T) {
subject.request();
}
}

fn main() {
let real_subject = RealSubject {};
println!("client: executing the client code with a real subject:");
Client::client_code(&real_subject);

println!("");
println!("client: executing the same client code with a proxy:");
let proxy = Proxy::new(&real_subject);
Client::client_code(&proxy);

}

0 comments on commit 0c52512

Please sign in to comment.