我经常在访谈中讨论设计问题,并发现了一个问题,即:
假设有一家公司希望在经济衰退时期处理员工加薪问题。作为一项预防措施,它决定只对至少符合两项标准的雇员提高工资,而不是提高所有雇员的工资。问题陈述是设计类和函数,以帮助公司处理远航信件。
请检查它的设计实现是否正常(比如它是否是松散耦合的、封装得很好的,以及其他OOPS的概念是否被遵循)。
package com.salaryhike;
import java.util.HashMap;
public class Company {
private String name;
public String getName() {
return name;
}
public Company(String name) {
this.name = name;
}
HashMap<Employee, HashMap<AcheivementType, Object>> achiements = new HashMap<>();
private void decideHike(SalaryUpdatable employee) {
if (employee instanceof Employee && achiements.containsKey(employee)) {
float hikeValue = (15 / 100f);
HashMap<AcheivementType, Object> employeeAchievements = achiements.get(employee);
Integer numOfResercepapers = (Integer) employeeAchievements.get(AcheivementType.REARCH_PAPER);
Integer numberOfyearsOfemployement = (Integer) employeeAchievements
.get(AcheivementType.NUM_OF_YEARS_EMPLOYED);
Boolean isStarOfTheYear = (Boolean) employeeAchievements.get(AcheivementType.IS_STAR_OF_THE_YEAR);
boolean eligibilitySet1 = false;
boolean eligibilitySet2 = false;
boolean eligibilitySet3 = false;
if (isStarOfTheYear != null && numberOfyearsOfemployement != null) {
eligibilitySet1 = isStarOfTheYear && (numberOfyearsOfemployement >= 5);
}
if (isStarOfTheYear != null && numOfResercepapers != null) {
eligibilitySet2 = isStarOfTheYear && (numOfResercepapers >= 2);
}
if (numberOfyearsOfemployement != null && numOfResercepapers != null) {
eligibilitySet3 = ((numberOfyearsOfemployement >= 5) && (numOfResercepapers >= 2));
}
if (eligibilitySet1 || eligibilitySet2 || eligibilitySet3) {
employee.updateSalary(this, employee.getSalary(this) + (hikeValue * employee.getSalary(this)));
}
}
}
public void registerAchievement(Employee employee, AcheivementType type, Object newValue) {
(achiements.get(employee)).put(type, newValue);
}
public void hireEmployee(Employee employee) {
if (achiements.containsKey(employee)) {
throw new IllegalEmployement("EMPLOYEE ALREADY EMPLOYED");
}
achiements.put(employee, new HashMap<AcheivementType, Object>());
}
public void removeEmployee(Employee employee) {
achiements.remove(employee);
}
public class IllegalEmployement extends RuntimeException {
public IllegalEmployement(String msg) {
super(msg);
}
}
public static void init() {
Company company = new Company("ABC_PVT_LTD");
Employee employee1 = new Employee(company, "A", 20000);
Employee employee2 = new Employee(company, "B", 40000);
Employee employee3 = new Employee(company, "C", 50000);
Employee employee4 = new Employee(company, "D", 350000);
Employee employee5 = new Employee(company, "A", 20000);
Employee employee6 = new Employee(company, "B", 40000);
Employee employee7 = new Employee(company, "C", 50000);
Employee employee8 = new Employee(company, "D", 350000);
company.hireEmployee(employee1);
company.hireEmployee(employee2);
company.hireEmployee(employee3);
company.hireEmployee(employee4);
company.hireEmployee(employee5);
company.hireEmployee(employee6);
company.hireEmployee(employee7);
company.hireEmployee(employee8);
employee1.registerAchievements(AcheivementType.REARCH_PAPER, 3);
employee2.registerAchievements(AcheivementType.REARCH_PAPER, 1);
employee3.registerAchievements(AcheivementType.REARCH_PAPER, 2);
employee4.registerAchievements(AcheivementType.JAVA_CERIFICATION_NUM, 3);
employee1.registerAchievements(AcheivementType.NUM_OF_YEARS_EMPLOYED, 5);
employee2.registerAchievements(AcheivementType.IS_STAR_OF_THE_YEAR, true);
employee3.registerAchievements(AcheivementType.IS_STAR_OF_THE_YEAR, true);
employee4.registerAchievements(AcheivementType.JAVA_CERIFICATION_NUM, 3);
employee5.registerAchievements(AcheivementType.REARCH_PAPER, 3);
employee6.registerAchievements(AcheivementType.REARCH_PAPER, 1);
employee7.registerAchievements(AcheivementType.REARCH_PAPER, 2);
employee8.registerAchievements(AcheivementType.JAVA_CERIFICATION_NUM, 3);
company.decideHike(employee1);
company.decideHike(employee2);
company.decideHike(employee3);
company.decideHike(employee4);
company.decideHike(employee5);
company.decideHike(employee6);
company.decideHike(employee7);
company.decideHike(employee8);
System.out.println(employee1.getSalary(company));
System.out.println(employee2.getSalary(company));
System.out.println(employee3.getSalary(company));
System.out.println(employee4.getSalary(company));
System.out.println(employee5.getSalary(company));
System.out.println(employee6.getSalary(company));
System.out.println(employee7.getSalary(company));
System.out.println(employee8.getSalary(company));
}
public static void main(String args[]) {
Company.init();
}
}
enum AcheivementType {
REARCH_PAPER, NUM_OF_YEARS_EMPLOYED, IS_STAR_OF_THE_YEAR, JAVA_CERIFICATION_NUM
}
interface SalaryUpdatable {
public void updateSalary(Company company, double updatedSalary);
public double getSalary(Company company);
public class SalaryException extends RuntimeException {
public SalaryException(String msg) {
super(msg);
}
}
}
class Employee implements SalaryUpdatable {
private Company company;
private double salary;
private String name;
public Employee(Company company, String name, double offeredSalary) {
this.company = company;
this.name = name;
this.salary = offeredSalary;
}
public String getName() {
return name;
}
public double getSalary(Company company) {
if (company == this.company) {
return salary;
} else {
throw new SalaryException("NOT ATHOURIZED TO KNOW SALARY");
}
}
public void updateSalary(Company company, double updatedSalary) {
if (company == this.company) {
this.salary = updatedSalary;
} else {
throw new SalaryException("NOT ATHOURIZED TO KNOW SALARY");
}
}
public void registerAchievements(AcheivementType type, Object value) {
company.registerAchievement(this, type, value);
}
} 发布于 2015-08-10 07:30:49
分离
这意味着将init和main移到类SalaryHikeTest中。
参见有效Java 这里的相关项目摘要。
项目52:如果存在适当的接口类型,则通过接口引用对象,那么参数、返回值、变量和字段都应该使用接口类型声明。
不要使用HashMap,因为Map就足够了。
而不是:
HashMap<Employee, HashMap<AcheivementType, Object>> achiements = new HashMap<>();用途:
Map<Employee, Map<AcheivementType, Object>> achiements = new HashMap<>();它是
IllegalEmployement,SalaryException未使用。
提取接口SalaryUpdatable是不合理的。雅格尼
这些片段也是不必要的:
} else {
throw new SalaryException("NOT ATHOURIZED TO KNOW SALARY");
}他们不在规范里。即使它们在特殊情况下使用例外情况。请参阅有效Java (摘要)中的项目57及以下内容。
变量后面的1、2或3表示违反0,1,n
boolean eligibilitySet1 = false;
boolean eligibilitySet2 = false;
boolean eligibilitySet3 = false;更糟糕的是,在这种情况下,您手工编码了标准的每个元素组合。C(n,r)对于n=3和r= 2是3,但这是不可行的:如果条件是“满足10个准则中的任何5个”,则必须提交代码252的情况。如果条件是“符合大约20项标准中的10项”,你将不得不提交代码184,756个案例。它叫组合爆炸是有原因的。
也见numberOfyearsOfemployement >= 5、numOfResercepapers >= 2等被复制/粘贴。复制/粘贴代码是等待发生的错误。相反,请计算满足的标准,最后将其与阈值进行比较:
与此相比较:
int numCriteriaSatisfied = 0;
if (numberOfyearsOfemployement >= 5) numCriteriaSatisfied ++;
if (numOfResercepapers >= 2) numCriteriaSatisfied ++;
if (isStarOfTheYear) numCriteriaSatisfied ++;
if (numCriteriaSatisfied >= MINIMUM_NUMBER_OF_CRITERIA) doSomething(...);有一些面向对象的设计问题,但如果您首先修复这些问题,它们将更容易发现和修复。
https://codereview.stackexchange.com/questions/100406
复制相似问题