设计模式很依赖场景,通过场景也能更好理解这种模式解决了什么问题。
小明所在的公司内部有多个部门,每个部门下可能有不同的子部门或者员工。
请你设计一个组合模式来管理这些部门和员工,实现对公司组织结构的统一操作。部门和员工都具有一个通用的接口,可以获取他们的名称以及展示公司组织结构。
第一行是一个整数 N(1 <= N <= 100),表示后面有 N 行输入。
接下来的 N 行,每行描述一个部门或员工的信息。部门的信息格式为 D 部门名称,员工的信息格式为 E 员工名称,其中 D 或 E 表示部门或员工。
输出公司的组织结构,展示每个部门下的子部门和员工
MyCompany
8
D HR
E HRManager
D Finance
E AccountantA
E AccountantB
D IT
E DeveloperA
E DeveloperB
Company Structure:
MyCompany
HR
HRManager
Finance
AccountantA
AccountantB
IT
DeveloperA
DeveloperB
public interface Component {
String showName();
}
public class Company implements Component {
private final String name;
@Setter
private List<Department> departments;
public Company(String name) {
this.name = name;
}
public void addDepartment(Department department) {
if (CollectionUtils.isEmpty(departments)) {
departments = new ArrayList<>();
departments.add(department);
} else {
departments.add(department);
}
}
@Nullable
public Department gotLastDepartment() {
if (CollectionUtils.isEmpty(departments)) {
return null;
} else {
return departments.get(departments.size() - 1);
}
}
@Override
public String showName() {
return name;
}
public String showCompanyStructure() {
StringBuilder sb = new StringBuilder("Company Structure:\n").append(showName()).append("\n");
Optional.ofNullable(departments).ifPresent(departments -> departments.stream().filter(Objects::nonNull).forEach(department -> {
sb.append(" ").append(department.showName()).append("\n");
Optional.ofNullable(department.getEmployees()).ifPresent(employees -> {
employees.stream().forEach(
employee -> sb.append(" ").append(employee.showName()).append("\n")
);
});
}));
return sb.toString();
}
}
@Data
public class Department implements Component {
private String name;
private List<Employee> employees;
public Department(String name) {
this.name = name;
}
@Override
public String showName() {
return this.name;
}
public void addEmployee(Employee employee) {
if (CollectionUtils.isEmpty(employees)) {
employees = new ArrayList<>();
employees.add(employee);
} else {
employees.add(employee);
}
}
}
@AllArgsConstructor
public class Employee implements Component {
private String name;
@Override
public String showName() {
return name;
}
}
public class Application {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String companyName = scanner.nextLine();
Company company = new Company(companyName);
int n = scanner.nextInt();
for (int i = 0; i < n; i++) {
String type = scanner.next();
String name = scanner.next();
if (StringUtils.equals(type, "D")) {
company.addDepartment(new Department(name));
} else if (StringUtils.equals(type, "E")) {
Department department = company.gotLastDepartment();
department.addEmployee(new Employee(name));
}
}
System.out.printf(company.showCompanyStructure());
}
}
public class Company implements Component {
private final String name;
@Setter
private List<Department> departments;
}
public class Department implements Component {
private String name;
private List<Employee> employees;
}
public class Employee implements Component {
private String name;
}
// Company-Department (1 对 n)、Department-Employee(1对n)
class Composite implements Component {
private String name;
private List<Component> children;
}
// 这个便是Employee
class Leaf implements Component {
private String name;
}
public interface Component {
void display(int depth);
}
public class Department implements Component {
private String name;
private List<Component> children;
public Department(String name) {
this.name = name;
this.children = new ArrayList<>();
}
public void add(Component component) {
children.add(component);
}
@Override
public void display(int depth) {
StringBuilder indent = new StringBuilder();
for (int i = 0; i < depth; i++) {
indent.append(" ");
}
System.out.println(indent + name);
for (Component component : children) {
component.display(depth + 1);
}
}
}
public class Employee implements Component {
private String name;
public Employee(String name) {
this.name = name;
}
@Override
public void display(int depth) {
StringBuilder indent = new StringBuilder();
for (int i = 0; i < depth; i++) {
indent.append(" ");
}
System.out.println(indent + " " + name);
}
}
public class Company {
private String name;
private Department root;
public Company(String name) {
this.name = name;
this.root = new Department(name);
}
public void add(Component component) {
root.add(component);
}
public void display() {
System.out.println("Company Structure:");
root.display(0); // 从 1 开始,以适配指定的缩进格式
}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 读取公司名称
String companyName = scanner.nextLine();
Company company = new Company(companyName);
// 读取部⻔和员工数量
int n = scanner.nextInt();
scanner.nextLine(); // 消耗换行符
// 读取部⻔和员工信息
for (int i = 0; i < n; i++) {
String type = scanner.next();
String name = scanner.nextLine().trim();
if ("D".equals(type)) {
Department department = new Department(name);
company.add(department);
} else if ("E".equals(type)) {
Employee employee = new Employee(name);
company.add(employee);
}
}
// 输出公司组织结构
company.display();
}
}
MyCompany
HR
HRManager
Finance
AccountantA
AccountantB
IT
DeveloperA
DeveloperB
public class Employee implements Component {
...
@Override
public void display(int depth) {
StringBuilder indent = new StringBuilder();
for (int i = 0; i < depth; i++) {
indent.append(" ");
}
System.out.println(indent + " " + name); // 这里的depth实际上是1,因此作者多加了" "
}
}
显然,这并不是正确的实现。
public interface Component {
void showName(int depth);
}
public class Composite implements Component {
private String name;
private List<Component> children;
public Composite(String name) {
this.name = name;
children = new ArrayList<>();
}
public void addComponent(Component component) {
children.add(component);
}
public Composite gotLastComposite() {
if (!children.isEmpty()) {
Component component = children.get(children.size() - 1);
if (component instanceof Composite) {
return (Composite) component;
} else {
throw new RuntimeException("last component is not composite");
}
} else {
throw new RuntimeException("doesn't exist last component");
}
}
@Override
public void showName(int depth) {
System.out.println(StringUtils.repeat(" ", depth) + name);
for (Component child : children) {
child.showName(depth + 1);
}
}
}
@AllArgsConstructor
public class Employee implements Component {
private String name;
@Override
public void showName(int depth) {
System.out.println(StringUtils.repeat(" ", depth) + name);
}
}
public class Company extends Composite {
public Company(String name) {
super(name);
}
@Override
public void showName(int depth) {
System.out.println("Company Structure:");
super.showName(depth);
}
}
public class Application {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String companyName = scanner.nextLine();
Company company = new Company(companyName);
int n = scanner.nextInt();
for (int i = 0; i < n; i++) {
String type = scanner.next();
String name = scanner.next();
if (StringUtils.equals(type, "D")) {
company.addComponent(new Composite(name));
} else if (StringUtils.equals(type, "E")) {
Composite department = company.gotLastComposite();
department.addComponent(new Employee(name));
}
}
company.showName(0);
}
}
class Composite implements Component {
private String name;
private List<Component> children;
}
// 这个便是Employee
class Leaf implements Component {
private String name;
}
组合模式:实现接口A + 组合多个接口A
public class EncryptDataSourceImpl implements DataSource {
private DataSource dataSource;
}
public class Circle implements Shape {
private Color color;
}