exercises

Log | Files | Refs | README

index.md (3974B)


      1 ---
      2 title: Design Patterns and Best Practices in Rust
      3 ---
      4 
      5 Rust exercises following the book Design Patterns and Best Practices in Rust -
      6 Evan Williams
      7 
      8 Learning by doing a few bad examples and a few good examples.
      9 
     10 ## Bad Examples with Anti-Patterns in Rust using OOP
     11 
     12 #### Use Box<dyn Operand> dynamic dispatch everywhere, end up writing a lot of code to force OOP class and interface polymorphism:
     13 
     14 > [!info] Bad Calculator - Source Code:
     15 > [exercises/design_patterns_in_rust/bad_calculator/src/main.rs](https://github.com/ling0x/notes/blob/main/content/exercises/design_patterns_in_rust/bad_calculator/src/main.rs)
     16 
     17 #### Leverage enums to perform the same functions but more concisely:
     18 
     19 > [!info] Not So Bad Calculator - Source Code:
     20 > [exercises/design_patterns_in_rust/not_so_bad_calculator/src/main.rs](https://github.com/ling0x/notes/blob/main/content/exercises/design_patterns_in_rust/not_so_bad_calculator/src/main.rs)
     21 
     22 #### Use OO constructors and store more data inside enums to make it more generic that resulted in silent errors:
     23 
     24 > [!info] Slightly Worse Calculator - Source Code:
     25 > [exercises/design_patterns_in_rust/slightly_worse_calculator/src/main.rs](https://github.com/ling0x/notes/blob/main/content/exercises/design_patterns_in_rust/slightly_worse_calculator/src/main.rs)
     26 
     27 #### Overuse enums and sub-enums to scale the code to more use cases end up with code that is very difficult to work with:
     28 
     29 > [!info] The Worst Calculator - Source Code:
     30 > [exercises/design_patterns_in_rust/the_worst_calculator/src/main.rs](https://github.com/ling0x/notes/blob/main/content/exercises/design_patterns_in_rust/the_worst_calculator/src/main.rs)
     31 
     32 ### Examples for ownership and lifetime management
     33 
     34 The advantages the better example offers that the bad examples don't:
     35 
     36 - Clear ownership semantics: Each component should own its data directly, with
     37   no unnecessary indirection
     38 - Explicit state management: The struct keeps related data together
     39 - Better error handling: Use Result types to handle errors explicitly
     40 - Thread-safety when needed: Instead of sprinkling Rc and RefCell throughout the
     41   code, we provide a separate thread-safe wrapper when concurrent access is
     42   required.
     43 - Simpler mental model: We can reason about data flow more easily because
     44   ownership and mutation are explicit
     45 - Better performance: We avoid the overhead of reference counting and runtime
     46   borrowing checks in the common case
     47 
     48 > [!info] Source Code:
     49 > [exercises/design_patterns_in_rust/bad_calculator_2/src/main.rs](https://github.com/ling0x/notes/blob/main/content/exercises/design_patterns_in_rust/bad_calculator_2/src/main.rs)
     50 
     51 ### These examples demonstrate the anti-pattern of using `unsafe` and `global statics` to fight the borrow checker and how they can be refactored to work with Rust's ownership system.
     52 
     53 - Separate concerns by phase: parse first, then process, then store. Each phase
     54   should complete before the next begins.
     55 - Use indices instead of references
     56 - Let data flow downward
     57 - Question whether you need interior mutability
     58 - Keep mutable state local
     59 - Trust the borrow checker's feedback
     60 
     61 > [!info] Source Code:
     62 > [exercises/design_patterns_in_rust/bad_calculator_3/src/main.rs](https://github.com/ling0x/notes/blob/main/content/exercises/design_patterns_in_rust/bad_calculator_3/src/main.rs)
     63 
     64 ## The Gang of Four design patterns
     65 
     66 ### Creational patterns
     67 
     68 - Abstract Factory
     69 - Builder Pattern
     70 - Prototype Pattern
     71 
     72 > [!info] Source Code:
     73 > [exercises/design_patterns_in_rust/creational_patterns/src/main.rs](https://github.com/ling0x/notes/blob/main/content/exercises/design_patterns_in_rust/creational_patterns/src/main.rs)
     74 
     75 ### Structural patterns
     76 
     77 - Proxies, decorators, and adapters
     78 - Facades
     79 - Composites
     80 - Flyweight
     81 - The Bridge pattern
     82 
     83 > [!info] Source Code:
     84 > [exercises/design_patterns_in_rust/structural_patterns/src/main.rs](https://github.com/ling0x/notes/blob/main/content/exercises/design_patterns_in_rust/structural_patterns/src/main.rs)