组合模式的典型例子通常涉及到树形结构的处理,下面是几个形象且易于理解的例子:
文件系统
在文件系统中,目录可以包含文件或者其他目录,但是从用户的角度来看,目录和文件都可以被"打开"或者"获取大小"。这里的目录就是一个组合对象,文件是叶子节点。
java
interface FileSystemItem {
void showProperties();
long getSize();
}
class File implements FileSystemItem {
private String name;
private long size;
public File(String name, long size) {
this.name = name;
this.size = size;
}
@Override
public void showProperties() {
System.out.println("File: " + name + " (Size: " + size + ")");
}
@Override
public long getSize() {
return size;
}
}
class Directory implements FileSystemItem {
private String name;
private List<FileSystemItem> children = new ArrayList<>();
public Directory(String name) {
this.name = name;
}
public void add(FileSystemItem item) {
children.add(item);
}
@Override
public void showProperties() {
System.out.println("Directory: " + name);
for (FileSystemItem child : children) {
child.showProperties();
}
}
@Override
public long getSize() {
long size = 0;
for (FileSystemItem child : children) {
size += child.getSize();
}
return size;
}
}
图形界面组件
在图形用户界面(GUI)中,容器组件可以包含其他容器组件或者叶子组件(如按钮、文本框等)。无论是容器还是叶子组件,都可以对它们执行某些操作,如绘制、启用/禁用等。
java
interface GUIComponent {
void render();
}
class Button implements GUIComponent {
@Override
public void render() {
System.out.println("Render Button");
}
}
class Panel implements GUIComponent {
private List<GUIComponent> children = new ArrayList<>();
public void add(GUIComponent component) {
children.add(component);
}
@Override
public void render() {
System.out.println("Render Panel");
for (GUIComponent child : children) {
child.render();
}
}
}
组织结构
在组织结构中,公司可以分为部门,部门下可以有子部门或员工。部门和员工都可以执行某些操作,如获取成本。
java
interface OrganizationComponent {
void printStructure();
double getCost();
}
class Employee implements OrganizationComponent {
private String name;
private double salary;
public Employee(String name, double salary) {
this.name = name;
this.salary = salary;
}
@Override
public void printStructure() {
System.out.println("Employee: " + name + ", Salary: " + salary);
}
@Override
public double getCost() {
return salary;
}
}
class Department implements OrganizationComponent {
private String name;
private List<OrganizationComponent> members = new ArrayList<>();
public Department(String name) {
this.name = name;
}
public void add(OrganizationComponent component) {
members.add(component);
}
@Override
public void printStructure() {
System.out.println("Department: " + name);
for (OrganizationComponent member : members) {
member.printStructure();
}
}
@Override
public double getCost() {
double cost = 0;
for (OrganizationComponent member : members) {
cost += member.getCost();
}
return cost;
}
}
在这些例子中,组合模式允许客户端以统一的方式操作单个对象和组合对象,这样的设计简化了客户端代码,并使得整个结构更加灵活。