diff --git a/README.md b/README.md index d05e204..b2aec92 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Relativos al proceso de creación de un objeto. Composición de clases u objetos. -* Nothing yet. +* [Composite](#composite) ### Patrones de Comportamiento (Behavioral Patterns) @@ -97,3 +97,20 @@ Es una jerarquía que encapsula muchas *familias* posibles y la creación de un * [Ovnis](https://github.com/LuisBurgos/design-patterns/tree/master/src/abstractfactory/examples/ufo) * [El Reino](https://github.com/LuisBurgos/design-patterns/tree/master/src/abstractfactory/examples/kingdom) + +## Composite [↑](#lista-de-patrones) + +**Propósito:** Componer objetos en estructuras de árbol que representan jerarquías de un **todo** y sus **partes.** El Composite provee a los *clientes* un mismo trato para todos los objetos que forman la jerarquía. + +Pensemos en nuestro sistema de archivos, este contiene *directorios* con *archivos* y a su vez estos *archivos* pueden ser otros *directorios* que contenga más *archivos*, y así sucesivamente. Lo anterior puede ser representado facilmente con el patrón Composite. + +**Aplicación:** Usamos el patrón Composite... +* Cuando queremos representar jerarquías de objetos +compuestas por un todo y sus partes. +* Se quiere que los *clientes* ignoren la diferencia +entre la composición de objetos y su uso +individual. + +**Ejemplos:** +* [Menu](https://github.com/LuisBurgos/design-patterns/tree/master/src/composite/examples/menu) +* [Sistema de Archivos](https://github.com/LuisBurgos/design-patterns/tree/master/src/composite/examples/directories) diff --git a/src/composite/examples/directories/Directory.java b/src/composite/examples/directories/Directory.java new file mode 100644 index 0000000..29d7f21 --- /dev/null +++ b/src/composite/examples/directories/Directory.java @@ -0,0 +1,38 @@ +package composite.examples.directories; + +import java.util.ArrayList; + +/** + * Created by luisburgos on 18/07/15. + */ +public class Directory extends File { + + private ArrayList files; + + public Directory (String name) { + this.name = name; + files = new ArrayList<>(); + } + + @Override + public void add(File file) { + files.add(file); + } + + @Override + public void remove(File file) { + files.remove(file); + } + + @Override + public void showInfo() { + System.out.print(identado.toString() + "* Directory: " + getName() + "\n"); + identado.append(" "); + for(File file : files){ + file.showInfo(); + } + identado.setLength(identado.length() - 3); + } + + +} diff --git a/src/composite/examples/directories/File.java b/src/composite/examples/directories/File.java new file mode 100644 index 0000000..e57b9e5 --- /dev/null +++ b/src/composite/examples/directories/File.java @@ -0,0 +1,27 @@ +package composite.examples.directories; + +/** + * Created by luisburgos on 18/07/15. + */ +public abstract class File { + + protected String name; + protected static StringBuffer identado = new StringBuffer(); + + public void add(File component) { + throw new UnsupportedOperationException(); + } + + public void remove(File component) { + throw new UnsupportedOperationException(); + } + + public String getName() { + return name; + } + + public void showInfo() { + throw new UnsupportedOperationException(); + } + +} diff --git a/src/composite/examples/directories/FileSystem.java b/src/composite/examples/directories/FileSystem.java new file mode 100644 index 0000000..fe92a49 --- /dev/null +++ b/src/composite/examples/directories/FileSystem.java @@ -0,0 +1,19 @@ +package composite.examples.directories; + +/** + * Created by luisburgos on 18/07/15. + */ +public class FileSystem { + + private File allFiles; + + public FileSystem(File allFiles) { + this.allFiles = allFiles; + } + + public void printFiles() { + allFiles.showInfo(); + } + + +} diff --git a/src/composite/examples/directories/FileSystemTestDrive.java b/src/composite/examples/directories/FileSystemTestDrive.java new file mode 100644 index 0000000..b9e5ed2 --- /dev/null +++ b/src/composite/examples/directories/FileSystemTestDrive.java @@ -0,0 +1,34 @@ +package composite.examples.directories; + +/** + * Created by luisburgos on 18/07/15. + */ +public class FileSystemTestDrive { + + public static void main(String[] args) { + + //Dummy linux file system. + + File home = new Directory("home"); + File opt = new Directory("opt"); + File usr = new Directory("usr"); + + File root = new Directory("root"); + + root.add(home); + root.add(opt); + root.add(usr); + + usr.add(new SimpleFile("bin")); + usr.add(new SimpleFile("lib")); + + opt.add(new SimpleFile("google")); + opt.add(new SimpleFile("idea")); + opt.add(new SimpleFile("spotify")); + + home.add(new SimpleFile("luisburgos")); + + FileSystem fileSystem = new FileSystem(root); + fileSystem.printFiles(); + } +} diff --git a/src/composite/examples/directories/SimpleFile.java b/src/composite/examples/directories/SimpleFile.java new file mode 100644 index 0000000..3b295c8 --- /dev/null +++ b/src/composite/examples/directories/SimpleFile.java @@ -0,0 +1,16 @@ +package composite.examples.directories; + +/** + * Created by luisburgos on 18/07/15. + */ +public class SimpleFile extends File { + + public SimpleFile(String name) { + this.name = name; + } + + @Override + public void showInfo() { + System.out.print(identado.toString() + "-Simple File: " + getName() + "\n"); + } +} diff --git a/src/composite/examples/menu/Client.java b/src/composite/examples/menu/Client.java new file mode 100644 index 0000000..7054acc --- /dev/null +++ b/src/composite/examples/menu/Client.java @@ -0,0 +1,14 @@ +package composite.examples.menu; + +public class Client { + + private MenuComponent allMenus; + + public Client(MenuComponent todosLosMenus) { + this.allMenus = todosLosMenus; + } + + public void printMenu() { + allMenus.print(); + } +} diff --git a/src/composite/examples/menu/MenuComponent.java b/src/composite/examples/menu/MenuComponent.java new file mode 100644 index 0000000..99e033f --- /dev/null +++ b/src/composite/examples/menu/MenuComponent.java @@ -0,0 +1,31 @@ +package composite.examples.menu; + +public abstract class MenuComponent { + + protected String name; + protected static StringBuffer identado = new StringBuffer(); + + public void add(MenuComponent component) { + throw new UnsupportedOperationException(); + } + + public void remove(MenuComponent component) { + throw new UnsupportedOperationException(); + } + + public String getName() { + throw new UnsupportedOperationException(); + } + + public double getPrice() { + throw new UnsupportedOperationException(); + } + + public boolean isVegetarian() { + throw new UnsupportedOperationException(); + } + + public void print() { + throw new UnsupportedOperationException(); + } +} diff --git a/src/composite/examples/menu/MenuComposite.java b/src/composite/examples/menu/MenuComposite.java new file mode 100644 index 0000000..f4843c7 --- /dev/null +++ b/src/composite/examples/menu/MenuComposite.java @@ -0,0 +1,40 @@ +package composite.examples.menu; + +import java.util.ArrayList; + +public class MenuComposite extends MenuComponent { + + private ArrayList menuComponents; + + public MenuComposite(String name) { + this.name = name; + menuComponents = new ArrayList<>(); + } + + @Override + public void add(MenuComponent component) { + this.menuComponents.add(component); + } + + @Override + public void remove(MenuComponent component) { + this.menuComponents.remove(component); + } + + @Override + public String getName() { + return this.name; + } + + @Override + public void print() { + + System.out.print(identado.toString() + "* " + getName() + "\n"); + //System.out.println(identado.toString() + "---------------------"); + identado.append(" "); + for(MenuComponent menuComponent : menuComponents){ + menuComponent.print(); + } + identado.setLength(identado.length() - 5); + } +} diff --git a/src/composite/examples/menu/MenuItem.java b/src/composite/examples/menu/MenuItem.java new file mode 100644 index 0000000..23b7fb3 --- /dev/null +++ b/src/composite/examples/menu/MenuItem.java @@ -0,0 +1,47 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package composite.examples.menu; + +/** + * + * @author luisburgos + */ +public class MenuItem extends MenuComponent { + + private boolean vegetarian; + private double price; + + public MenuItem(String name, boolean vegetarian, double price) { + this.name = name; + this.vegetarian = vegetarian; + this.price = price; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public double getPrice() { + return this.price; + } + + @Override + public boolean isVegetarian() { + return this.vegetarian; + } + + @Override + public void print() { + System.out.print(identado.toString() + "# " + getName()); + if (isVegetarian()) { + System.out.print("(v)"); + } + System.out.println("," + getPrice()); + } + +} diff --git a/src/composite/examples/menu/MenuTestDrive.java b/src/composite/examples/menu/MenuTestDrive.java new file mode 100644 index 0000000..387fb94 --- /dev/null +++ b/src/composite/examples/menu/MenuTestDrive.java @@ -0,0 +1,58 @@ +package composite.examples.menu; + +public class MenuTestDrive { + + + public static void main(String args[]) { + + MenuComponent meals = new MenuComposite("Comidas"); + MenuComponent dinners = new MenuComposite("Cenas"); + MenuComponent desserts = new MenuComposite("Postres"); + MenuComponent mainCourse = new MenuComposite("Plato Fuerte"); + + MenuComponent allMenus = new MenuComposite("Menus"); + + allMenus.add(meals); + allMenus.add(dinners); + + meals.add(mainCourse); + meals.add(desserts); + + mainCourse.add(new MenuItem( + "Crispy Chicken", + false, + 100.89) + ); + + desserts.add(new MenuItem( + "Apple Pie", + false, + 15.59) + ); + + desserts.add(new MenuItem( + "Cheesecake", + false, + 19.99) + ); + + dinners.add(new MenuItem( + "Hotdogs", + false, + 6.05) + ); + + dinners.add(new MenuItem( + "Spaghetti ", + true, + 30.89) + ); + + + //The client does not distinguish between item and composite + Client client = new Client(allMenus); + client.printMenu(); + + } + +} diff --git a/src/composite/pattern/Component.java b/src/composite/pattern/Component.java new file mode 100644 index 0000000..67518d2 --- /dev/null +++ b/src/composite/pattern/Component.java @@ -0,0 +1,22 @@ +package composite.pattern; + +/** + * Created by luisburgos on 18/07/15. + */ +public abstract class Component { + + protected String name; + + public void add(Component component) { + throw new UnsupportedOperationException(); + } + public void remove(Component component) { + throw new UnsupportedOperationException(); + } + public abstract void doSomething(); + + public String getName() { + return name; + } + +} diff --git a/src/composite/pattern/Composite.java b/src/composite/pattern/Composite.java new file mode 100644 index 0000000..272dd15 --- /dev/null +++ b/src/composite/pattern/Composite.java @@ -0,0 +1,34 @@ +package composite.pattern; + +import java.util.ArrayList; + +/** + * Created by luisburgos on 18/07/15. + */ +public class Composite extends Component{ + + private ArrayList components; + + public Composite(String name) { + this.name = name; + components = new ArrayList<>(); + } + + @Override + public void add(Component component) { + components.add(component); + } + + @Override + public void remove(Component component) { + components.remove(component); + } + + @Override + public void doSomething() { + System.out.println(getName() + " doing something..."); + for(Component component : components){ + component.doSomething(); + } + } +} diff --git a/src/composite/pattern/CompositeTest.java b/src/composite/pattern/CompositeTest.java new file mode 100644 index 0000000..2b910a0 --- /dev/null +++ b/src/composite/pattern/CompositeTest.java @@ -0,0 +1,37 @@ +package composite.pattern; + +/** + * Created by luisburgos on 18/07/15. + */ +public class CompositeTest { + + public static void main(String[] args) { + + Component componentOne = new Composite("Composite One"); + Component componentTwo = new Composite("Composite Two"); + Component componentThree = new Composite("Composite Three"); + + Component componentWrapper = new Composite("All components"); + + componentWrapper.add(componentOne); + componentWrapper.add(componentTwo); + componentWrapper.add(componentThree); + + componentOne.add(new Leaf("ONE: Sub component one")); + componentOne.add(new Leaf("ONE: Sub component two")); + componentOne.add(new Leaf("ONE: Sub component three")); + + componentTwo.add(new Leaf("TWO: Sub component one")); + componentTwo.add(new Leaf("TWO: Sub component two")); + + componentThree.add(new Leaf("THREE: Sub component one")); + componentThree.add(new Leaf("THREE: Sub component two")); + componentThree.add(new Leaf("THREE: Sub component three")); + componentThree.add(new Leaf("THREE: Sub component four")); + + + componentWrapper.doSomething(); + + } + +} diff --git a/src/composite/pattern/Leaf.java b/src/composite/pattern/Leaf.java new file mode 100644 index 0000000..495bf30 --- /dev/null +++ b/src/composite/pattern/Leaf.java @@ -0,0 +1,16 @@ +package composite.pattern; + +/** + * Created by luisburgos on 18/07/15. + */ +public class Leaf extends Component{ + + public Leaf(String name) { + this.name = name; + } + + @Override + public void doSomething() { + System.out.println(" " + getName() + " doing something..."); + } +}