Skip to content

Commit 63857f9

Browse files
committed
Chain of Responsibility: Patient->Reception->etc.
1 parent e9d99fe commit 63857f9

File tree

10 files changed

+199
-0
lines changed

10 files changed

+199
-0
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ members = [
1616
"structural/facade",
1717
"structural/flyweight",
1818
"structural/proxy",
19+
"behavioral/chain-of-responsibility",
1920
]
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[package]
2+
edition = "2021"
3+
name = "chain-of-responsibility"
4+
version = "0.1.0"
5+
6+
[[bin]]
7+
name = "chain-of-responsibility"
8+
path = "main.rs"
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Chain of Responsibility
2+
3+
## Conceptual Example
4+
5+
The chain of responsibility is constructed as the following:
6+
7+
```
8+
Patient -> Reception -> Doctor -> Medical -> Cashier
9+
```
10+
11+
How to execute the example:
12+
13+
```bash
14+
cargo run
15+
```
16+
17+
## Execution Result
18+
19+
```
20+
Reception registering a patient John
21+
Doctor checking a patient John
22+
Medical giving medicine to a patient John
23+
Cashier getting money from a patient John
24+
25+
The patient has been already handled:
26+
27+
Patient registration already done
28+
Doctor checkup has been already done
29+
Medicine has been already given to a patient
30+
Payment done
31+
```
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
mod cashier;
2+
mod doctor;
3+
mod medical;
4+
mod reception;
5+
6+
pub use cashier::Cashier;
7+
pub use doctor::Doctor;
8+
pub use medical::Medical;
9+
pub use reception::Reception;
10+
11+
use crate::patient::Patient;
12+
13+
pub trait Department {
14+
fn execute(&mut self, patient: &mut Patient) {
15+
self.handle(patient);
16+
17+
if let Some(next) = &mut self.next() {
18+
next.execute(patient);
19+
}
20+
}
21+
22+
fn handle(&mut self, patient: &mut Patient);
23+
fn next(&mut self) -> &mut Option<Box<dyn Department>>;
24+
}
25+
26+
pub(self) fn into_next(department: impl Department + Sized + 'static) -> Option<Box<dyn Department>> {
27+
Some(Box::new(department))
28+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
use super::{Department, Patient};
2+
3+
#[derive(Default)]
4+
pub struct Cashier {
5+
next: Option<Box<dyn Department>>,
6+
}
7+
8+
impl Department for Cashier {
9+
fn handle(&mut self, patient: &mut Patient) {
10+
if patient.payment_done {
11+
println!("Payment done");
12+
} else {
13+
println!("Cashier getting money from a patient {}", patient.name);
14+
patient.payment_done = true;
15+
}
16+
}
17+
18+
fn next(&mut self) -> &mut Option<Box<dyn Department>> {
19+
&mut self.next
20+
}
21+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
use super::{Department, Patient, into_next};
2+
3+
pub struct Doctor {
4+
next: Option<Box<dyn Department>>,
5+
}
6+
7+
impl Doctor {
8+
pub fn new(next: impl Department + 'static) -> Self {
9+
Self { next: into_next(next) }
10+
}
11+
}
12+
13+
impl Department for Doctor {
14+
fn handle(&mut self, patient: &mut Patient) {
15+
if patient.doctor_check_up_done {
16+
println!("Doctor checkup has been already done");
17+
} else {
18+
println!("Doctor checking a patient {}", patient.name);
19+
patient.doctor_check_up_done = true;
20+
}
21+
}
22+
23+
fn next(&mut self) -> &mut Option<Box<dyn Department>> {
24+
&mut self.next
25+
}
26+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
use super::{Department, Patient, into_next};
2+
3+
pub struct Medical {
4+
next: Option<Box<dyn Department>>,
5+
}
6+
7+
impl Medical {
8+
pub fn new(next: impl Department + 'static) -> Self {
9+
Self { next: into_next(next) }
10+
}
11+
}
12+
13+
impl Department for Medical {
14+
fn handle(&mut self, patient: &mut Patient) {
15+
if patient.medicine_done {
16+
println!("Medicine has been already given to a patient");
17+
} else {
18+
println!("Medical giving medicine to a patient {}", patient.name);
19+
patient.medicine_done = true;
20+
}
21+
}
22+
23+
fn next(&mut self) -> &mut Option<Box<dyn Department>> {
24+
&mut self.next
25+
}
26+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
use super::{Department, Patient, into_next};
2+
3+
#[derive(Default)]
4+
pub struct Reception {
5+
next: Option<Box<dyn Department>>,
6+
}
7+
8+
impl Reception {
9+
pub fn new(next: impl Department + 'static) -> Self {
10+
Self { next: into_next(next) }
11+
}
12+
}
13+
14+
impl Department for Reception {
15+
fn handle(&mut self, patient: &mut Patient) {
16+
if patient.registration_done {
17+
println!("Patient registration already done");
18+
} else {
19+
println!("Reception registering a patient {}", patient.name);
20+
patient.registration_done = true;
21+
}
22+
}
23+
24+
fn next(&mut self) -> &mut Option<Box<dyn Department>> {
25+
&mut self.next
26+
}
27+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
mod department;
2+
mod patient;
3+
4+
use department::{Cashier, Department, Doctor, Medical, Reception};
5+
use patient::Patient;
6+
7+
fn main() {
8+
let cashier = Cashier::default();
9+
let medical = Medical::new(cashier);
10+
let doctor = Doctor::new(medical);
11+
let mut reception = Reception::new(doctor);
12+
13+
let mut patient = Patient {
14+
name: "John".into(),
15+
..Patient::default()
16+
};
17+
18+
reception.execute(&mut patient);
19+
20+
println!("\nThe patient has been already handled:\n");
21+
22+
reception.execute(&mut patient);
23+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#[derive(Default)]
2+
pub struct Patient {
3+
pub name: String,
4+
pub registration_done: bool,
5+
pub doctor_check_up_done: bool,
6+
pub medicine_done: bool,
7+
pub payment_done: bool,
8+
}

0 commit comments

Comments
 (0)