I have an Engineer
which doesn't look very good. How can I make him better organized? What about good practices?
Interface:
public interface Engineer {
String HOMELESS = "homeless";
String ENGINEER = "engineer";
String SOFTWARE_ENGINEER = "softwareEngineer";
String TEST_ENGINEER = "testEngineer";
String TEST_AUTOMATION_ENIGNEER = "testAutomationEngineer";
static final int WORK = 1;
static final int LOOKING_FOR_NEW_JOB = 2;
static final int BUSY = 3;
static final int FREE = 4;
static final int SLEEP = 5;
boolean isHappy();
String getEmployer();
String getType();
String makeOffer(int salary, String employer);
void fire();
void setView(EngineerImpl.View view);
/**
* Sets employer
* @param name
* @return
*/
void setEmployer(String name);
String getName();
void startWork(long time);
/**
* Stops {@link Engineer}
* @return
*/
int stopWork(long time);
/**
* Sets {@link Engineer} into hibernate mode for {@code seconds}
* @param seconds
*/
void sleep(int seconds);
boolean eatPizza(int pieces);
}
Implementation:
public class EngineerImpl implements Engineer {
private View view;
static class EngineersFactory {
public static Engineer getEngineer(String name, String type) {
return new EngineerImpl(name, type);
}
public static Engineer getEngineer(String name) {
return getEngineer(name, ENGINEER);
}
public static Engineer getSoftwareEngineer(String name) {
return getEngineer(name, SOFTWARE_ENGINEER);
}
public static Engineer getTestEngineer(String name) {
return getEngineer(name, TEST_ENGINEER);
}
public static Engineer getTestAutomationEngineer(String name) {
return getEngineer(name, TEST_AUTOMATION_ENIGNEER);
}
}
interface View {
void showSmile();
}
private boolean isHappy = false;
private String employer;
private int salary;
private String name;
private int status;
private long workStartedAt;
private int previousStatus;
private final String type;
public EngineerImpl(String name, String type) {
isHappy = true;
this.name = name;
status = WORK;
this.type = type;
}
@Override
public String getType() {
return type;
}
@Override
public void setView(View view) {
this.view = view;
}
@Override
public boolean isHappy() {
return isHappy;
}
@Override
public String getEmployer() {
return employer;
}
@Override
public String makeOffer(int salary, String employer) {
if (shouldIAcceptNewOffer(salary, employer)) {
acceptOffer(salary, employer);
return employer;
}
return this.employer;
}
@Override
public void fire() {
this.salary = 0;
this.employer = HOMELESS;
isHappy = false;
status = LOOKING_FOR_NEW_JOB;
}
@Override
public void setEmployer(String name) {
this.employer = name;
}
@Override
public String getName() {
return name;
}
@Override
public void startWork(long time) {
status = BUSY;
workStartedAt = time;
}
@Override
public int stopWork(long time) {
status = FREE;
view.showSmile();
return (int) (time - workStartedAt);
}
@Override
public void sleep(int seconds) {
previousStatus = status;
status = SLEEP;
try {
Thread.sleep(seconds);
} catch (InterruptedException e) {
// ...
}
status = previousStatus;
}
@Override
public boolean eatPizza(int pieces) {
isHappy = ((pieces % 2) == 0 && status == FREE);
if (isHappy) {
view.showSmile();
} else {
sleep(10);
}
return isHappy;
}
@Override
public boolean equals(Object engineer) {
if (this == engineer) {
return true;
}
Engineer e = (Engineer) engineer;
return this.isHappy == e.isHappy() && hashCode() == e.hashCode();
}
@Override
public int hashCode() {
return getName().hashCode()
+ getEmployer().hashCode()
+ getType().hashCode();
}
private boolean shouldIAcceptNewOffer(int salary, String employer) {
return salary > this.salary && employer.equals(this.employer);
}
private void acceptOffer(int salary, String employer) {
this.salary = salary;
this.employer = employer;
isHappy = true;
view.showSmile();
}
}
Some explicit questions:
- Is it OK to put constants to interface and use them in the implementation?
- Should I make constants
static final
if they are defined in an interface? Which constants should I prefer,int
orString
? - Can I make some additional actions in setters?
- When should I write a JavaDoc?