refactoring : primitive obsession - replace conditional with polymorphism
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
package com.example.refactoring._11_primitive_obsession._32_replace_conditional_with_polymorphism.switches;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class Employee {
|
||||
|
||||
protected List<String> availableProjects;
|
||||
|
||||
public Employee() {
|
||||
}
|
||||
|
||||
public Employee(List<String> availableProjects) {
|
||||
this.availableProjects = availableProjects;
|
||||
}
|
||||
|
||||
public abstract int vacationHours();
|
||||
|
||||
public boolean canAccessTo(String project) {
|
||||
return this.availableProjects.contains(project);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.example.refactoring._11_primitive_obsession._32_replace_conditional_with_polymorphism.switches;
|
||||
|
||||
public class FullTimeEmployee extends Employee {
|
||||
|
||||
@Override
|
||||
public int vacationHours() {
|
||||
return 120;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAccessTo(String project) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.example.refactoring._11_primitive_obsession._32_replace_conditional_with_polymorphism.switches;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PartTimeEmployee extends Employee {
|
||||
|
||||
public PartTimeEmployee(List<String> availableProjects) {
|
||||
super(availableProjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int vacationHours() {
|
||||
return 80;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.example.refactoring._11_primitive_obsession._32_replace_conditional_with_polymorphism.switches;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TemporalEmployee extends Employee {
|
||||
|
||||
public TemporalEmployee(List<String> availableProjects) {
|
||||
super(availableProjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int vacationHours() {
|
||||
return 32;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.example.refactoring._11_primitive_obsession._32_replace_conditional_with_polymorphism.switches._before;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Employee {
|
||||
|
||||
private String type;
|
||||
|
||||
private List<String> availableProjects;
|
||||
|
||||
public Employee(String type, List<String> availableProjects) {
|
||||
this.type = type;
|
||||
this.availableProjects = availableProjects;
|
||||
}
|
||||
|
||||
public int vacationHours() {
|
||||
return switch (type) {
|
||||
case "full-time" -> 120;
|
||||
case "part-time" -> 80;
|
||||
case "temporal" -> 32;
|
||||
default -> 0;
|
||||
};
|
||||
}
|
||||
|
||||
public boolean canAccessTo(String project) {
|
||||
return switch (type) {
|
||||
case "full-time" -> true;
|
||||
case "part-time", "temporal" -> this.availableProjects.contains(project);
|
||||
default -> false;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.example.refactoring._11_primitive_obsession._32_replace_conditional_with_polymorphism.variation;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ChinaExperiencedVoyageRating extends VoyageRating {
|
||||
|
||||
public ChinaExperiencedVoyageRating(Voyage voyage, List<VoyageHistory> history) {
|
||||
super(voyage, history);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int captainHistoryRisk() {
|
||||
int result = super.captainHistoryRisk() - 2;
|
||||
return Math.max(result, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int voyageProfitFactor() {
|
||||
return super.voyageProfitFactor() + 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int voyageLengthFactor() {
|
||||
int result = 0;
|
||||
result += 3;
|
||||
if (this.voyage.length() > 12) result += 1;
|
||||
if (this.voyage.length() > 18) result -= 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int historyLengthFactor() {
|
||||
return this.history.size() > 10 ? 1 : 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.example.refactoring._11_primitive_obsession._32_replace_conditional_with_polymorphism.variation;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class RatingFactory {
|
||||
|
||||
public static VoyageRating createRating(Voyage voyage, List<VoyageHistory> history) {
|
||||
if (voyage.zone().equals("china") && hasChinaHistory(history)) {
|
||||
return new ChinaExperiencedVoyageRating(voyage, history);
|
||||
} else {
|
||||
return new VoyageRating(voyage, history);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean hasChinaHistory(List<VoyageHistory> history) {
|
||||
return history.stream().anyMatch(v -> v.zone().equals("china"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package com.example.refactoring._11_primitive_obsession._32_replace_conditional_with_polymorphism.variation;
|
||||
|
||||
public record Voyage(String zone, int length) {
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package com.example.refactoring._11_primitive_obsession._32_replace_conditional_with_polymorphism.variation;
|
||||
|
||||
public record VoyageHistory(String zone, int profit) {
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.example.refactoring._11_primitive_obsession._32_replace_conditional_with_polymorphism.variation;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class VoyageRating {
|
||||
|
||||
protected Voyage voyage;
|
||||
|
||||
protected List<VoyageHistory> history;
|
||||
|
||||
public VoyageRating(Voyage voyage, List<VoyageHistory> history) {
|
||||
this.voyage = voyage;
|
||||
this.history = history;
|
||||
}
|
||||
|
||||
public char value() {
|
||||
final int vpf = this.voyageProfitFactor();
|
||||
final int vr = this.voyageRisk();
|
||||
final int chr = this.captainHistoryRisk();
|
||||
return (vpf * 3 > (vr + chr * 2)) ? 'A' : 'B';
|
||||
}
|
||||
|
||||
protected int captainHistoryRisk() {
|
||||
int result = 1;
|
||||
if (this.history.size() < 5) result += 4;
|
||||
result += this.history.stream().filter(v -> v.profit() < 0).count();
|
||||
return Math.max(result, 0);
|
||||
}
|
||||
|
||||
private int voyageRisk() {
|
||||
int result = 1;
|
||||
if (this.voyage.length() > 4) result += 2;
|
||||
if (this.voyage.length() > 8) result += this.voyage.length() - 8;
|
||||
if (List.of("china", "east-indies").contains(this.voyage.zone())) result += 4;
|
||||
return Math.max(result, 0);
|
||||
}
|
||||
|
||||
protected int voyageProfitFactor() {
|
||||
int result = 2;
|
||||
|
||||
if (this.voyage.zone().equals("china")) result += 1;
|
||||
if (this.voyage.zone().equals("east-indies")) result +=1 ;
|
||||
result += voyageLengthFactor();
|
||||
result += historyLengthFactor();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected int voyageLengthFactor() {
|
||||
return this.voyage.length() > 14 ? -1 : 0;
|
||||
}
|
||||
|
||||
protected int historyLengthFactor() {
|
||||
return this.history.size() > 8 ? 1 : 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package com.example.refactoring._11_primitive_obsession._32_replace_conditional_with_polymorphism.variation._before;
|
||||
|
||||
public record Voyage(String zone, int length) {
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package com.example.refactoring._11_primitive_obsession._32_replace_conditional_with_polymorphism.variation._before;
|
||||
|
||||
public record VoyageHistory(String zone, int profit) {
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.example.refactoring._11_primitive_obsession._32_replace_conditional_with_polymorphism.variation._before;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class VoyageRating {
|
||||
|
||||
private Voyage voyage;
|
||||
|
||||
private List<VoyageHistory> history;
|
||||
|
||||
public VoyageRating(Voyage voyage, List<VoyageHistory> history) {
|
||||
this.voyage = voyage;
|
||||
this.history = history;
|
||||
}
|
||||
|
||||
public char value() {
|
||||
final int vpf = this.voyageProfitFactor();
|
||||
final int vr = this.voyageRisk();
|
||||
final int chr = this.captainHistoryRisk();
|
||||
return (vpf * 3 > (vr + chr * 2)) ? 'A' : 'B';
|
||||
}
|
||||
|
||||
private int captainHistoryRisk() {
|
||||
int result = 1;
|
||||
if (this.history.size() < 5) result += 4;
|
||||
result += this.history.stream().filter(v -> v.profit() < 0).count();
|
||||
if (this.voyage.zone().equals("china") && this.hasChinaHistory()) result -= 2;
|
||||
return Math.max(result, 0);
|
||||
}
|
||||
|
||||
private int voyageRisk() {
|
||||
int result = 1;
|
||||
if (this.voyage.length() > 4) result += 2;
|
||||
if (this.voyage.length() > 8) result += this.voyage.length() - 8;
|
||||
if (List.of("china", "east-indies").contains(this.voyage.zone())) result += 4;
|
||||
return Math.max(result, 0);
|
||||
}
|
||||
|
||||
private int voyageProfitFactor() {
|
||||
int result = 2;
|
||||
|
||||
if (this.voyage.zone().equals("china")) result += 1;
|
||||
if (this.voyage.zone().equals("east-indies")) result +=1 ;
|
||||
if (this.voyage.zone().equals("china") && this.hasChinaHistory()) {
|
||||
result += 3;
|
||||
if (this.history.size() > 10) result += 1;
|
||||
if (this.voyage.length() > 12) result += 1;
|
||||
if (this.voyage.length() > 18) result -= 1;
|
||||
} else {
|
||||
if (this.history.size() > 8) result +=1 ;
|
||||
if (this.voyage.length() > 14) result -= 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean hasChinaHistory() {
|
||||
return this.history.stream().anyMatch(v -> v.zone().equals("china"));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.example.refactoring._11_primitive_obsession._32_replace_conditional_with_polymorphism.switches;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class EmployeeTest {
|
||||
|
||||
@Test
|
||||
void fulltime() {
|
||||
Employee employee = new FullTimeEmployee();
|
||||
assertEquals(120, employee.vacationHours());
|
||||
assertTrue(employee.canAccessTo("new project"));
|
||||
assertTrue(employee.canAccessTo("spring"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void partime() {
|
||||
Employee employee = new PartTimeEmployee(List.of("spring", "jpa"));
|
||||
assertEquals(80, employee.vacationHours());
|
||||
assertFalse(employee.canAccessTo("new project"));
|
||||
assertTrue(employee.canAccessTo("spring"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void temporal() {
|
||||
Employee employee = new TemporalEmployee(List.of("jpa"));
|
||||
assertEquals(32, employee.vacationHours());
|
||||
assertFalse(employee.canAccessTo("new project"));
|
||||
assertFalse(employee.canAccessTo("spring"));
|
||||
assertTrue(employee.canAccessTo("jpa"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.example.refactoring._11_primitive_obsession._32_replace_conditional_with_polymorphism.variation;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
class VoyageRatingTest {
|
||||
|
||||
@Test
|
||||
void westIndies() {
|
||||
VoyageRating voyageRating = RatingFactory.createRating(new Voyage("west-inides", 10),
|
||||
List.of(new VoyageHistory("east-indies", 5),
|
||||
new VoyageHistory("west-indies", 15),
|
||||
new VoyageHistory("china", -2),
|
||||
new VoyageHistory("west-africa", 7)));
|
||||
assertEquals('B', voyageRating.value());
|
||||
}
|
||||
|
||||
@Test
|
||||
void china() {
|
||||
VoyageRating voyageRating = RatingFactory.createRating(new Voyage("china", 10),
|
||||
List.of(new VoyageHistory("east-indies", 5),
|
||||
new VoyageHistory("west-indies", 15),
|
||||
new VoyageHistory("china", -2),
|
||||
new VoyageHistory("west-africa", 7)));
|
||||
assertEquals('A', voyageRating.value());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user