我想实现一个复合模式Java
,以便映射一个软件开发组织。因此,假设有多个项目经理和多个开发人员。每个开发人员仅分配给一个项目经理,并且每个开发人员都可以使用各种编程语言进行编码。项目经理带领开发人员,并确切地知道他们的工作量。
我对这种设计模式不是百分百确定,但是我认为这是此方案的完美用例,不是吗?
结果应如下所示:
我想查询项目经理,以检查所有能够使用特定编程语言(例如)进行编码的开发人员的工作量Java
。
这是我到目前为止的内容:
Employee.java:
public class Employee {
private String name = null;
public Employee() {
name = "Noob";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
ProgrammingLanguages.java:
public enum ProgrammingLanguages {
JAVA,
JAVASCRIPT,
C,
PHP,
SWIFT,
PYTHON
}
ProjectManager.java:
import java.util.ArrayList;
import java.util.List;
public class ProjectManager extends Employee {
private List<Employee> employeeList = null;
public ProjectManager() {
employeeList = new ArrayList<Employee>();
}
public List<Employee> getEmployees() {
return employeeList;
}
public void setEmployees(List<Employee> employees) {
employeeList = employees;
}
public int getTotalWorkload() {
int workload = 0;
for (Employee employee : employeeList) {
workload += employee.getWorkload(); // Error! Cannot resolve method 'getWorkload()'
}
return workload;
}
}
开发商:
import java.util.ArrayList;
import java.util.List;
public class Developer extends Employee {
private List<ProgrammingLanguages> languagesList = null;
private int workload = 0;
public Developer() {
languagesList = new ArrayList<ProgrammingLanguages>();
}
public void setLanguagesList(List<ProgrammingLanguages> languagesList) {
this.languagesList = languagesList;
}
public void addProgrammingLanguage(ProgrammingLanguages language) {
languagesList.add(language);
}
public List<ProgrammingLanguages> getLanguagesList() {
return languagesList;
}
public void setWorkload(int workload) {
this.workload = workload;
}
public int getWorkload() {
return workload;
}
}
不幸的是,我在ProjectManager
类中遇到了一个编译器错误,为什么?
提前致谢。
是的,如果要映射树结构,则复合模式确实是正确的选择。参考您的示例,复合设计模式意味着您的类Employee
充当节点,该类ProjectManager
充当分支,该类Developer
充当叶子。在这种情况下,合成图案的主要优点是可以均匀地处理合成对象。结果,您可以使用此特定的GoF设计模式来表示实例的整个层次结构。
您需要以下参与者:
abstract
类Employee
必须声明组合物的界面和实现公共行为在一定程度上。ProjectManager
类扩展abstract
类Employee
并实现了行为治疗Employee
,你的情况的孩子,IDProjectManager
或Developer
实例。Developer
还扩展了abstract
类Employee
,并且表示没有任何孩子一片叶子。我使用您的示例代码来演示复合模式。请注意,它可能与您期望的结果有所不同,但是您可以将其作为参考。
Employee.java
(节点):
package me.eckhart;
import java.util.List;
public abstract class Employee {
private String name = null;
public static final String OPERATION_NOT_SUPPORTED = "Operation not supported.";
public String getName() {
return name;
}
public Employee setName(String name) {
if (name == null) throw new IllegalArgumentException("Argument 'name' is null.");
this.name = name;
return this;
}
public Employee addEmployee(Employee employee) {
throw new UnsupportedOperationException(OPERATION_NOT_SUPPORTED);
}
public List<Employee> getEmployees() {
throw new UnsupportedOperationException(OPERATION_NOT_SUPPORTED);
}
public Employee setEmployees(List<Employee> employees) {
throw new UnsupportedOperationException(OPERATION_NOT_SUPPORTED);
}
public Employee setLanguagesList(List<ProgrammingLanguages> languagesList) {
throw new UnsupportedOperationException(OPERATION_NOT_SUPPORTED);
}
public Employee addProgrammingLanguage(ProgrammingLanguages language) {
throw new UnsupportedOperationException(OPERATION_NOT_SUPPORTED);
}
public List<ProgrammingLanguages> getLanguagesList() {
throw new UnsupportedOperationException(OPERATION_NOT_SUPPORTED);
}
/* Composite operations. */
public abstract int getWorkload(ProgrammingLanguages language);
public abstract Employee setWorkload(int workload);
}
ProjectManager.java
(分支):
package me.eckhart;
import java.util.ArrayList;
import java.util.List;
public class ProjectManager extends Employee {
private List<Employee> employeeList = null;
public ProjectManager() {
this.employeeList = new ArrayList<>();
}
@Override
public Employee addEmployee(Employee employee) {
if (employee == null) throw new IllegalArgumentException("Argument 'employee' is null.");
this.employeeList.add(employee);
return this;
}
@Override
public List<Employee> getEmployees() {
return this.employeeList;
}
@Override
public Employee setEmployees(List<Employee> employeeList) {
if (employeeList == null) throw new IllegalArgumentException("Argument 'employeeList' is null.");
this.employeeList = employeeList;
return this;
}
/* Composite operations. */
public int getWorkload(ProgrammingLanguages language) {
int workload = 0;
for (Employee employee : employeeList) {
workload += employee.getWorkload(language);
}
return workload;
}
public Employee setWorkload(int workload) {
throw new UnsupportedOperationException(Employee.OPERATION_NOT_SUPPORTED);
}
}
Developer.java
(叶子):
package me.eckhart;
import java.util.ArrayList;
import java.util.List;
public class Developer extends Employee {
private List<ProgrammingLanguages> languagesList = null;
private int workload = 0;
public Developer() {
this.languagesList = new ArrayList<>();
}
@Override
public Employee setLanguagesList(List<ProgrammingLanguages> languagesList) {
this.languagesList = languagesList;
return this;
}
@Override
public Employee addProgrammingLanguage(ProgrammingLanguages language) {
this.languagesList.add(language);
return this;
}
@Override
public List<ProgrammingLanguages> getLanguagesList() {
return this.languagesList;
}
/* Composite operations. */
public Employee setWorkload(int workload) {
if (workload < -1) throw new IllegalArgumentException("Workload cannot be negative.");
this.workload = workload;
return this;
}
public int getWorkload(ProgrammingLanguages language) {
if (this.languagesList.contains(language)) return workload;
return 0;
}
}
ProgrammingLanguages.java
(枚举):
package me.eckhart;
public enum ProgrammingLanguages {
JAVA,
JAVASCRIPT,
C,
PHP,
SWIFT,
PYTHON
}
我创建了一个单元测试,以演示如何访问一种特定编程语言的工作负载。
EmployeeTest.java
(JUnit 4.11):
package me.eckhart;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class EmployeeTest {
protected Employee projectManagerIt;
@Before
public void setUp() throws Exception {
Employee webDevSr = new Developer();
webDevSr.setName("Jane").addProgrammingLanguage(ProgrammingLanguages.JAVASCRIPT).addProgrammingLanguage(ProgrammingLanguages.PYTHON).setWorkload(10);
Employee webDevJr = new Developer();
webDevJr.setName("Alex").addProgrammingLanguage(ProgrammingLanguages.PHP).setWorkload(15);
Employee projectManagerWebDev = new ProjectManager();
projectManagerWebDev.setName("James").addEmployee(webDevSr).addEmployee(webDevJr);
Employee softwareDevSr = new Developer();
softwareDevSr.setName("Martin").addProgrammingLanguage(ProgrammingLanguages.C).addProgrammingLanguage(ProgrammingLanguages.JAVA).setWorkload(35);
Employee softwareDevJr = new Developer();
softwareDevJr.setName("John").addProgrammingLanguage(ProgrammingLanguages.JAVA).setWorkload(30);
Employee projectManagerBackend = new ProjectManager();
projectManagerBackend.setName("Tom").addEmployee(softwareDevSr).addEmployee(softwareDevJr);
Employee freelanceSoftwareDev = new Developer();
freelanceSoftwareDev.setName("Marco").addProgrammingLanguage(ProgrammingLanguages.JAVA).addProgrammingLanguage(ProgrammingLanguages.PYTHON).addProgrammingLanguage(ProgrammingLanguages.C).setWorkload(25);
Employee freelanceWebDev = new Developer();
freelanceWebDev.setName("Claudio").addProgrammingLanguage(ProgrammingLanguages.SWIFT).addProgrammingLanguage(ProgrammingLanguages.JAVASCRIPT).addProgrammingLanguage(ProgrammingLanguages.PHP).setWorkload(10);
Employee freelanceProjectManager = new ProjectManager();
freelanceProjectManager.setName("Angie").addEmployee(freelanceSoftwareDev).addEmployee(freelanceWebDev);
projectManagerIt = new ProjectManager();
projectManagerIt.setName("Peter").addEmployee(projectManagerWebDev).addEmployee(projectManagerBackend).addEmployee(freelanceProjectManager);
}
@Test
public void testComposite() throws Exception {
Assert.assertEquals(90, projectManagerIt.getWorkload(ProgrammingLanguages.JAVA));
Assert.assertEquals(20, projectManagerIt.getWorkload(ProgrammingLanguages.JAVASCRIPT));
Assert.assertEquals(60, projectManagerIt.getWorkload(ProgrammingLanguages.C));
Assert.assertEquals(25, projectManagerIt.getWorkload(ProgrammingLanguages.PHP));
Assert.assertEquals(10, projectManagerIt.getWorkload(ProgrammingLanguages.SWIFT));
Assert.assertEquals(35, projectManagerIt.getWorkload(ProgrammingLanguages.PYTHON));
}
}
UML类图如下所示:
setUp()
方法中的代码EmployeeTest.java
实现以下树结构:
组合设计模式的主要缺点是,您需要通过运行时检查来限制某些操作,因为客户端通常不知道他们是在处理ProjectManager
(分支Developer
)实例还是(叶子)实例。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句