Composite Pattern
Composes objects into tree structures to represent part-whole hierarchies. It treats individual objects and compositions of objects uniformly, simplifying the interaction between them.
Example
// Define a trait for the nodes in the tree trait Node { fn get_name(&self) -> &str; fn add_child(&mut self, child: Box<dyn Node>); fn print(&self, depth: usize); } // Implementation of a leaf node representing a file struct File { name: String, } impl File { // Create a new File node with the given name fn new(name: String) -> Self { File { name } } } impl Node for File { // Get the name of the file fn get_name(&self) -> &str { &self.name } // Since a file cannot have children, this method does nothing fn add_child(&mut self, _child: Box<dyn Node>) { // Files cannot have children, so this method is empty } // Print the name of the file fn print(&self, depth: usize) { // Indent the output based on the depth in the tree structure println!("{}{}", "-".repeat(depth), self.name); } } // Implementation of a composite node representing a directory struct Directory { name: String, children: Vec<Box<dyn Node>>, } impl Directory { // Create a new Directory node with the given name fn new(name: String) -> Self { Directory { name, children: Vec::new(), } } } impl Node for Directory { // Get the name of the directory fn get_name(&self) -> &str { &self.name } // Add a child node to the directory fn add_child(&mut self, child: Box<dyn Node>) { self.children.push(child); } // Print the name of the directory and recursively print its children fn print(&self, depth: usize) { // Indent the output based on the depth in the tree structure println!("{}{}", "-".repeat(depth), self.name); // Recursively print the children nodes for child in &self.children { child.print(depth + 1); } } } fn main() { // Create the tree structure let mut root = Directory::new("Root".to_string()); let mut subdirectory1 = Directory::new("Subdirectory 1".to_string()); let mut subdirectory2 = Directory::new("Subdirectory 2".to_string()); let file1 = Box::new(File::new("File 1".to_string())); let file2 = Box::new(File::new("File 2".to_string())); let file3 = Box::new(File::new("File 3".to_string())); // Add files and subdirectories to the parent directories subdirectory1.add_child(file1); subdirectory1.add_child(file2); subdirectory2.add_child(file3); root.add_child(Box::new(subdirectory1)); root.add_child(Box::new(subdirectory2)); // Print the entire tree structure root.print(0); }