Skip to content

Commit 803df38

Browse files
committed
chore: Refactor markdown content and code structure in Stock Market Monitor
1 parent 943cc93 commit 803df38

File tree

3 files changed

+137
-26
lines changed

3 files changed

+137
-26
lines changed

DesignModule04/Observer.rs

+45-7
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,57 @@
11
use std::cell::RefCell;
2+
use std::rc::Rc;
23

3-
fn main()
4-
{
4+
struct WeatherStation {
5+
observers: Vec<Rc<RefCell<dyn Observer>>>,
6+
}
7+
8+
impl WeatherStation {
9+
fn new() -> Self {
10+
WeatherStation {
11+
observers: Vec::new(),
12+
}
13+
}
14+
15+
fn add_observer(&mut self, observer: Rc<RefCell<dyn Observer>>) {
16+
self.observers.push(observer);
17+
}
18+
19+
fn set_measurements(&self, temperature: f32, humidity: f32) {
20+
for observer in &self.observers {
21+
observer.borrow_mut().update(temperature, humidity);
22+
}
23+
}
24+
}
25+
26+
trait Observer {
27+
fn update(&self, temperature: f32, humidity: f32);
28+
}
29+
30+
struct DisplayDevice {
31+
name: String,
32+
}
33+
34+
impl Observer for DisplayDevice {
35+
fn update(&self, temperature: f32, humidity: f32) {
36+
println!(
37+
"{}: Temperature = {}°C, Humidity = {}%",
38+
self.name, temperature, humidity
39+
);
40+
}
41+
}
42+
43+
fn main() {
544
let mut weather_station = WeatherStation::new();
6-
let display1 = Rc::new(RefCell::new(DisplayDevice{
45+
let display1 = Rc::new(RefCell::new(DisplayDevice {
746
name: String::from("Display 1"),
847
}));
9-
let display2 = Rc::new(RefCell::new(DisplayDevice{
48+
let display2 = Rc::new(RefCell::new(DisplayDevice {
1049
name: String::from("Display 2"),
1150
}));
1251

13-
weather_station.add_observer(display1);
14-
weather_station.add_observer(display2);
52+
weather_station.add_observer(display1.clone());
53+
weather_station.add_observer(display2.clone());
1554

1655
weather_station.set_measurements(25.5, 60.0);
1756
weather_station.set_measurements(26.0, 58.5);
18-
1957
}

DesignModule04/StockMarket/src/README.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
# Stock Market Monitor (Observer Pattern)
22

3-
This project demonstrates the implementation of the Observer pattern in Rust using a Stock Market monitoring system as a real-world example.
3+
This markdown content has been refactored:
44

55
## Overview
66

7-
The Stock Market Monitor allows multiple observers (displays and alert systems) to receive updates whenever stock prices change. This showcases how the Observer pattern can be used to implement a publish-subscribe model.
7+
This project showcases the implementation of the Observer pattern in Rust using a Stock Market monitoring system as an example.
88

99
## Features
1010

1111
- Real-time updates of stock prices to multiple observers
12-
- Different types of observers (displays and alert systems)
12+
- Support for different types of observers (displays and alert systems)
1313
- Easy addition of new observers
1414

1515
## Mermaid Diagram
@@ -81,4 +81,4 @@ stock_market.set_price("AAPL", 150.0);
8181

8282
## Notes
8383

84-
The Observer pattern is excellent for implementing distributed event handling systems. It's widely used in implementing distributed event handling systems, MVC architectural pattern, and in designing user interface toolkits. However, if overused, it can lead to complex systems where observers are difficult to track and maintain.
84+
The Observer pattern is excellent for implementing distributed event handling systems. It's widely used in implementing distributed event handling systems, MVC architectural pattern, and in designing user interface toolkits. However, if overused, it can lead to complex systems where observers are difficult to track and maintain.
+88-15
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
11
use std::collections::HashMap;
2-
use std::cell::RefCell;
32
use std::rc::Rc;
3+
use std::borrow::Cow;
44

55
// Observer trait
66
trait StockObserver {
7-
fn update(&self, symbol: &str, price: f64);
7+
fn update(&self, symbol: Cow<str>, price: f64);
88
}
99

1010
// Subject (Observable)
1111
struct StockMarket {
1212
prices: HashMap<String, f64>,
13-
observers: Vec<Rc<RefCell<dyn StockObserver>>>,
13+
observers: Vec<Rc<dyn StockObserver>>,
1414
}
1515

1616
impl StockMarket {
1717
fn new() -> Self {
1818
StockMarket {
19-
prices: HashMap::new(),
20-
observers: Vec::new(),
19+
prices: HashMap::with_capacity(10),
20+
observers: Vec::with_capacity(10),
2121
}
2222
}
2323

24-
fn add_observer(&mut self, observer: Rc<RefCell<dyn StockObserver>>) {
24+
fn add_observer(&mut self, observer: Rc<dyn StockObserver>) {
2525
self.observers.push(observer);
2626
}
2727

@@ -31,8 +31,9 @@ impl StockMarket {
3131
}
3232

3333
fn notify_observers(&self, symbol: &str, price: f64) {
34+
let symbol = Cow::Borrowed(symbol);
3435
for observer in &self.observers {
35-
observer.borrow().update(symbol, price);
36+
observer.update(symbol.clone(), price);
3637
}
3738
}
3839
}
@@ -43,7 +44,7 @@ struct PriceDisplay {
4344
}
4445

4546
impl StockObserver for PriceDisplay {
46-
fn update(&self, symbol: &str, price: f64) {
47+
fn update(&self, symbol: Cow<str>, price: f64) {
4748
println!("{}: {} stock updated to ${:.2}", self.name, symbol, price);
4849
}
4950
}
@@ -53,7 +54,7 @@ struct AlertSystem {
5354
}
5455

5556
impl StockObserver for AlertSystem {
56-
fn update(&self, symbol: &str, price: f64) {
57+
fn update(&self, symbol: Cow<str>, price: f64) {
5758
if price > self.threshold {
5859
println!("ALERT: {} stock price ${:.2} exceeds threshold ${:.2}", symbol, price, self.threshold);
5960
}
@@ -63,15 +64,15 @@ impl StockObserver for AlertSystem {
6364
fn main() {
6465
let mut stock_market = StockMarket::new();
6566

66-
let display1 = Rc::new(RefCell::new(PriceDisplay {
67+
let display1 = Rc::new(PriceDisplay {
6768
name: String::from("Display 1"),
68-
}));
69-
let display2 = Rc::new(RefCell::new(PriceDisplay {
69+
});
70+
let display2 = Rc::new(PriceDisplay {
7071
name: String::from("Display 2"),
71-
}));
72-
let alert_system = Rc::new(RefCell::new(AlertSystem {
72+
});
73+
let alert_system = Rc::new(AlertSystem {
7374
threshold: 100.0,
74-
}));
75+
});
7576

7677
stock_market.add_observer(display1);
7778
stock_market.add_observer(display2);
@@ -82,4 +83,76 @@ fn main() {
8283
stock_market.set_price("GOOGL", 1330.0);
8384
stock_market.set_price("MSFT", 95.0);
8485
stock_market.set_price("MSFT", 120.0);
86+
}
87+
88+
#[cfg(test)]
89+
mod tests {
90+
use super::*;
91+
92+
#[test]
93+
fn test_stock_market() {
94+
let mut stock_market = StockMarket::new();
95+
96+
let display1 = Rc::new(PriceDisplay {
97+
name: String::from("Display 1"),
98+
});
99+
let display2 = Rc::new(PriceDisplay {
100+
name: String::from("Display 2"),
101+
});
102+
let alert_system = Rc::new(AlertSystem {
103+
threshold: 100.0,
104+
});
105+
106+
stock_market.add_observer(display1);
107+
stock_market.add_observer(display2);
108+
stock_market.add_observer(alert_system);
109+
110+
stock_market.set_price("AAPL", 15.0);
111+
stock_market.set_price("GOOGL", 1330.0);
112+
stock_market.set_price("MSFT", 95.0);
113+
stock_market.set_price("MSFT", 120.0);
114+
}
115+
116+
#[test]
117+
fn test_price_display() {
118+
let display = PriceDisplay {
119+
name: String::from("Display 1"),
120+
};
121+
display.update(Cow::Borrowed("AAPL"), 15.0);
122+
}
123+
124+
#[test]
125+
fn test_alert_system() {
126+
let alert = AlertSystem {
127+
threshold: 100.0,
128+
};
129+
alert.update(Cow::Borrowed("AAPL"), 105.0);
130+
}
131+
132+
#[test]
133+
fn test_stock_observer() {
134+
let display = PriceDisplay {
135+
name: String::from("Display 1"),
136+
};
137+
let observer: &dyn StockObserver = &display;
138+
observer.update(Cow::Borrowed("AAPL"), 15.0);
139+
}
140+
141+
#[test]
142+
fn test_stock_observer_vec() {
143+
let display1 = Rc::new(PriceDisplay {
144+
name: String::from("Display 1"),
145+
});
146+
let display2 = Rc::new(PriceDisplay {
147+
name: String::from("Display 2"),
148+
});
149+
150+
let mut observers: Vec<Rc<dyn StockObserver>> = Vec::new();
151+
observers.push(display1);
152+
observers.push(display2);
153+
154+
for observer in &observers {
155+
observer.update(Cow::Borrowed("AAPL"), 15.0);
156+
}
157+
}
85158
}

0 commit comments

Comments
 (0)