Padrão de design composto em Java
1. Introdução
Neste tutorial rápido, apresentaremos o padrão de design composto em Java.
Vamos descrever a estrutura e a finalidade de seu uso.
2. A estrutura
O padrão composto destina-se a permitir o tratamento de objetos individuais e composições de objetos, ou "compostos" da mesma maneira.
Ele pode ser visto como uma estrutura em árvore composta de tipos que herdam um tipo de base e pode representar uma única parte ou uma hierarquia inteira de objetos.
Podemos dividir o padrão em:
-
component - é a interface base para todos os objetos na composição. Deve ser uma interface ou uma classe abstrata com os métodos comuns para gerenciar os compostos filhos.
-
leaf - implementa o comportamento padrão do componente base. Ele não contém uma referência aos outros objetos.
-
composto - possui elementos foliares. Ele implementa os métodos do componente base e define as operações relacionadas a filhos.
-
client - tem acesso aos elementos da composição usando o objeto do componente base.
3. Exemplo Prático
Agora, vamos mergulhar na implementação. Vamos suporwe want to build a hierarchical structure of departments in a company.
3.1. O Componente Base
Como um objeto de componente, definiremos uma interfaceDepartment simples:
public interface Department {
void printDepartmentName();
}
3.2. Leafs
Para os componentes folha, vamos definir classes para os departamentos financeiro e de vendas:
public class FinancialDepartment implements Department {
private Integer id;
private String name;
public void printDepartmentName() {
System.out.println(getClass().getSimpleName());
}
// standard constructor, getters, setters
}
A segunda classe folha,SalesDepartment, é semelhante:
public class SalesDepartment implements Department {
private Integer id;
private String name;
public void printDepartmentName() {
System.out.println(getClass().getSimpleName());
}
// standard constructor, getters, setters
}
Ambas as classes implementam o métodoprintDepartmentName() a partir do componente base, onde imprimem os nomes das classes para cada uma delas.
Além disso, como são classes folha, não contêm outros objetosDepartment.
A seguir, vamos ver uma classe composta também.
3.3. O Elemento Composto
Como uma classe composta, vamos criar uma classeHeadDepartment:
public class HeadDepartment implements Department {
private Integer id;
private String name;
private List childDepartments;
public HeadDepartment(Integer id, String name) {
this.id = id;
this.name = name;
this.childDepartments = new ArrayList<>();
}
public void printDepartmentName() {
childDepartments.forEach(Department::printDepartmentName);
}
public void addDepartment(Department department) {
childDepartments.add(department);
}
public void removeDepartment(Department department) {
childDepartments.remove(department);
}
}
This is a composite class as it holds a collection of Department components, bem como métodos para adicionar e remover elementos da lista.
O métodoprintDepartmentName() composto é implementado iterando sobre a lista de elementos folha e invocando o método apropriado para cada um.
4. Teste
Para fins de teste, vamos dar uma olhada em uma classeCompositeDemo:
public class CompositeDemo {
public static void main(String args[]) {
Department salesDepartment = new SalesDepartment(
1, "Sales department");
Department financialDepartment = new FinancialDepartment(
2, "Financial department");
HeadDepartment headDepartment = new HeadDepartment(
3, "Head department");
headDepartment.addDepartment(salesDepartment);
headDepartment.addDepartment(financialDepartment);
headDepartment.printDepartmentName();
}
}
Primeiro, criamos duas instâncias para os departamentos financeiro e de vendas. Depois, instanciamos o departamento principal e adicionamos nele as instâncias criadas anteriormente.
Finalmente, podemos testar o método de composiçãoprintDepartmentName(). Como esperamos,the output contains the class names of each leaf component:
SalesDepartment
FinancialDepartment
5. Conclusão
Neste artigo, aprendemos sobre o padrão de design composto. O artigo destaca a estrutura principal e demonstra o uso através do exemplo prático.
Como de costume, o código completo está disponível emGithub project.